pub struct DurableKeyMaterial {
pub cipher: Option<Arc<dyn PayloadCipher>>,
pub hmac_key: Option<[u8; 32]>,
pub hwm_key: Option<(u32, [u8; 32])>,
pub previous_hmac_key: Option<[u8; 32]>,
pub previous_hwm_key: Option<(u32, [u8; 32])>,
pub integrity_sealed: bool,
pub integrity_grandfather: HashSet<ExecutionId>,
}Expand description
Key material and integrity-seal state shared by every durable-backend construction call
site: open_durable_backend, the P1/P2 AgentBuilder::with_durable_* methods
(builder.rs), and their reassembly points in Agent::ensure_session_durable_ctx and
plan.rs’s ensure_durable_backend (#6458).
hmac_key is None for a single-user local, non-shared database (INV-8) — the documented
stance where control entries carry no HMAC. hwm_key (issue #6360) is meant to be attached
unconditionally (FR-009): None only when ZEPH_DURABLE_KEY itself is unavailable — unlike
hmac_key, single-user local deployments still get high-water-mark deletion detection.
previous_hmac_key is Some only while a zeph durable rotate-key rotation window is open
(#6451). previous_hwm_key is the HWM-side counterpart, Some under the same condition
(addendum to #6451): unlike previous_hmac_key, its epoch reuses the AEAD cipher’s key_id
lifecycle rather than being epoch-less try-both (see HwmKeySlot/with_previous_hwm_key in
zeph-durable). integrity_sealed/integrity_grandfather (issue #6449) are resolved from
the vault by crate::commands::durable::load_integrity_seal in the zeph binary crate.
A mis-wired key field here — wrong key, wrong slot, or an unintended None — never results in
a silent accept: every control-entry and high-water-mark verification this key material feeds
fails closed, surfacing as
ControlIntegrity or
HighWaterMarkIntegrity rather than a
silently accepted read.
Deliberately does not derive Debug: every key field holds raw key-material bytes that must
never be logged or printed (see project pitfall: secret-bearing Debug derives).
§Examples
use zeph_core::DurableKeyMaterial;
// A non-durable / disabled-encryption configuration: every key slot empty.
let key_material = DurableKeyMaterial {
cipher: None,
hmac_key: None,
hwm_key: None,
previous_hmac_key: None,
previous_hwm_key: None,
integrity_sealed: false,
integrity_grandfather: Default::default(),
};
assert!(key_material.hmac_key.is_none());Fields§
§cipher: Option<Arc<dyn PayloadCipher>>AEAD payload cipher; None when config.encrypt_payload = false (development mode only).
hmac_key: Option<[u8; 32]>Current control-entry HMAC key.
hwm_key: Option<(u32, [u8; 32])>Current high-water-mark key as (epoch, key).
previous_hmac_key: Option<[u8; 32]>Previous control-entry HMAC key, valid only during an open rotation window.
previous_hwm_key: Option<(u32, [u8; 32])>Previous high-water-mark key as (epoch, key), valid only during an open rotation window.
integrity_sealed: boolWhether the durable integrity seal is set.
integrity_grandfather: HashSet<ExecutionId>Executions grandfathered in before the integrity seal was set, exempt from verification.
Auto Trait Implementations§
impl !RefUnwindSafe for DurableKeyMaterial
impl !UnwindSafe for DurableKeyMaterial
impl Freeze for DurableKeyMaterial
impl Send for DurableKeyMaterial
impl Sync for DurableKeyMaterial
impl Unpin for DurableKeyMaterial
impl UnsafeUnpin for DurableKeyMaterial
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request