Single-use activation
A device is created in the portal and activated with a one-time code. Once consumed, the code is spent. There is no re-activation path that quietly issues a second credential for the same code.
Security architecture
This page describes the security properties a reviewer needs to evaluate the system. It deliberately stops short of implementation detail that would only help someone attack a customer's deployment.
01 · Device identity
A device is created in the portal and activated with a one-time code. Once consumed, the code is spent. There is no re-activation path that quietly issues a second credential for the same code.
The device credential is encrypted under the Android Keystore, using StrongBox where the hardware provides it. Where it does not, the fallback is explicit and guarded rather than an unhandled provider exception.
Credentials rotate with a bounded overlap and a durable acknowledgement before the previous credential is retired. Retired credentials are kept as a hash for audit and are never reusable.
02 · Issuer trust
Production trust is limited to exact certificate bytes authenticated through either the signed AAMVA Digital Trust Service VICAL or a reviewed issuing authority's official certificate endpoint. VICAL updates are verified for signature, provider chain, validity interval, and rollback before activation; direct certificates are parsed, validity-checked, jurisdiction-bound, and pinned byte-for-byte.
A verification does not need a live network connection. Offline operation remains available only while both the device policy lease and the admitted signed trust publication are valid. Laurel begins refreshing trust before expiry and keeps a still-valid current bundle if a refresh fails. An invalid candidate never replaces it, and no grace period revives expired, revoked, rolled-back, or incorrectly signed trust material.
03 · The presentation
A signed credential that is valid in isolation is not enough. The verifier binds the response to the session that produced it, so a captured response cannot be replayed into a different exchange.
The age claim is read only from the verified document model, after issuer, security-object, digest, device, and session checks have all passed. Nothing is parsed out of pre-verification data and used to make a decision.
The verifier reports “connected” only after the transport supports messages, and “receiving” only once bytes have arrived. A UI that overstates progress trains staff to trust the wrong screen.
Every session close carries an allowlisted reason — normal completion, holder termination, operator cancel, timeout, lifecycle, permission, or failure. An empty transport message means transport termination, never a decline and never an under-21 result.
Platform library logging is disabled in favor of a typed, bounded in-app trace. Addresses, session identifiers, and payloads are not written to a device log where another application could read them.
04 · Ingestion
Reporting delivery is at-least-once, so the platform must be able to recognize a repeat. The way it does so is itself constrained by the privacy boundary.
The event identity is claimed atomically before a counter is updated, so a concurrent duplicate cannot produce a second increment.
The receipt stores a domain-separated HMAC commitment to the exact payload and scope, under an API-owned key that is not in the database. A plain hash of a three-value outcome vocabulary would be trivially dictionary-testable; this is not.
An exact retry is acknowledged idempotently. A replay whose payload or scope differs is rejected rather than accepted as a new event.
A receipt holds no queryable result, location, occurrence time, failure reason, or version, and is retained for at most thirty days — matching the device outbox window. It is delivery de-duplication state, not reportable data.
05 · Platform
Organization scope is applied in the database query rather than as an application-layer filter, so a missing check is a failing test rather than a silent cross-tenant read.
Portal sign-in runs through WorkOS AuthKit. Session verification and role/membership resolution are shared code, not re-implemented per surface.
The API is the only writer to the database, and the only thing devices in the field talk to. Every frontend goes through the same contracts a device does.
Schema changes ship as reviewed, ordered migrations with a documented rollback path, and deployment controls that keep environments from being substituted for one another.
06 · What we do not claim
LaurelID does not hold SOC 2, ISO 27001, or PCI attestation, has not completed an independent third-party security audit, and has no government approval or endorsement. If any of those change, they will appear here with the report behind them — not as a badge.
LaurelID verifies that a presented mobile ID cryptographically proves 21+. It does not claim to detect every conceivable presentation attack, and it is not a substitute for staff judgement about whether the person holding the phone is the person the credential describes.
We publish no availability percentage and no accuracy rate, because we have no measurement we would defend under scrutiny. See the trust center for how incidents are communicated today.
Security review is a standard leg of a pilot, not an add-on you have to negotiate for.