aeat.application.modelo._review_package_recipient_replay_guard module¶
Replay-nonce ledger for recipient-encrypted review packages.
Every RecipientEncryptedPackage carries a
fresh, unique envelope_nonce_hex minted at encryption time (see
_review_package_recipient_encryption). This
module lets the recipient side of decrypt_review_package_for_recipient()
record which nonces have already been successfully decrypted, so a captured
ciphertext replayed a second time against the same recipient bucket is
refused rather than silently re-accepted.
The nonce ledger is a bucket-scoped append-only consumption record, following
the exact governed-repository shape of
RecipientFingerprintRegistryRepository: one
FINANCIAL-sensitivity secure-object singleton per bucket, an empty ledger
when absent, and mark_consumed refuses a nonce already on file. This is
the composition-service-no-parallel-write-path companion to that
registry – the decrypt primitive itself performs no persistence; a caller
(the future CLI decrypt verb) composes this ledger’s check_and_consume
around the existing, unmodified
decrypt_review_package_for_recipient() call.
The encrypted row’s storage policy is governed by
SensitivityClass.
Nonce identity is clock-free (the nonce is a random 32-byte value minted once
per encryption, never derived from a timestamp), so replay defence does not
depend on wall-clock ordering the way the paired expiry check does – see
_review_package_recipient_encryption for the
issued_at / valid_until expiry fields, which are a distinct concern
(a package can be replayed within its validity window, and expiry alone does
not detect a same-nonce replay before the deadline).
See also
_review_package_recipient_encryptionMints the
envelope_nonce_hexthis ledger consumes and defines the paired expiry fields._review_package_recipient_registryThe structural template this repository mirrors.
- exception RecipientReplayGuardError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
AeatErrorBase error for recipient-package replay-guard failures.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- exception RecipientPackageReplayedError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
RecipientReplayGuardErrorRaised when a nonce already recorded as consumed is presented again.
A captured recipient-encrypted package replayed against the same bucket (whether by an adversary or by an operator’s own accidental re-run) is refused – the nonce is single-use once consumed.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- class ConsumedNonceRecord(**data)[source]¶
Bases:
BaseModelOne consumed
envelope_nonce_hexon file, with its consumption time.- nonce_hex: str¶
- consumed_at: datetime¶
- class ConsumedNonceLedger(**data)[source]¶
Bases:
BaseModelA bucket’s full set of consumed recipient-package replay nonces.
- Parameters:
records (tuple[ConsumedNonceRecord, ...])
- records: tuple[ConsumedNonceRecord, ...]¶
- class RecipientReplayGuardRepository(*, bucket_id=None, objects=None)[source]¶
Bases:
objectGoverned repository for the encrypted consumed-nonce ledger.
The singleton row is owned by
MODELO_REVIEW_PACKAGE_RECIPIENT_REPLAY_GUARD_NAMESPACEand persisted throughSecureObjectRepository, mirroringRecipientFingerprintRegistryRepository.- Parameters:
bucket_id (str | None)
objects (SecureObjectRepository | None)
- load()[source]¶
Load the ledger, returning an empty ledger when absent.
- Raises:
RecipientReplayGuardError – When the envelope exists but the filesystem I/O itself fails.
DecryptionError – When the envelope exists but its ciphertext fails AEAD authentication (tampered or corrupted at rest) – propagated verbatim rather than re-wrapped, so a caller can distinguish “this ledger was tampered with” from a generic I/O failure. This is the anti-tautology proof this repository’s roundtrip tests require: a corrupted on-disk payload must be refused loudly, not silently coerced into a plausible-looking empty ledger (which would re-open every previously-consumed nonce to replay).
- Return type:
- mark_consumed(nonce_hex, *, consumed_at=None)[source]¶
Atomically record
nonce_hexas consumed.- Parameters:
nonce_hex (
str) – The envelope’senvelope_nonce_hex(seeRecipientEncryptedPackage).consumed_at (
datetime|None) – Optional override for the record’sconsumed_attimestamp (tests only); defaults to the current UTC time.
- Raises:
RecipientPackageReplayedError – When
nonce_hexis already on file – the package has been presented for decryption before.- Return type: