aeat.core.classification package

Sensitivity classification primitives for persisted state.

Every persisted record (SQL row, file-backed envelope, blob, secret-store entry, audit-log entry) declares a SensitivityClass. Each class maps to a default ClassificationPolicy resolved by default_policy_for(); the policy pins the at-rest treatment (plaintext or ciphertext-required), retention behaviour, and the redaction rule references that the audit sink and run-trace path honour. Operator-facing output uses OutputSensitivityClass and default_output_policy_for() so CLI public output can be classified without pretending it is a persisted record.

The default policy table is the single point of truth. Per-domain repositories MAY override the default for an individual record (e.g. when an operator tags a corpus blob as identity-bearing), but the default is always available via default_policy_for(). Redaction rule references stored as names are resolved to live RedactionRule instances by core.redaction.

class SensitivityClass(*values)[source]

Bases: StrEnum

Closed catalogue of sensitivity classes for persisted state.

Variables:
  • SECRET – Long-lived authentication material — OAuth client secrets, service-account private keys, certificate passphrases, refresh tokens. Treatment: ciphertext at rest; never logged; deletion verifiable; finite TTL required.

  • SESSION – Short-lived bearer state — Playwright storage_state, OAuth access-token caches, AEAT session sidecars. Treatment: ciphertext at rest; integrity-bound to the providing factor.

  • IDENTITY – Operator and taxpayer identity records — NIF, full name, contact email, business profile. Treatment: ciphertext at rest where the field is not needed for query; never logged at INFO or above.

  • FINANCIAL – Bank transaction rows, invoice records, attachment blobs, usage ratios, draft and submission payloads, amendment records. Treatment: ciphertext at rest by default; redaction rules govern log echo; retention aligns to the fiscal year plus statute of limitations.

  • AUDIT – Submission audit log, run-trace records, divergence records, workflow-run records. Treatment: redaction at write time (NIF hashed, URL host-only, token fingerprinted) on top of ciphertext at rest for the underlying record.

  • CACHE – LLM response cache, schema cache, status cache, corpora-derived caches. Treatment: defaults to plaintext for public reference data; identity-bearing caches escalate to IDENTITY.

  • CORPUS – Public reference material — manuals, normatives, BOE PDFs, registry definitions. Treatment: plaintext at rest is acceptable; integrity (SHA-256) MUST still be tracked.

  • OPERATIONAL – Settings, build manifests, low-sensitivity configuration that legitimately remains in plaintext.

  • DIAGNOSTICscratch/ outputs, browser traces, screenshots, network captures. Treatment: governed retention default (e.g. seven days); explicit redaction; opt-in capture.

SECRET
SESSION
IDENTITY
FINANCIAL
AUDIT
CACHE
CORPUS
OPERATIONAL
DIAGNOSTIC
class OutputSensitivityClass(*values)[source]

Bases: StrEnum

Closed catalogue of output redaction surfaces.

Variables:
  • CLI_PUBLIC – Operator-facing CLI success output. It is not a persisted sensitivity class; the renderer redacts before emitting text or JSON.

  • LOG – Log-line and log-context output.

  • ERROR – Error-envelope and exception-message output.

  • DIAGNOSTIC – Diagnostic output that may also be persisted under SensitivityClass.DIAGNOSTIC.

CLI_PUBLIC
LOG
ERROR
DIAGNOSTIC
class AtRestTreatment(*values)[source]

Bases: StrEnum

Closed catalogue of at-rest data-protection treatments.

Variables:
  • PLAINTEXT – The record is stored as-is, with integrity tracking but without confidentiality protection. Acceptable for CORPUS and OPERATIONAL classes.

  • CIPHERTEXT_REQUIRED – The record MUST be stored as ciphertext. Repositories enforce this at write time and refuse mismatches with ClassificationError.

PLAINTEXT
CIPHERTEXT_REQUIRED
class RetentionPolicy(**data)[source]

Bases: BaseModel

Retention envelope for a SensitivityClass.

A policy declares how long a record SHOULD live and when it SHOULD be archived. Repositories enforce max_age at read time when the record carries a written_at field; archival itself is implemented by per-domain repositories.

Variables:
  • max_age – Maximum live-record age. None means unbounded (e.g. for CORPUS material whose lifetime is the project lifetime).

  • archive_after – Age at which a record should be archived from the live store. None means archival is not policy- mandated.

  • require_explicit_expiry – When True, a record of this class MUST carry an explicit expires_at field at write time. Defaults to True for SECRET and SESSION.

Parameters:
max_age: timedelta | None
archive_after: timedelta | None
require_explicit_expiry: bool
class RedactionStrategy(*values)[source]

Bases: StrEnum

Closed catalogue of redaction strategies applied at write time.

Variables:
  • SHA256_PREFIX – Replace the matched value with the first eight hex characters of its SHA-256 digest.

  • HOST_ONLY – For URL-shaped values, retain only the host component; drop path, query, and fragment.

  • FINGERPRINT – Replace bearer / OAuth token-shaped values with their SHA-256 fingerprint formatted as token:sha256:<8hex>.

  • ELLIPSIS – Replace the matched value with three ASCII-safe full stops (...).

SHA256_PREFIX
HOST_ONLY
FINGERPRINT
ELLIPSIS
class RedactionRule(**data)[source]

Bases: BaseModel

One rule applied at write time by the audit sink and run-trace path.

The rule shape is stable; core.redaction.redact() and core.redaction.redact_structured() consume tuples of rules and apply them in order.

Variables:
  • name – Stable identifier for log diagnostics. Lowercase kebab-case.

  • pattern – Regex (Python re flavour) matched against string values to detect the field shape that should be redacted. The regex is compiled at use time, not at declaration; rules can be loaded from configuration without requiring a working regex compiler at import.

  • strategy – How the matched value is rewritten.

  • applies_to – Sensitivity classes this rule applies to. Empty tuple means the rule applies regardless of class.

Parameters:
name: str
pattern: str
strategy: RedactionStrategy
applies_to: tuple[SensitivityClass, ...]
class ClassificationPolicy(**data)[source]

Bases: BaseModel

Default policy attached to one SensitivityClass.

Per-domain repositories consult this record at write time to decide on encryption, retention, and redaction. Per-record overrides are supported by the consumer; the default is always available via default_policy_for().

Variables:
  • sensitivity – The class this policy governs.

  • at_rest – At-rest treatment.

  • retention – Retention behaviour.

  • redaction_rules – Tuple of redaction-rule names (matched by RedactionRule.name) that apply when this class participates in audit-sink writes. Resolution to live RedactionRule instances is performed by core.redaction.default_rules_for(); the policy carries names only so the table can be loaded eagerly without depending on the rule registry.

Parameters:
sensitivity: SensitivityClass
at_rest: AtRestTreatment
retention: RetentionPolicy
redaction_rules: tuple[str, ...]
class OutputClassificationPolicy(**data)[source]

Bases: BaseModel

Default redaction policy attached to an output surface.

Output classification is intentionally separate from SensitivityClass: CLI success output is a rendering-time boundary, while diagnostics may also be persisted and therefore keep their existing at-rest sensitivity.

Variables:
  • output – Output surface this policy governs.

  • redaction_rules – Tuple of redaction-rule names to apply before output leaves the process.

  • persisted_as – Persisted sensitivity class when this output is also stored. None means the surface is emit-only.

Parameters:
output: OutputSensitivityClass
redaction_rules: tuple[str, ...]
persisted_as: SensitivityClass | None
default_policy_for(sensitivity)[source]

Return the default ClassificationPolicy for sensitivity.

Parameters:

sensitivity (SensitivityClass) – The SensitivityClass to look up.

Return type:

ClassificationPolicy

Returns:

The default policy. The returned record is frozen and shared; callers must not mutate it. Per-record overrides are made by constructing a fresh ClassificationPolicy.

default_output_policy_for(output)[source]

Return the default output redaction policy for output.

Parameters:

output (OutputSensitivityClass) – The output surface to look up.

Return type:

OutputClassificationPolicy

Returns:

The default OutputClassificationPolicy. The returned record is frozen and shared.

default_policy_table()[source]

Return the immutable default-policy mapping for every class.

Return type:

Mapping[SensitivityClass, ClassificationPolicy]

Returns:

The shared MappingProxyType view mapping each SensitivityClass to its ClassificationPolicy. The mapping itself and every value are frozen; callers cannot mutate either.