Backup Attestation
A backup that you cannot prove integrity of is a liability. Every Tetrapus snapshot is hashed into a Merkle root, signed by the Org's audit-scope KMS key, and recorded in backup_manifests. Restore is not just "load the bytes" — it recomputes the root from the restored DB and rejects the restore if the signature doesn't verify.
Lifecycle
backup_manifests table
| Column | Type | Purpose |
|---|---|---|
| id | UUID | Manifest PK |
| org_id | UUID | Tenant |
| backup_id | TEXT | Object-store key (e.g. s3://…/2026-04-26.bin) |
| taken_at | TIMESTAMPTZ | Snapshot wall-clock |
| sha256_root | BYTEA | Merkle root over canonical row hashes |
| signed_by_kid | TEXT | JWKS kid for verification |
| signature | BYTEA | ES256 r||s, 64 bytes |
| restored_verified_at | TIMESTAMPTZ | NULL until first successful restore-verify |
Canonical row order
"sha256 over the database" is meaningless without canonicalisation — Postgres heap order is allowed to change. The snapshot driver enumerates tables in alphabetical order, then rows in primary-key order, hashing the canonical-JSON form of each row. The leaf hashes feed an RFC 6962-shaped Merkle tree (same construction as audit attestation) and the resulting root is what gets signed.
CLI
tetrapus-admin backup snapshot drives the snapshot from an operator workstation; tetrapus-admin backup verify independently re-validates a manifest against a restored DB.
tetrapus-admin backup snapshot \
--org-id 3f2a… \
--out s3://acme-backups/2026-04-26.bin
# wrote 4.7 GiB
# sha256_root = 9b0c8a3e…
# signed_by = jwk_audit_2026q2 (KMS arn:…)
# manifest id = 1aa3-… tetrapus-admin backup verify \
--manifest s3://acme-backups/2026-04-26.json \
--against-db postgres://restore-staging.local/tetrapus \
--jwks-url https://tetrapus.example.com/.well-known/jwks.json
# recomputed sha256_root = 9b0c8a3e…
# signature verified by jwk_audit_2026q2
# OK: restore matches manifest, restored_verified_at recorded Why this matters
- Tamper detection: If anyone modifies the snapshot in object storage, the recomputed root won't match the signed value and restore aborts.
- Region migration: The signed manifest is the artefact region migration hands off — the new region verifies the signature with the customer's KMS public key before bringing the Org online.
- Auditor request: "Show me a backup taken on date X". You can produce both the bytes and a third-party-verifiable proof that the bytes are what was taken on date X.
- Insider risk: Backup operators do not hold the signing key — they can take a snapshot but cannot sign one.
Restore-verify guard
A backup whose restored_verified_at is NULL has never been restore-tested. The platform exposes this metric per Org so operators can alert on "no successful restore-verify in the last 30 days" — turning the once-a-year audit question "do your backups actually restore?" into a continuous metric.
Related
- – Audit Attestation — same Merkle construction
- – CMEK / BYOK — the audit-scope key signs manifests
- – Region Pinning — uses signed manifests for migration
- – Back to Enterprise
Questions?
Reach out for help with integration, deployment, or custom domain codecs.