Stage 01
Mobile wallet
The patron’s credential lives in their wallet, signed by the issuing authority. It never leaves the phone as a document.
Privacy architecture
Most privacy claims describe what a company promises not to do with data it holds. This one describes data the platform is incapable of holding, because no field, table, or contract exists to carry it.
01 · The data flow
Stage 01
The patron’s credential lives in their wallet, signed by the issuing authority. It never leaves the phone as a document.
Stage 02
The verifier requests one element over an encrypted session and validates it on the device. This is where identity data begins and ends.
Stage 03
One of three closed outcomes is rendered to staff. This is the only patron-derived value that exists after the session closes.
Stage 04
A counter for a location, an outcome, and a day. Nothing about a person reaches this stage, because nothing about a person left stage two.
02 · What Laurel receives
This is the entire set of fields a verifier is permitted to send. It is an allowlist: a device sending anything else gets a validation error, not a silently stripped field.
Every field describes your equipment or your operation. Exactly one field is patron-derived — the result — and it has three possible values.
It exists so an operator can tell “the tap did not connect”
from “the trust material needs updating.” It never explains
why a fail happened, because that explanation would be a fact
about a person.
03 · The prohibited list
Not “deleted after 30 days.” Not “encrypted at rest.” There is no column, no blob path, and no contract field for any of it, at any point in the system.
An error is not an exemption. Error payloads from device-ingestion handling exclude raw request bodies and unvalidated fields, and issues are grouped and titled from a bounded set of stage, error type, and failure code — never from a raw message that could carry a row value into a monitoring tool.
04 · Enforcement
A boundary maintained by discipline erodes. These are the mechanisms that make the wrong thing hard to build rather than merely discouraged.
There is no primary key anywhere in the schema that represents an individual. Nothing can hold a foreign key to something that does not exist.
The outcome-bearing tables are upsert-a-counter tables, never insert-a-row-per-outcome tables. They are structurally incapable of holding a per-patron record.
The device-to-platform schema rejects unrecognized fields rather than
stripping them. A device sending date_of_birth gets an error —
and that attempt is itself observable.
Rows below a minimum group size of three are withheld in the query and re-checked in responses, exports, and contracts, for every role.
De-duplication state stores a hash of the random event ID plus a keyed commitment to the payload. It carries no queryable outcome, location, time, reason, or version — so it is not a report in disguise.
Event metadata is constrained by a schema keyed to each event type. There is nowhere generic for an engineer to drop a name “just this once.”
05 · The consequence
Not because of how well the data is protected, but because the data is not there. That is the whole argument, and it is the reason we would rather be judged on the schema than on a policy document.
Staff and account data — the people who log into your portal — is a separate, ordinary privacy domain with ordinary rules. This page is about patron data.
We would rather answer hard questions early than discover them during a rollout.