pub struct KeyRing { /* private fields */ }Expand description
A bounded set of token-signing keys with explicit states (issue #137).
A ring is built once — from the environment in a Worker, or
programmatically by rotation tooling — and then frozen inside an
HmacSigner. It is not ambient request state (ADR 0007): each
signer owns its ring, and rotating keys in a running Worker means
updating the secrets so the next isolate builds a new ring.
Implementations§
Source§impl KeyRing
impl KeyRing
Sourcepub const CAPACITY: usize = 4
pub const CAPACITY: usize = 4
Maximum number of entries: one signing key plus CAPACITY − 1
verification-only or revoked. A token survives at most
CAPACITY − 1 rotations after it was minted; past that, its key
is retired and the link is dead by design — the documented cost of
being able to revoke a compromised key without a token table
(ADR 0014).
pub fn new() -> Self
pub fn is_empty(&self) -> bool
Sourcepub fn states(&self) -> Vec<(Kid, KeyState)>
pub fn states(&self) -> Vec<(Kid, KeyState)>
Safe view of the ring: each key’s id and state, never its bytes.
Sourcepub fn signing_key(&self) -> Option<&RingKey>
pub fn signing_key(&self) -> Option<&RingKey>
The key currently signing new tokens, if any.
pub fn state_of(&self, kid: &Kid) -> Option<KeyState>
Sourcepub fn rotate_signing(
&mut self,
kid: Kid,
secret: impl Into<Vec<u8>>,
) -> Result<Option<Kid>, SignerError>
pub fn rotate_signing( &mut self, kid: Kid, secret: impl Into<Vec<u8>>, ) -> Result<Option<Kid>, SignerError>
Installs secret as the single signing key, demoting the previous
signer to KeyState::VerifyingOnly. If the ring is at capacity,
the oldest non-signing entry is retired to make room (its id is
kept as a burned tombstone); the retired id is returned.
§Errors
SignerError::SecretTooShort, SignerError::KeyIdTooLong,
SignerError::KeyIdTaken, SignerError::KeyRevoked or
SignerError::RevokedSecretReuse when the new key is invalid;
SignerError::RingFull only in the degenerate ring whose entries
are all signing or revoked-with-nothing-to-drop (impossible under
Self::CAPACITY ≥ 1 except with hand-built state).
Sourcepub fn add_verifying_only(
&mut self,
kid: Kid,
secret: impl Into<Vec<u8>>,
) -> Result<Option<Kid>, SignerError>
pub fn add_verifying_only( &mut self, kid: Kid, secret: impl Into<Vec<u8>>, ) -> Result<Option<Kid>, SignerError>
Adds a verification-only key — the shape of HARNESS_SECRET_PREVIOUS
in the environment wiring. Same capacity and revocation rules as
Self::rotate_signing.
§Errors
Identical to Self::rotate_signing: SignerError::SecretTooShort,
SignerError::KeyIdTooLong, SignerError::KeyIdTaken,
SignerError::KeyRevoked or SignerError::RevokedSecretReuse
when the key is invalid, and SignerError::RingFull only in a
degenerate ring where nothing can be retired to make room.
Sourcepub fn revoke(&mut self, kid: &Kid) -> bool
pub fn revoke(&mut self, kid: &Kid) -> bool
Marks kid KeyState::Revoked. Its tokens stop verifying
immediately, even while its secret stays configured somewhere in
the ring — revocation is a state, not a deletion race. Returns
whether an entry existed to be revoked; a missing id is still
burned as a tombstone, so revoke(prev) survives the moment the
operator also drops HARNESS_SECRET_PREVIOUS.