# Backup and restore flow

## Purpose and scope

This procedure map separates backup creation and evidence from archive
inspection and an operator-approved restore. It does not represent live objects
or prove that an application can be recovered.

- **Source:** `sources/backup-restore.mmd`
- **Generated output:** `generated/backup-restore.svg`

![Sanitized backup and restore flow](generated/backup-restore.svg)

## Components and boundaries

The backup job selects allowlisted Kubernetes configuration. It does not query
Secret objects, and it reduces ConfigMaps to names and keys. Selected workload
specifications remain intact, so literal environment values, arguments, or
annotations are not independently scrubbed. The archive is therefore treated
as sensitive, compressed, age-encrypted, authenticated through Workload
Identity Federation, and uploaded to private Cloud Storage. Cloud IAM and
storage form a separate trust boundary; key custody and restore approval remain
operator-owned. The diagram's “sanitized” label means a restricted export, not
a guarantee that every retained field is public-safe.

## Data flow and failure paths

The evidence path is select → restrict resource/value export → compress →
encrypt → authenticate → upload → compare the remote object → emit status.
Selection, encryption, federation, upload, verification, and retention can fail
independently.

The recovery path is choose → download → integrity check → decrypt → list and
inspect → dry-run → controlled apply → post-restore checks. The recorded evidence
ends at decrypt-and-list inspection. Dry-run, resource application, application
startup, and data validation require separate proof.

## Omissions

The archive is not a volume, database, application-data, or complete cluster
backup and does not contain every bootstrap dependency. Credentials, encryption
identities, bucket names, object paths, and configuration values are omitted.

## Verification

Backup scripts and Kustomize output were reviewed on 16 July 2026, and the
CronJob last-success time was observed read-only that day. An encrypted upload,
remote-size comparison, and decrypt-and-list inspection were recorded on
15 July 2026; no resource apply occurred. On 24 July, read-only GCP inventory
confirmed the private backup bucket's uniform access, enforced public-access
prevention, versioning, and four lifecycle rules. That cloud control check does
not refresh the older CronJob/archive evidence or turn archive inspection into
a restore.

Pair this with [backup verification](../runbooks/backup-verification.md),
[restore validation](../runbooks/restore-validation.md), and the
[disaster-recovery overview](disaster-recovery.md).

Regenerate and validate with `npm run diagrams && npm run diagrams:check`.
