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.
§On-disk layout
$ASTRID_HOME/etc/pair-tokens.toml:
[[pair_token]]
token_hash = "..." # hex(sha256(token)) — 64 hex chars
principal = "alice" # the principal the new key will bind to
expires_at_epoch = 1234567890
issued_at_epoch = 1234560000
label = "alice's phone" # optional§Threat model
Same posture as the invite store: hashes on disk, atomic
write-then-rename, 0600 perms, constant-time hash comparison on
redeem. Pair-tokens are single-use only (no remaining_uses
field) — a redeemed token is removed immediately.
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§
- Pair
Token - On-disk persisted pair-token record. Raw token is never stored — only its SHA-256.
- Pair
Token Store - File-backed pair-token store. Read-modify-write with atomic
rename; concurrent mutators serialise on the kernel’s
admin_write_lock.
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.
- 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 random URL-safe-base64 token from the OS CSPRNG.
- hash_
token - Hash a token for storage / lookup. Hex-encoded SHA-256.
- now_
epoch - Current wall-clock seconds since Unix epoch.
- prune_
expired - Prune expired pair-tokens in place. Returns the count removed.