Expand description
Persistent pair-device token store (issue #756). Persistent pair-device token store (issue #756).
Mirrors crate::invite’s shape but targets adding a NEW key
to an EXISTING principal (the “pair device” flow) instead of
minting a fresh principal.
Durable records live in the fixed system:control:pair-tokens namespace,
bound to immutable principal UIDs. $ASTRID_HOME/etc/pair-tokens.toml is
accepted only by the bounded boot migration and is retired after verified
readback.
§Threat model
Same posture as the invite store: only domain-separated hashes are stored,
redemption compares hashes in constant time, and mutation uses atomic
system-owner KV batches. Pair-tokens are single-use only (no
remaining_uses field). Redemption first claims an exact record with a
durable reservation, performs the profile update, and then commits the
deletion; a preparation failure releases only that reservation.
Lifetime is capped at one hour (MAX_EXPIRY_SECS) — pair-tokens
are meant for immediate use on a neighbouring device. Longer
sharing windows are deliberately unsupported; if a user really
wants a multi-day window they should redeem a separate invite
(different principal) instead.
Structs§
- Durable
Pair Token - Durable UID-bound pair-token record. The public
PairTokenremains the legacy-file compatibility type; runtime handlers use this record so alias renames cannot retarget an outstanding pairing authority. - Durable
Pair Token Store - Storage-backed pair-token state with atomic conditional issue/consume/ revoke operations and strict one-time legacy import.
- Pair
Token - On-disk persisted pair-token record. Raw token is never stored — only its domain-separated BLAKE3 identifier.
- Pair
Token Store - File-backed pair-token store. Read-modify-write uses atomic rename on Unix;
all loads and mutators serialise on the kernel’s
admin_write_lockbecause a load can migrate legacy state.
Enums§
- Pair
Token Store Error - Errors surfaced by
PairTokenStoreoperations.
Constants§
- MAX_
EXPIRY_ SECS - Hard cap on a single pair-token’s lifetime. Pair-tokens are intended for immediate use (“scan this QR with your phone, now”) — a longer window is deliberately unsupported.
- SYSTEM_
KV_ NAMESPACE - Fixed host-only namespace for pair-device authority. Records are keyed by token identifier and bind the immutable principal UID, never a mutable alias or alias-derived namespace.
- TOKEN_
PREFIX - Type prefix carried by every raw device-pairing bearer token.
- TOKEN_
RAW_ LEN - Length of the random token portion in bytes (192 bits → 32 chars URL-safe base64). Same sizing as invite tokens.
Functions§
- ct_
hash_ eq - Constant-time hash comparison.
- generate_
token - Generate a typed token with a random URL-safe-base64 secret from the OS CSPRNG.
- hash_
token - Derive a token identifier for storage and lookup.
- now_
epoch - Current wall-clock seconds since Unix epoch.
- prune_
expired - Prune expired pair-tokens in place. Returns the count removed.