Security architecture

Fail closed, everywhere it matters.

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

Every verifier proves who it is.

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.

Hardware-backed storage

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.

Rotation and retirement

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

A narrow, authenticated trust set.

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.

Not accepted as a trust anchor Why
Android system / user CAs Wrong trust domain entirely
Credential-provided roots Lets the presenter choose its own validator
Imported roots No reviewed provenance
Test IACAs Non-production material in a production decision
Indefinitely stale packages Revocation and rotation stop meaning anything

03 · The presentation

Session integrity, not just a valid signature.

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.

Verified before read

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.

Honest state reporting

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.

Terminations are attributed

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.

Diagnostics without payloads

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

Replay protection that cannot become a report.

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.

Atomic claim

The event identity is claimed atomically before a counter is updated, so a concurrent duplicate cannot produce a second increment.

Keyed commitment

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.

Changed replay fails closed

An exact retry is acknowledged idempotently. A replay whose payload or scope differs is rejected rather than accepted as a new event.

Receipts are bounded and expire

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

Tenancy, roles, and change control.

Tenant scope in the query

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.

Authentication

Portal sign-in runs through WorkOS AuthKit. Session verification and role/membership resolution are shared code, not re-implemented per surface.

Single writer

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.

Migrations and rollback

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

Stated limits.

No certification, no external audit

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.

No perfect-fraud claim

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.

No uptime or accuracy figure

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.

Next step

Bring your hardest questions.

Security review is a standard leg of a pilot, not an add-on you have to negotiate for.