113 lines
5.5 KiB
Markdown
113 lines
5.5 KiB
Markdown
|
|
# Erasure versus audit
|
||
|
|
|
||
|
|
**Status:** audit-core's position. Written for AUDIT-WP-0008-T03.
|
||
|
|
**Framework:** NetKingdom Tenancy Posture v0.1 (draft-8), §4.5 and §19.11.
|
||
|
|
**Declared consequence:** `tenancy.yaml` targets `R2`. `R4` is not a target.
|
||
|
|
|
||
|
|
## The question
|
||
|
|
|
||
|
|
Raised by `rapp-postgres` as question 11 of the tenancy posture review. The
|
||
|
|
retention axis tops out at `R4`, verified erasure, reachable either by waiting
|
||
|
|
out the erasure horizon or by encrypting per entity and destroying the key.
|
||
|
|
Crypto-shredding is the established mechanism for erasure under immutable
|
||
|
|
retention.
|
||
|
|
|
||
|
|
Applied to an audit service it destroys the evidence the service exists to hold.
|
||
|
|
|
||
|
|
The question was asked because a naive "R4 everywhere" fleet target would
|
||
|
|
instruct this service to erase its own trail, and nobody would notice until it
|
||
|
|
mattered.
|
||
|
|
|
||
|
|
## The shape of the answer, and why it is not enough
|
||
|
|
|
||
|
|
The literature's usual resolution is to separate the **fact** of an event,
|
||
|
|
retained, from its **personal payload**, encrypted per subject and shreddable.
|
||
|
|
The trail survives erasure with its personal content removed. That shape is
|
||
|
|
right, and we accept it as the shape.
|
||
|
|
|
||
|
|
It does not survive contact with this repo's integrity design, in two ways.
|
||
|
|
|
||
|
|
### 1. It is not retrofittable
|
||
|
|
|
||
|
|
`_record_hash` (`audit_core/postgres_backend.py`) is SHA-256 over the canonical
|
||
|
|
JSON of the **cleartext** record, and the hash chain commits to that value.
|
||
|
|
Encrypting a payload after the fact severs the binding between `payload_hash`
|
||
|
|
and the stored record: the chain still verifies, because `verify_rows` walks
|
||
|
|
stored hashes, but the hash no longer attests to anything present.
|
||
|
|
|
||
|
|
Shreddability has to be built as **encrypt-then-hash at accept time**, with the
|
||
|
|
chain committing to ciphertext. Retrofitting it onto events already accepted
|
||
|
|
means rewriting the chain — which is the single thing AUDIT-WP-0007 was built to
|
||
|
|
make detectable. A design that requires forging the tamper-evidence log in order
|
||
|
|
to comply is not a design.
|
||
|
|
|
||
|
|
### 2. The retained hash is a confirmation oracle
|
||
|
|
|
||
|
|
This is the sharper problem and it is easy to miss.
|
||
|
|
|
||
|
|
Audit records are low-entropy. An event carries a type, an actor, a tenant, a
|
||
|
|
subject and a timestamp, drawn from small enumerable sets. Given the retained
|
||
|
|
SHA-256, an adversary guesses a plausible record, hashes the guess, and compares.
|
||
|
|
A match confirms the content.
|
||
|
|
|
||
|
|
So destroying the key **does not** make the payload unrecoverable while that
|
||
|
|
hash survives. Key destruction removes the ability to read the ciphertext; it
|
||
|
|
does nothing about a separate commitment that anyone can test guesses against.
|
||
|
|
|
||
|
|
The remedies are known — an HMAC under a per-subject key that dies with the key,
|
||
|
|
or a per-record salt destroyed alongside it — and neither is built here.
|
||
|
|
|
||
|
|
**Conclusion: crypto-shredding does not reach `R4` under this design.** Claiming
|
||
|
|
it would be an overclaim of exactly the kind §6 exists to prohibit, and worse
|
||
|
|
than most, because the claim being made would be "this data is gone".
|
||
|
|
|
||
|
|
This finding was general rather than specific to us, and the framework adopted
|
||
|
|
it as **Decision 4.5.3**: the key-destroyed route now requires that no retained
|
||
|
|
commitment reveals the erased content. It applies to anyone hashing, chaining or
|
||
|
|
indexing what they intend to shred.
|
||
|
|
|
||
|
|
## What audit-core therefore declares
|
||
|
|
|
||
|
|
- **Target `R2`**, not `R4`. Retention declared per dataset, erasure horizon
|
||
|
|
published. That is in `tenancy.yaml` and reflected on `/readyz` as
|
||
|
|
`recoverable_days`.
|
||
|
|
- **`R4` is unreachable by design**, and §19.11 records audit-core as explicitly
|
||
|
|
exempt from any fleet `R4` target.
|
||
|
|
- **Our provider block says so to senders.** A consumer with a verified erasure
|
||
|
|
obligation over its audit trail cannot discharge it here, and is told that
|
||
|
|
rather than left to assume.
|
||
|
|
|
||
|
|
## The dependency we are not competent to close
|
||
|
|
|
||
|
|
Declining to build erasure means that if an Article 17 request arrives naming a
|
||
|
|
data subject who appears in the audit trail, audit-core has no mechanism. The
|
||
|
|
answer will rest on audit evidence being exempt — legal obligation, or
|
||
|
|
legitimate interest in fraud and security investigation.
|
||
|
|
|
||
|
|
Those grounds are ordinary and widely relied on. They are also a **legal
|
||
|
|
conclusion**, and this repo is not competent to reach one. Nothing in `INTENT`,
|
||
|
|
`SCOPE`, the capability case, or the framework records anyone in this estate
|
||
|
|
having actually reached it. §19.11 says as much in the framework's own words:
|
||
|
|
"the legal basis for retaining audit facts remains a risk/legal question outside
|
||
|
|
this framework."
|
||
|
|
|
||
|
|
**Routed to `risk-nexus`**, which owns judging what an external rule demands of
|
||
|
|
the estate (moved there from `policy-nexus` on 2026-08-17). Open, unowned inside
|
||
|
|
audit-core, and deliberately visible.
|
||
|
|
|
||
|
|
The distinction being drawn: a *recorded tension* is a position someone has
|
||
|
|
taken and can defend. An *unnoticed liability* is the same technical state with
|
||
|
|
nobody named. An audit service discovering mid-regulator-question that its
|
||
|
|
exemption was assumed rather than established is the specific failure this
|
||
|
|
document exists to prevent.
|
||
|
|
|
||
|
|
## What would change the position
|
||
|
|
|
||
|
|
- A `data.archive` provision with per-subject encryption at accept time, making
|
||
|
|
encrypt-then-hash available for new events. Old events remain unshreddable.
|
||
|
|
- A ruling or advice from `risk-nexus` that the retention basis does not hold,
|
||
|
|
which would make the R4 problem urgent rather than theoretical.
|
||
|
|
- A sender arriving with a genuine per-subject erasure obligation over its audit
|
||
|
|
trail. Today none exists; the provider block is written so one would find out
|
||
|
|
before building on us rather than after.
|