Appearance
Theseus site-pairing QR (layer 2)
Approved: 17 September 2026 (#152)
An unlocked Theseus phone stores HTTPS origin + write-scoped field token from a QR minted on Mobile Access. This is not the Nav mobile key, not a Keryx ntfy subscribe token, and not safecall-ops (T4).
Layer 1 (Wantok unlock) stays in front. The unlock screen has no site QR scanner. Its only scanner reads the RTLS test QR, which opens the restricted tester mode and never a site pairing.
Payload
Type safecall.theseus.pair.v1:
json
{
"type": "safecall.theseus.pair.v1",
"origin": "https://customer.example",
"field_token": "th_…",
"token_id": "<uuid>",
"created_at": "2026-09-17T00:00:00.000Z"
}| Field | Rule |
|---|---|
origin | HTTPS origin of the SafeCall box the phone will call. Reject http. |
field_token | Opaque th_ secret. Never server_mobile_api_key. Shown once at mint. |
token_id | UUID. Used to revoke. |
created_at | ISO-8601 mint time |
SQLite stores SHA-256 of the token (token_hash) plus token_id. The raw secret is not kept after mint. Soft revoke sets revoked_at.
HTTP
| Method | Path | Auth |
|---|---|---|
| POST | /api/v1/theseus/qr | Admin JWT (guard_auth + admin) |
| DELETE | /api/v1/theseus/qr/token/:token_id | guard_admin |
| GET | /api/v1/theseus/session | Authorization: Bearer th_… (not JWT) |
GET /theseus/session is a pairing probe only: 200 if the hash matches and revoked_at is null; 401 otherwise. No snapshot, no writes.
Mint origin comes from the request Origin header (must be HTTPS). Lab HTTP admin UIs cannot mint; the phone must call HTTPS.
In the app
Pairing is the app's sign-in. The start screen shows Scan site QR to sign in when no pairing is stored, and the origin, the session state, Switch site and Sign out when one is. Sign out only forgets the pairing on the phone; it does not call the revoke route.
Scanner
Theseus parses v1 and hard-rejects:
- Nav
{ url, mobile_key } - Keryx
safecall.keryx.ntfy.v2
No ntfy topics. No safecall-ops. Tokens live on the customer SQLite, not the NAS — no operator-actions row.
Web
Mobile Access shows a third, full-width Theseus card under Keryx / Nav, with its own canvas #theseus-qr-canvas.