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: BaseModel

Frozen 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.SECRET or core.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 SECRET and SESSION classes 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: object

Repository for the substrate’s secret and session-bearing state.

Wraps an adapters.persistence.storage.blob_store.EncryptedBlobStore behind 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 via core.locks.exclusive_file_lock().

Parameters:
property store_dir: Path

Return the configured store directory.

put(record, *, overwrite=False)[source]

Persist record and return the underlying blob reference.

Acquires the store-wide core.locks.exclusive_file_lock() for the duration of the write.

Parameters:
Return type:

BlobReference

Returns:

The adapters.persistence.storage.blob_store.BlobReference for the freshly written blob.

get(key)[source]

Return the SecretRecord persisted under key.

Parameters:

key (str) – The natural key string passed to put().

Return type:

SecretRecord

Returns:

The decrypted SecretRecord.

Raises:

SecretNotFoundError – When no record exists for key.

delete(key)[source]

Remove the record persisted under key.

Parameters:

key (str) – The natural key string passed to put().

Raises:

SecretNotFoundError – When no record exists for key.

Return type:

None

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).

Return type:

Iterable[str]

Returns:

A tuple of 64-character hex digests in iteration order.

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 concurrent rotate(), put(), or delete() cannot interleave between the lookup and the overwrite.

Parameters:
  • key (str) – Natural key of the record to rotate.

  • new_value (bytes) – The new secret payload bytes.

  • expires_at (datetime | None) – New explicit expiry. Required when the policy mandates it.

Return type:

BlobReference

Returns:

The adapters.persistence.storage.blob_store.BlobReference of the rotated blob.