aeat.adapters.persistence.storage.bucket._manifest module¶
Strict pydantic v2 record for the per-bucket plaintext manifest.
The bucket manifest sits at <aeat-root>/buckets/<bucket-id>/manifest.toml
and carries only non-sensitive metadata: the bucket identifier and label,
creation and unlock timestamps, the Argon2id KDF parameters and salt
(salt is public per Argon2 design), the recovery-enrollment flag, and a
schema version. The manifest never contains the derived key, the wrapped
key, the passphrase, or any byte derivable from them; those artefacts
travel through the separate master-key surface.
The ManifestKdfParams nested model carried here is the
manifest-side shape (algorithm tag, parameter version, the four
Argon2id cost parameters, salt). The canonical OWASP-pinned
constructor and the parameter-window validators live alongside it
under master_key/_kdf_params.py; manifest I/O wires the two
together.
- class ManifestKdfParams(**data)[source]¶
Bases:
BaseModelArgon2id parameters and salt as carried in the bucket manifest.
Strict pydantic v2 record. The canonical OWASP-baseline constructor is declared in
adapters.persistence.storage.master_key._kdf_params; this manifest-side record holds whatever parameters the bucket was enrolled under so a future cost-bump can be non-breaking.- Parameters:
- algorithm: str¶
- version: int¶
- memory_cost: int¶
- time_cost: int¶
- parallelism: int¶
- salt: bytes¶
- output_length: int¶
- class BucketLifecycleStatus(*values)[source]¶
Bases:
StrEnumPlaintext lifecycle marker carried on the bucket manifest.
The encrypted
UserProfileStatusrecord is the lifecycle authority, but reading it costs a bucket decryption. The manifest mirrors that status as a plaintext marker so the manifest scan can exclude a tombstoned profile from every live operator surface (list/switch/ name-uniqueness) without unlocking the bucket. TheProfileRepositoryis the sole writer of both stores and keeps the two in lockstep.Values match
UserProfileStatusso the application-layer repository maps the two enums one-to-one.- ACTIVE¶
- TOMBSTONED¶
- class BucketKeySchedule(*values)[source]¶
Bases:
StrEnumData-key schedule used by encrypted records in this bucket.
- BUCKET_DEK_V1¶
- class BucketManifest(**data)[source]¶
Bases:
BaseModelPlaintext manifest for one per-bucket directory.
The manifest never carries sensitive bytes; see
ManifestKdfParamsfor the salt contract.- Parameters:
bucket_id (Annotated[str, FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])
label (str)
created_at (datetime)
last_unlocked_at (datetime | None)
kdf_params (ManifestKdfParams)
recovery_enrolled (bool)
idle_lock_minutes (int | None)
key_schedule (BucketKeySchedule)
schema_version (int)
status (BucketLifecycleStatus)
- bucket_id: Annotated[str, Field(min_length=1)]¶
- label: str¶
- created_at: datetime¶
- last_unlocked_at: datetime | None¶
- kdf_params: ManifestKdfParams¶
- recovery_enrolled: bool¶
- idle_lock_minutes: int | None¶
- key_schedule: BucketKeySchedule¶
- schema_version: int¶
- status: BucketLifecycleStatus¶
Plaintext mirror of the encrypted record’s lifecycle status.
Required, with no default. A manifest that omits
statusis rejected at the read boundary (fail-closed) rather than silently hydrating as a live profile — a silent default would risk leaking a tombstoned bucket back onto the operator surface. TheProfileRepositorysets it explicitly on every write:ACTIVEat creation,TOMBSTONEDin the same write that tombstones the encrypted record.