Inventory data by purpose

For each feature, list input address/domain/IP, raw message/header/body, parsed metadata, check evidence, provider request/response, report capability, account ownership, audit event, log, analytics event, export, cache, queue payload/failure, and backup. Add location, encryption, access, processor, owner, and purpose.

Separate content needed briefly for analysis from durable aggregate findings. A raw test message can be much more sensitive than a status code; do not give both the same default lifetime.

Choose periods with accountable approval

Set a maximum active lifetime for each class based on user purpose, incident/audit need, provider contract, and applicable legal requirements. Record the decision owner and review date. “Keep forever in case useful” is not a retention rule.

Define what account deletion/export includes, what minimal suppression/audit evidence must remain, how legal holds override normal expiry, and when the hold ends. Avoid promising immediate backup erasure if the architecture only supports aging out encrypted backups on a schedule; explain and approve the real behavior.

Automate lifecycle transitions

Attach expiry at creation. Queue deletion for database rows, encrypted objects, search indexes, caches, generated reports, and provider-side jobs. Revoke report capabilities and credentials. Ensure retries are idempotent and a failed deletion appears in readiness/alerts.

Use crypto-erasure only under a reviewed key hierarchy where destroying a scoped key reliably makes data unrecoverable. Deleting an application reference while an object remains addressable is not enough.

Protect the disposal process

Authorize and audit deletion without logging the sensitive payload. Require step-up approval for bulk/operator deletion, protect against tenant crossover, and preserve append-only receipts with safe identifiers. Do not let a user choose storage paths.

Verify end to end

Create tagged synthetic fixtures across every store. Advance the retention job in a test environment, assert content/capabilities/exports/caches disappear, and verify held records remain. Test restore from a backup to ensure expired data is re-expired or segregated during recovery.

Publish the inventory, periods, backup caveat, owners, and last test. Retention is implemented when every copy has a lifecycle and failed disposal is observable—not when the primary table has a deleted_at column.