aeat.adapters.persistence.storage.secret_store._secret_store module¶
Encrypted, file-locked store for secret and session-bearing records.
Layered on top of adapters.persistence.storage.blob_store.EncryptedBlobStore
and core.locks.exclusive_file_lock(), the store persists
short-lived bearer state (SensitivityClass SESSION) and long-lived
authentication material (SensitivityClass SECRET) under a stable
string key. Each record is wrapped in an
adapters.persistence.storage.envelope.Envelope of
SecretRecord, encrypted via the blob store’s per-record DEK wrapped
by the active MasterKeyProvider using AES-256-GCM, and indexed by
an HMAC-SHA256 digest of the natural-key string so consumers can query
SecretStore.get() without leaking the plaintext key.
A JSON catalogue file at store_dir / "index.json" maps the hex
digest of each key to the underlying
adapters.persistence.storage.blob_store.BlobReference.
Every mutation acquires exclusive_file_lock(store_dir / "secrets.lock")
so parallel writers serialise rather than race.
The retention contract is enforced at write time: SECRET- and SESSION-class
records MUST carry an expires_at field; the store raises
RetentionPolicyError
when it is absent.
- class SecretRecord(**data)[source]¶
Bases:
BaseModelFrozen record persisted in the
SecretStore.- Variables:
key – Operator-facing natural key (e.g.
aeat:google:oauth-token).value – Secret payload as raw bytes. Plaintext on the API surface only; the blob store encrypts before write.
classification – Sensitivity class. Must be
core.classification.SensitivityClass.SECRETorcore.classification.SensitivityClass.SESSION; other classes are rejected by the field validator at construction time.metadata – Operator-supplied non-secret tags (e.g. operator email, issued_by, scope). Stringified key/value entries only.
created_at – Timezone-aware datetime captured at write time.
expires_at – Optional explicit expiry. Required for the
SECRETandSESSIONclasses per the default retention policy.
- Parameters:
- key: str¶
- value: bytes¶
- classification: SensitivityClass¶
- metadata: dict[str, str]¶
- created_at: datetime¶
- expires_at: datetime | None¶
- class SecretStore(*, store_dir, blob_store, master_key_provider=None)[source]¶
Bases:
objectRepository for the substrate’s secret and session-bearing state.
Wraps an
adapters.persistence.storage.blob_store.EncryptedBlobStorebehind a digest-keyed index so callers can query records by their natural string key without that key ever appearing in plaintext on disk. Mutating operations are serialised viacore.locks.exclusive_file_lock().- Parameters:
store_dir (Path)
blob_store (EncryptedBlobStore)
master_key_provider (MasterKeyProvider | None)
- put(record, *, overwrite=False)[source]¶
Persist
recordand return the underlying blob reference.Acquires the store-wide
core.locks.exclusive_file_lock()for the duration of the write.- Parameters:
record (
SecretRecord) – TheSecretRecordto persist.overwrite (
bool) – IfTrue, replace any existing record at the same key. IfFalse(default), raiseSecretAlreadyExistsErroron collision.
- Return type:
- Returns:
The
adapters.persistence.storage.blob_store.BlobReferencefor the freshly written blob.
- get(key)[source]¶
Return the
SecretRecordpersisted underkey.- Parameters:
- Return type:
- Returns:
The decrypted
SecretRecord.- Raises:
SecretNotFoundError – When no record exists for
key.
- delete(key)[source]¶
Remove the record persisted under
key.- Parameters:
- Raises:
SecretNotFoundError – When no record exists for
key.- Return type:
- list_digests()[source]¶
Yield every persisted lookup digest.
Plaintext keys are NOT recoverable from digests by design; this method exists for inventory diagnostics (e.g. counting records, rotating store-wide).
- rotate(key, new_value, *, expires_at=None)[source]¶
Replace the value of an existing secret and return the new blob reference.
Holds the store-wide
core.locks.exclusive_file_lock()across the read and write so a concurrentrotate(),put(), ordelete()cannot interleave between the lookup and the overwrite.- Parameters:
- Return type:
- Returns:
The
adapters.persistence.storage.blob_store.BlobReferenceof the rotated blob.