1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! The `Signer` port and the signed-token payload (ADR 0006, amended by
//! ADR 0014). The HMAC reference implementation — a bounded key ring with
//! explicit signing / verification-only / revoked states — lives in
//! `cratefield-core::signer` (issue #3, issue #137).
/// Which key in the [`crate::KeyRing`] a token was signed with. Tokens
/// name their key so rotation never breaks links in flight.
///
/// The two positional names are what the environment-derived runtimes
/// wire (`HARNESS_SECRET` is `Cur`, `HARNESS_SECRET_PREVIOUS` is `Prev`);
/// legacy tokens from the flat current/previous scheme carry exactly these
/// names (issue #137). A ring built programmatically can give its keys
/// stable [`Kid::Named`] labels instead, so an entry keeps its identity as
/// it moves from signing to verification-only.
/// The longest accepted `Kid::Named` wire name. Key ids ride inside every
/// token; the bound keeps a hostile payload from claiming arbitrary
/// storage.
pub const MAX_KID_NAME: usize = 32;
/// The signed payload: `{ purpose, subject, exp?, kid }`.
///
/// `purpose` scopes a token to one use (`email-signup.confirm`,
/// `waitlist.status`, ...) and must be module-qualified: the module part
/// *is* the module binding (ADR 0014, issue #137) — a token minted by one
/// module can never verify for another because the full purpose is
/// compared. `exp` is a Unix timestamp in seconds. Every purpose carries
/// an explicit lifetime: the reference signer clamps over-long or missing
/// expiries to its [`crate::TokenPolicy`] (issue #137), so a non-expiring
/// token is a deliberate policy decision, never an omission. Venture and
/// environment binding is stamped and enforced by the signer itself, not
/// carried here: modules hand the same payload shape to every runtime.
/// Failures surfaced by `verify` beyond "the token is simply invalid",
/// which is reported as `None`.
/// Produces and verifies `base64url(json).base64url(mac)` tokens where the
/// MAC is computed over the **encoded** payload string, so a token has
/// exactly one valid encoding (ADR 0006).
///
/// The reference implementation keeps a bounded ring of keys (ADR 0014,
/// issue #137): one in the *signing* state, any number in
/// *verification-only*, and revoked keys whose tokens are refused.
/// Verification tries every live key's MAC in constant time; a token
/// naming a revoked key, minted for another venture/environment binding,
/// expired past its policy lifetime, or carrying the wrong purpose
/// verifies as `None`.