pub struct AuditKeyStore { /* private fields */ }Expand description
Manager for the audit_key history under a single keyspace.
All methods are async because the underlying keyspace I/O is async. Concurrent rotations on the same store are not serialised in this layer — the caller (services) owns the invariant that rotation happens from a single coordinator path.
Implementations§
Source§impl AuditKeyStore
impl AuditKeyStore
Sourcepub fn new(ks: KeyspaceHandle) -> Self
pub fn new(ks: KeyspaceHandle) -> Self
Wrap a keyspace handle. The caller is responsible for configuring encryption-at-rest if desired.
Sourcepub async fn active(&self) -> Result<AuditKey, AppError>
pub async fn active(&self) -> Result<AuditKey, AppError>
Read the currently active key. Returns
AppError::NotFound if no initial key has been derived yet
— callers should invoke Self::ensure_initial on boot.
Sourcepub async fn fetch(&self, key_id: &KeyId) -> Result<Option<AuditKey>, AppError>
pub async fn fetch(&self, key_id: &KeyId) -> Result<Option<AuditKey>, AppError>
Fetch a specific key by id. Used by verifiers walking history to find the key that produced a given hash.
Sourcepub async fn history(&self) -> Result<Vec<AuditKey>, AppError>
pub async fn history(&self) -> Result<Vec<AuditKey>, AppError>
List every key in the store, newest first. Used by
verify_actor-style helpers in super::writer::AuditWriter
to walk history when the envelope’s audit_key_id is
unavailable (defensive — every envelope written here has one).
Sourcepub async fn ensure_initial(
&self,
master_seed: &[u8],
) -> Result<AuditKey, AppError>
pub async fn ensure_initial( &self, master_seed: &[u8], ) -> Result<AuditKey, AppError>
Derive the initial audit_key from master_seed and persist it.
Idempotent: if an initial key already exists, returns it
unchanged. Safe to call on every daemon start.
The derivation is deterministic
(HKDF-SHA256(master_seed, info: "vtc-audit-key/v2")) so a
backup+restore on the same seed reproduces the initial key
and pre-rotation hashes stay verifiable.
Info string bumped from /v1 to /v2 alongside the
VTA-driven-keys rework (tasks/vtc-mvp/vta-driven-keys.md
§5.2) — the IKM is now a 32-byte Ed25519 private from the
VTA bundle, not a 64-byte BIP-39 seed.
Sourcepub async fn rotate(&self, reason: RotationReason) -> Result<AuditKey, AppError>
pub async fn rotate(&self, reason: RotationReason) -> Result<AuditKey, AppError>
Rotate the active key. The previous key gets valid_until: now
and a fresh-random successor is generated + activated.
Returns the new active key.
Concurrent rotations are not safe at this layer — the caller must hold a logical exclusivity lock.
Trait Implementations§
Source§impl Clone for AuditKeyStore
impl Clone for AuditKeyStore
Source§fn clone(&self) -> AuditKeyStore
fn clone(&self) -> AuditKeyStore
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more