Last verified: 28 September 2026
Backup & Restore
Substrate signs digests; operators store bytes. Every backup bundle carries a substrate-attested cryptographic manifest you can verify offline — independently of Substrate infrastructure.
Substrate-attested backup integrity
When an operator issues a backup bundle, the substrate computes layered digests (schema, data, config, expression manifests), signs them with an Ed25519 key held in cluster_signing_keys (purpose = 'backup_bundle_signing'), and stores the signed manifest. The actual data bytes live in operator-controlled object storage (S3 / GCS / Azure Blob / on-prem MinIO / local filesystem for air-gap deployments). The substrate stores only the manifest JCS, the Ed25519 signature, the storage URI, and the SHA-256 of the bytes — it never stores, proxies, or transports the raw data.
This is your data. You hold it. Substrate provides cryptographic verifiability of backup integrity. A recipient downloads bytes from storage_uri, recomputes storage_content_sha256, and calls verifyBackupBundle() to confirm the Ed25519 signature matches the manifest. No Substrate infrastructure required after the bundle is issued. Aligns with §CC sovereign-mode no-phone-home + §LL no-ambient-collection invariants.
Bundle kinds
Generated from lib/registry/backup-bundle-kinds-registry.ts · 2 closed kinds (§ZB H2 — adding a 3rd kind requires a §ZB amendment + coordinator gate)
Every issued backup bundle carries a bundle_kind declaration from this closed registry. guard:backup-bundle-shape (BLOCKING-from-day-one) enforces the closed 2-value enum at every CI pass.
environment-backup-manifest — Environment Backup Manifest
Substrate-attested layered-digest manifest covering the full org+environment data surface at a point in time. Captures schema_digest (pg_dump --schema-only), data_digest (pg_dump --data-only), config_snapshot_digest (system_settings JCS), and an optional audit_bundle_id pointer to the §ZA audit export covering the same time-window. The substrate signs the digests; the operator stores the actual bytes in operator-controlled object storage per H17. Verification: download bytes from storage_uri, recompute SHA-256, verify manifest signature.
default retention: long · since: ZB-i
expression-snapshot-manifest — Expression Snapshot Manifest
Substrate-attested snapshot of expression-version state at a point in time. Records a composedFromDigest-anchored snapshot of every active expression manifest version in the environment, enabling recipients to verify that a restored deployment matches the expression configuration at backup time. Lighter-weight than a full environment backup; default retention is medium (1 year) since expression manifests are substrate-bootstrapped and recoverable from the canonical expression registry. Useful for checkpoint-style snapshots between full environment backups.
default retention: medium · since: ZB-i
Retention classes
Generated from lib/registry/audit-retention-classes-registry.ts · 4 closed classes (reused §ZA canon per §ZB H10 — adding a 5th class requires a §Z amendment)
Backup bundles declare a retention_class from the same closed 4-value enum used by the audit lifecycle (§ZA). Default mappings per bundle kind are set in BACKUP_BUNDLE_KINDS_REGISTRY.defaultRetentionClass. Per-framework retention floors (ComplianceFramework.backupRetentionMinDays) are reserved for post-launch counsel population — the shape mirrors auditRetentionMinDays from §GG.
short — Short (90 days)
Ephemeral operational events (auth flows, session events). Regulatory floor rarely exceeds 90 days for this class; GDPR Article 30 does not mandate retention for purely transient system events.
retention: 90 days · since: ZA-iii
medium — Medium (1 year)
Standard operational audit trail (identity changes, commerce lifecycle, integrity checks). Matches common EU/UK GDPR data-minimisation guidance for business-process audit records.
retention: 365 days · since: ZA-iii
long — Long (7 years)
Governance and regulatory events (organisation creation, stewardship grants, data subject requests, substrate-operator attestations). Matches EU VAT directive + DORA + NIS2 minimum retention floors for business-critical records. 2555 days = 7 × 365 days (leap-year rounding per telemetry-pattern).
retention: 2555 days · since: ZA-iii
permanent — Permanent (never expires)
Chain-structural events that must never be deleted: audit chain restoration anchors and partition-archival attestations. Sentinel value -1 maps to expires_at = NULL in audit_log. These rows outlive any partition-drop cycle.
retention: never expires (permanent) · since: ZA-iii
Verification ceremony
Bundle verification is a 2-of-2 distinct-actor ceremony matching the §ZA audit-chain restoration pattern (H7). Two operators must co-sign:
Custody-operator (ecosystem.custody.signed_bundle_issued) — attests signature integrity: confirms the Ed25519 signature over the JCS-canonical manifest is valid for the cluster signing key. Reuses the custody attestation path established for §ZA audit export bundles.
Resolution-operator (ecosystem.resolution.backup_verification_ratified) — ratifies the verification result: co-attests that the custody-operator's verification finding is substantively correct. New capability key, substrate-natural §Y extension, closed 16-role canon untouched.
Identical-actor rejection (C-EE-PRE-7 precedent): the custody-actor participant ID and the resolution-actor participant ID MUST differ. verifyBackupBundleCeremony() throws identical-operators when the same participant is supplied for both roles.
Verification-only at v1 (H4): in-place restore is deferred behind <horizon:in-place-restore-ceremony>. At v1, restoration is an operator-side operation — download the bytes from storage_uri, verify the bundle, run pg_restore against a fresh target environment using your own ops tooling. Substrate provides cryptographic verifiability of the backup integrity; you own the restore workflow.
Storage-pointer model
Substrate stores only:
· The signed manifest JCS (backup_bundles.signed_manifest_jcs)
· The Ed25519 signature (backup_bundles.ed25519_signature)
· The storage pointer (backup_bundles.storage_uri)
· The bytes digest (backup_bundles.storage_content_sha256)
Operator object storage options: S3 / GCS / Azure Blob / on-prem MinIO / local filesystem (file:///srv/backups/<bundle_id>.tgz) for air-gapped deployments. Configured at the deployment layer via system_settings.backup.storage_provider. The substrate validates the manifest and signature; it never touches the raw bytes.
Audit-chain linkage
A backup bundle MAY reference a §ZA audit export bundle via the audit_bundle_id field in BackupBundleManifest. When both are issued for the same time-window, the backup manifest points to the audit export, materialising an end-to-end tamper-evident lineage chain:
backup_bundle.audit_bundle_id → audit_export_bundles.bundle_id → audit_chain_segments.terminal_entry_hash → audit_log.entry_hash
A backup without a paired audit export still verifies cryptographically but lacks the audit-chain attestation. Operators MAY issue an audit export first, then a backup, to chain them for maximum verifiable continuity. audit_bundle_id is nullable — the field admits NULL when no audit pairing exists.
Registry sources: lib/registry/backup-bundle-kinds-registry.ts (2 kinds) · lib/registry/audit-retention-classes-registry.ts (4 classes) · lib/registry/ecosystem-coordination-roles-registry.ts (custody + resolution role rows)
C-GG-23 trust-page-no-i18n — inline English literals · CONTRACT §ZB (Phase 3e) · AGENTS.md Rule 26
guard:backup-bundle-shape (BLOCKING) · guard:backup-bundle-retention-class-declared (BLOCKING) · guard:trust-backup-restore-page-matches-registry (BLOCKING)