Skip to main content

Module pair_token

Module pair_token 

Source
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§

DurablePairToken
Durable UID-bound pair-token record. The public PairToken remains the legacy-file compatibility type; runtime handlers use this record so alias renames cannot retarget an outstanding pairing authority.
DurablePairTokenStore
Storage-backed pair-token state with atomic conditional issue/consume/ revoke operations and strict one-time legacy import.
PairToken
On-disk persisted pair-token record. Raw token is never stored — only its domain-separated BLAKE3 identifier.
PairTokenStore
File-backed pair-token store. Read-modify-write uses atomic rename on Unix; all loads and mutators serialise on the kernel’s admin_write_lock because a load can migrate legacy state.

Enums§

PairTokenStoreError
Errors surfaced by PairTokenStore operations.

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.