Registry stack documentation: machine-readable Markdown.
Index of all pages: https://docs.registrystack.org/preview/llms.txt
Full corpus: https://docs.registrystack.org/preview/llms-full.txt

# Retention and persistent state

> What Registry Relay and Registry Notary retain, what expires, and what operators must preserve or ship off host.

Use this page to decide which Registry Stack state needs backup, off-host shipping, expiry,
or deletion policy outside the products.
It documents current Registry Relay and Registry Notary behavior.
Retention enforcement, record-level erasure, and data-subject-rights workflows are outside the
1.0 product boundary.

## Operator boundary

Registry Stack gives operators rotation knobs, TTL-bound protocol stores, pseudonymized audit
handles, and deployment-posture gates.
It does not decide the legal retention period for a deployment, delete source-registry records,
or prove that a local rotating file kept every historical audit event.

Two consequences follow from that boundary:

- Treat local audit files as tamper-evidence for the retained records, not as a completeness
  guarantee for all records ever written.
  Use off-host shipping when completeness matters.
- Treat keyed pseudonyms as a linkability control, not as erasure.
  Destroying or rotating the HMAC secret prevents recomputing old pseudonyms from raw values,
  but it does not delete audit records, cache entries, status records, or source data.

## Durable state and externally retained records

| Store | What it can contain | Expiry or rotation | Operator control |
|---|---|---|---|
| Relay and Notary audit sinks | Chained audit envelopes with timestamps, event bodies, hashes, and HMAC-pseudonymized sensitive handles when configured. Operational metadata can still identify actors or actions. | Product file sinks default to `100 MB` and `14` retained files. `stdout` and `syslog` retention belongs to the collector. | Configure `audit.sink`, file path, rotation, `audit.hash_secret_env`, and off-host shipping. |
| Relay and Notary audit shipper cursor | Local `registry.audit.ack_cursor.v1` state with the acknowledgement time and last acknowledged chain hash, plus an optional shipper identifier. | The shipper atomically replaces the file after each successful hand-off. The runtime does not expire or rewrite it. | Mount the file read-only for the Registry process, keep it on local storage and at or below 16 KiB, and configure `deployment.evidence.audit_ack_cursor_path`. |
| Relay ingest cache | Normalized Parquet snapshots under `server.cache_dir`. These snapshots can contain full source rows from configured registries. | No time TTL. For audited SnapshotExact, the authored `retain_generations` value keeps between `1` and `16` completed cache generations, including the active generation, after successful publication. Ordinary sources keep the built-in current and previous generations. Older snapshots are removed best effort. | Place `server.cache_dir` on writable storage with the same data classification as the source rows. Treat authored retention as a bounded recovery set, not an API for selecting arbitrary rollback targets. |
| Config-trust anti-rollback state | The last accepted sequence, config and bundle hashes, root version, and optional break-glass pin metadata. Operator names, approval references, and reasons can be sensitive. | The state file is rewritten atomically and has no normal TTL. Break-glass overrides require expiry, and consumed override files are renamed. | Preserve `antirollback_state_path` across upgrades and protect break-glass override files with local root controls. |
| Relay consultation correctness state | Durable consultation audit, attempts and completions, dispatch permits, quota buckets, materialization publication history, batch-child replay bindings, serving-fence state, and audit-pseudonym keyring metadata. Pseudonymous handles and operational metadata can remain linkable. | Batch-child replay rows expire after `15 minutes` and are pruned on later reservations. Other Relay consultation tables have no general time-based pruning. Keyring retention controls when retired pseudonym key metadata can leave the retained set; it does not delete durable audit rows. | Back up the complete Relay database at a quiesced or coordinated recovery point. Preserve role bindings and key material, and keep any potentially stale restore offline until acknowledged writes are reconciled. |
| Notary correctness state | Hashed replay and nonce identifiers, evaluations, batch idempotency, credential status, keyed quota pseudonyms, encrypted preauthorization login state, and transaction-code verifiers. Credential identifiers and operational metadata can still be linkable. | Each typed domain has an absolute expiry or bounded window. Consumed nonce tombstones last `60` seconds. Credential status lasts through credential expiry plus `retention_seconds`. | Use the Notary-owned PostgreSQL schema for production and multi-instance deployments. Back up the complete database and keep a potentially stale restore offline through the documented quarantine. |
| Operator-owned config, source, and secret paths | Runtime configuration, signed bundles, trust anchors, metadata manifests, source files, provenance keys, and secret references. Source files can contain personal data. | Registry Stack does not expire these files, except through the specific audit, cache, replay, status, and break-glass mechanics above. | Mount source data read-only where possible; back up config, trust anchors, anti-rollback state, and secrets through your platform controls. |

## Process-local caches and client-held state

| Store | What it can contain | Expiry or rotation | Operator control |
|---|---|---|---|
| Relay and Notary OIDC JWKS cache | Issuer signing keys and negative lookup entries, not subject records. | In process only. Default positive cache TTL is `600` seconds and default negative cache TTL is `60` seconds. | Configure Relay OIDC `jwks_cache_ttl` where exposed. Notary shared fetchers use platform defaults where no product knob is exposed. Restart clears the cache. |
| Relay auth-failure throttle | Process-local counters keyed by resolved client address. Client IP addresses can be personal data. | Fixed window when enabled; defaults are disabled, `20` failures, and `60` seconds. Restart clears counters. | Configure `auth.failure_throttle.*` and `server.trust_proxy` correctly behind proxies. |
| Relay response headers | No Relay-owned response/result cache was found. Client and proxy caching follow HTTP headers. | Metadata and default release responses are `no-store`; successful release responses can opt into private max-age. | Configure release-profile response max age only when private client caching is acceptable. |
| Relay pagination cursors | Client-held signed cursor payloads can include query context, filters, principal ID, ingest version, and position. | Not stored server-side and no product TTL. Cursors become invalid when signer, principal, query, config, or ingest version changes. | Treat cursor tokens as client-held request context and avoid logging them unnecessarily. |
| Credential status-list JWT cache | Signed status-list JWT strings and hashed cache keys derived from credential status metadata, status URL, timestamps, and public JWK hash. | In memory only. Entries are pruned on access and expire no later than the `300` second JWT expiry; valid status entries expire earlier when the credential expires first. | Enabled only when credential status is enabled. Restart clears the cache; there is no separate size or storage knob. |
| Relay source OAuth token caches | Access tokens used by compiled Relay source credential providers. | In memory and bounded by the provider's token lifetime. | Configure the Relay integration credential binding and keep token secrets out of logs and config files. |

## Audit retention

Relay and Notary can write chained JSONL audit records.
The product file-sink defaults retain `14` files at `100 MB` each.
The shared platform sink has a smaller generic default, but the products override it when their
own audit config is used.

The chain detects edits, insertions, reordering, and deletion after the first retained record
within the retained set.
It does not prove that older rotated-away records, or earlier retained records, still exist.
If a deployment uses a local rotating file sink without off-host shipping, Relay and Notary surface
deployment-posture findings such as `relay.audit.retention_local_only` and
`notary.audit.retention_local_only`.
Under `evidence_grade`, those findings refuse startup.
Set `deployment.evidence.audit_offhost_shipping` only after the deployment really ships audit
records to external durable storage.

An `evidence_grade` Relay or Notary also requires an acknowledgement cursor for every configured
shipping target, including `stdout` and `syslog`.
The cursor is healthy only when its timestamp is fresh and its last acknowledged hash equals the
live keyed audit chain tail.
That equality records the trusted shipper's claim that the local backlog is zero; the unsigned
local cursor does not prove that external storage received or retained the records.
The shipper must continue running while the application reports not ready, because the signed
bundle acceptance event advances the audit tail before the service begins serving requests.
Offline `doctor` commands cannot bind a cursor to a live tail and report a fresh cursor as
`unverified`.

Never truncate, rewrite, or reserialize audit files as part of cleanup.
Back them up as files, keep old hash secrets for the audit retention period, and rotate hash
secrets only as an intentional key-lifecycle event.

## Relay consultation-state retention

When `consultation` is enabled, Registry Relay uses PostgreSQL transactions for durable audit,
single-holder dispatch fencing, quota decisions, consultation completion, batch-child replay,
materialization publication, and audit-pseudonym keyring authority. Process restart and fence
takeover recover unfinished consultation attempts before admission opens.

Relay owns `relay_state_private` and `relay_state_api`. Registry Notary owns
`registry_notary_private` and `registry_notary_api`. The products do not share tables, migrations,
runtime roles, or keyrings even when their databases run in one PostgreSQL cluster.

The Relay consultation store excludes registry source rows, raw selectors, source URLs, and source
credentials. It retains bounded canonical operation state, keyed commitments and pseudonyms,
audit envelopes, result and publication metadata, and keyring lifecycle metadata. Treat this as
sensitive operational state. The 15-minute expiry for a batch-child replay row is the only fixed
row-retention deletion in the consultation protocol. Relay does not automatically prune durable
audit phases, completed consultation intent, materialization publication history, or quota rows as
a general retention service.

Set the keyring's audit-event retention interval to the deployment's audit policy. That interval
prevents retired pseudonym key metadata from leaving the retained key set too early; it does not
delete audit events or replace the operator's database retention policy. Keep every retained
pseudonym key value in the secret manager for the same period as the corresponding database and
audit records.

Back up the complete Relay database after quiescing writers, or use a coordinated platform
snapshot. Preserve the schema owner, runtime, keyring-maintenance, and keyring-reader role object
identifiers with the backup. Relay startup and readiness attest schema and keyring consistency but
cannot detect writes missing from a stale recovery point. The
[Relay product documentation](../../products/registry-relay/) and
[backup and restore procedure](../backup-and-restore/) define the recovery boundary.

For audited SnapshotExact, the recoverable unit also includes the immutable source inputs and
Relay ingest cache captured at the same quiesced point as the Relay database. Bind the source and
cache artifact hashes to the database active-pointer and history state, exact generation, and
restricted content digest in access-controlled recovery evidence. `retain_generations` keeps a
bounded set of cache files available for recovery and readers. It does not expose an operation
that activates any retained generation as an arbitrary rollback target.

## Notary correctness-state retention

Registry Notary enforces one-time use, cross-replica quota decisions, evaluation retention,
idempotent completion, and credential lifecycle transitions through typed PostgreSQL transactions.
The process-local backend is available only for explicit local, single-instance development and
loses every correctness decision on restart.

The PostgreSQL store does not retain credential bodies, source rows, holder private keys, raw
transaction-code PINs, or source-system credentials. It does retain encrypted or pseudonymized
operational state that needs access, backup, and deletion controls. Use the
[Registry Notary PostgreSQL operations guide](https://docs.registrystack.org/products/registry-notary/postgresql-state-operations/)
for domain retention, bounded pruning, backup, recovery, and stale-restore quarantine.

## What remains outside the product

Registry Stack does not implement a general erasure workflow for source records, audit records,
cache entries, or credential status records.
It also does not prune operator-owned config files, source files, old release artifacts, or
break-glass evidence after the product-level expiry checks have run.
Those controls belong in the operator's storage, backup, incident-response, and data-protection
processes.

## Next

- [Run single-node Compose behind your reverse proxy](../single-node-compose-behind-proxy/)
- [Back up and restore a deployment](../backup-and-restore/)
- [Upgrade and roll back a deployment](../upgrade-and-rollback/)
- [Harden a production deployment](../../security/hardening-checklist/)
- [Known limitations and non-guarantees](../../explanation/known-limitations/)