Credentials
What a Participant QR contains, how versions invalidate old codes, and how personal links differ
Every Participant holds a credential, and that credential is what a QR encodes. It is a signed value, not a database lookup key: the server can verify it before touching a row. This page explains what is inside it, when it stops working, and how a personal link differs from the QR itself.
Form
Signed static token
Starts with ulsav1_
Contains
Kind, id, version
No name, email, or Event
Stored
Never
Derived from a server secret on demand
Changes on
Claim or removal
The version goes up
Personal link
Separate token
Also versioned, and turned off on claim
Works offline
No
The scanner always submits online
What is inside the QR
The token carries three things and a signature:
| Part | Meaning |
|---|---|
| Kind | Participant or Account |
| Id | The Participant or Account identifier |
| Version | A counter that starts at 1 |
| Signature | A truncated HMAC over the first three parts |
The value is rendered on demand from a server secret. A database leak yields no usable credential, because the token is never stored.
The scanner checks the signature first. A random QR, a competitor's QR, or a hand-edited value fails before any lookup.
Static means shareable
The Participant credential does not rotate on a timer. It is the same value until the version changes.
That makes it work on paper, in a screenshot, and in an email. It also means a screenshot can be forwarded. Ulsav's protection is the duplicate rule: the first successful online check-in wins, and a second presentation at the same session returns Already Checked In with the original time and operator.
The scanner's "This QR code has expired" message is a client-side check for scanned values that carry a timestamp. A normal Participant QR carries none, so a printed pass does not expire on its own.
When a credential stops working
The version is the switch. Two actions increase it:
- A Participant claims the place with an Account.
- A Participant is removed.
Claiming increases both the QR version and the link version, and turns the personal link off. Removing increases the QR version and disables the link. Any older QR or link then fails as an invalid credential.
There is no separate rotate button
The organizer product does not expose a rotate or revoke action. A credential changes when the person claims the place or is removed. If you need to invalidate a shared screenshot without removing the person, there is no supported path today.
When the QR is shown
A Participant page renders a QR only when the Registration is confirmed, the personal form is submitted, and the person has a name. A pending entry or an incomplete place shows the outstanding steps instead.
This is deliberate. A draft or pending Registration never hands out a working pass, and a guest place cannot arrive before its details are done.
The personal link
The buyer receives a link per unclaimed Participant after confirmation. The link is a bearer URL, not the QR value.
Opening it shows the current Participant details, the personal form when it is still open, and the QR. The link cannot see the Order, change the roster, or manage money.
The link has its own version. A claim turns it off, and a removal invalidates it. The buyer cannot regenerate a guest link after the person claims the place.
The Account QR
A scanner also accepts an Account credential. It resolves the Account, then finds the Participants this session would accept.
| Candidates found | Result |
|---|---|
| None | No Accepted Pass |
| Exactly one | That person is checked in |
| More than one | The operator chooses from a list |
The candidate list only includes people this session admits. An Account credential does not expose unrelated Event history, and an unclaimed guest place does not resolve through it.
Account QR codes are a scanner capability. The participant-facing pages show the per-Participant QR, so in practice most doors see the personal code.
Manual lookup is not a credential
Typing an email, phone, or name is a search, not a credential check. It can return no match or several matches, and the operator resolves it.
A successful manual admission is recorded with the manual method. A failed lookup is still recorded as an attempt, so an operator can explain why someone was sent to the help desk.
Privacy
Only a fingerprint of the presented value is stored on the attempt. Raw QR values, personal links, and secrets are not written to the attempt log or to application logs.
The fingerprint is a one-way hash with a prefix. It is enough to tell two presentations apart and useless for reconstructing the pass.
Failure paths
- A QR from a cancelled entry. The scan finds the person but the Registration is cancelled, so the result is Registration Cancelled.
- A QR from a replaced person. The old Participant is removed and its version bumped, so the old code is an invalid credential.
- A QR for another Event's Pass. The session does not accept that Pass, so the result is Pass Not Accepted.
- A QR after a claim. The old QR and the old link both fail; the person should use their Account or the page they now see.
- A printed pass at a second session. It works. Sessions are independent, so a main gate and a meal counter both admit.
Related
- Check-in — how a presented credential is judged
- Troubleshooting — what each rejection means at the door
- Participants — claiming a place with an Account
- Authentication — how sign-in works