Attestkeep docs

Backup and restore

Everything the operator knows lives in PostgreSQL and in cluster resources. Back those up and an installation can be rebuilt; there is no hidden state anywhere else.

What to back up

WhatWhereIf you lose it
The databaseThe bundled PostgreSQL's volume, or the external database you pointed externalDsnExistingSecret atFindings, decisions, exceptions, audit log, evidence archive, users and the licence certificate are gone. This is the backup that matters.
PoliciesImageSecurityPolicy resources — in the cluster, and ideally in git alreadyRe-apply from your repository; the chart reseeds a default if none exists.
The session keySecret attestkeep-session (unless you supplied api.session.existingSecret)Everyone is signed out and signs in again. Nothing else.
The data keySecret attestkeep-data-key — generated by the chart on install, unless you supplied api.dataKey.existingSecretThe issue-tracker credentials sealed under it cannot be opened. Each tracker channel has to have its token entered again, which re-seals it under the new key; nothing else in the product depends on it.
The evidence signing keySecret attestkeep-evidence-key — created by the operator, not the chartA new key is generated and new records seal under it, but checkpoints and evidence documents signed by the old key no longer verify against the installation's current key. History survives; the ability to vouch for old signatures does not. See the evidence trust model.

The webhook's serving certificate is not on the list: the operator reissues it and republishes the CA bundle on its own. The activation key is not either — reinstalling into the same cluster produces the same fingerprint, so the existing licence slot is simply picked up again at activation, as Licensing describes.

Configuration export — the bundle

Since 0.3.4, Settings → Backup exports a JSON bundle of the configuration you built by hand: notification channels, triage decisions, the user list and policies. It exists for the two moves a database dump is the wrong shape for — standing up a second cluster with the same setup, and keeping a portable copy of decisions that took meetings to make.

Backup history. From 1.3.1 the same page lists every export and import, ten to a page: when, by whom, and what the bundle carried — for an import, what was added, how many records were already there, and the cluster and time the bundle was exported from. A preview is not listed. The operator does not keep the bundle itself; the file you downloaded is the only copy.

The bundle complements the database dump; it does not replace it. Findings, admission history, the ledger and its checkpoints only exist in PostgreSQL.

Backing up the bundled PostgreSQL

Attestkeep does not take database backups: the dump is yours to run, schedule and keep. If you brought your own database, your existing backup regime already covers it and this section is not for you. The bundled database is a single-replica StatefulSet named attestkeep-postgresql, and a plain SQL dump is the portable answer:

kubectl -n attestkeep exec statefulset/attestkeep-postgresql -- \
  sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > attestkeep.sql

Schedule it with whatever already runs your cron jobs, and store the file with your other backups. A volume snapshot of the PVC works too, if your storage class offers one — the dump is simply the answer that restores anywhere, including into a different storage class or a different cluster.

Restoring

Install the chart, stop the operator so nothing writes or migrates mid-restore, load the dump, start it again:

kubectl -n attestkeep scale deploy/attestkeep deploy/attestkeep-scanner --replicas=0

kubectl -n attestkeep exec -i statefulset/attestkeep-postgresql -- \
  sh -c 'psql -U "$POSTGRES_USER" -d postgres -c \
    "DROP DATABASE \"$POSTGRES_DB\" WITH (FORCE); CREATE DATABASE \"$POSTGRES_DB\" OWNER \"$POSTGRES_USER\""'

kubectl -n attestkeep exec -i statefulset/attestkeep-postgresql -- \
  sh -c 'psql -q -U "$POSTGRES_USER" "$POSTGRES_DB"' < attestkeep.sql

kubectl -n attestkeep scale deploy/attestkeep --replicas=2
kubectl -n attestkeep scale deploy/attestkeep-scanner --replicas=1

Restoring a dump into the same or a newer operator version is supported: migrations are recorded in the dump, and a newer operator applies only what the dump does not already carry. Restoring a newer dump into an older operator is not — migrations move forward only, which is the same rule Upgrade states for rollbacks.

What a restore means for your evidence

Everything recorded after the dump was taken is gone, and the evidence package does not pretend otherwise. The operator stamps a heartbeat as it runs; on the first pass after a restore it finds the last stamp at dump age and records the whole span since as a window in which the control was not operating. A period report covering it shows the gap, exactly as it shows any other outage.

That is the honest cost of restoring from backup: you get your history back up to the dump, and the document says plainly where history is missing. A restore that could silently paper over the lost window would be a way to rewrite the record, and this product's evidence would be worth less for having it.