Source code for aeat.application.bucket_maintenance._manifest_digest
"""Manifest-digest helper for the sealed bucket-export archive header.Used by: :class:`~application.bucket_maintenance.BucketMaintenanceService`to generate export archive digests.The ``ExportArchiveHeader.manifest_digest`` field carries aSHA-256 hex digest over the serialised :class:`BucketManifest` JSONbytes. The digest is the export's integrity anchor: it is bound into thesealed payload's AEAD associated data (``_archive_associated_data`` in:mod:`~._service`), so tampering with the header digest makes thepayload's AEAD tag verification fail and the import is refused atdecryption.The digest is NOT recomputed-and-compared against the freshly-provisionedmanifest on the import host. The manifest carries host-specific lifecycletimestamps (``created_at``, ``last_unlocked_at``) that legitimately differbetween the exporting and importing hosts, so a literal recompute could nevermatch; the AEAD binding is the authoritative integrity mechanism.Authority: ``2026-06-03-bucket-sealed-archive-adr``."""from__future__importannotationsfrom...adapters.persistence.storage.bucketimportBucketManifestfrom...core.external_constantsimportUTF_8_ENCODINGfrom...core.hashingimportsha256_hex
[docs]defcompute_manifest_digest(manifest:BucketManifest)->str:"""Return the SHA-256 hex digest of ``manifest`` serialised to JSON. Uses JSON rather than TOML because pydantic's ``model_dump_json`` provides a deterministic byte-stable serialisation that does not depend on the hand-rolled TOML emitter. The digest is the archive-header integrity anchor: it is bound into the sealed payload's AEAD associated data, so a tampered digest fails the payload's authentication tag and the import is refused at decryption (it is not recomputed-and-compared against the import- host manifest, whose lifecycle timestamps legitimately differ). The output is a 64-character lowercase hex string matching the ``manifest_digest`` field constraint on :class:`~adapters.persistence.storage.bucket.ExportArchiveHeader`. """serialised=manifest.model_dump_json().encode(UTF_8_ENCODING)returnsha256_hex(serialised)