Archival & erasure
The archival job
Section titled “The archival job”python -m app.archival run # everything decided & older than the retention windowpython -m app.archival run --days 0 # ignore the window (testing / decommissioning)For each eligible verification it: bundles the encrypted blobs into a tar under
ARCHIVE_DIR/<date>/<verification_id>.tar, writes a manifest (artifact IDs, kinds,
plaintext + ciphertext SHA-256), records the archive ref in the database, deletes
the hot copies, and logs a vault.archived audit event.
Schedule it — a daily cron (Railway cron service, or any scheduler) is right. The job is idempotent; already-archived artifacts are skipped.
Get the bundles offline — the archive dir is a staging area. Periodically move its contents to your offline media (two copies, separate locations), verify the manifest hashes after copying, then clear the staging dir. The bundles are ciphertext: safe to carry, safe to store anywhere.
Restore (disputes, regulator requests)
Section titled “Restore (disputes, regulator requests)”python -m app.archival restore ver_01ky…Copies the verification’s blobs from the bundle back into the hot vault (put the
bundle back in ARCHIVE_DIR first if it lives on offline media). Decryption works
as normal because the wrapped keys never left the database. Restoration is audit-
logged.
Erasure
Section titled “Erasure”Two equivalent doors, both audit-logged:
python -m app.archival erase ver_01ky… # operator CLIDELETE /v1/verifications/{id}/data # API (privacy requests)Destroys the wrapped keys, deletes hot blobs, nulls identity fields. Offline bundles need no handling — their contents are now permanently undecryptable. See Privacy & retention for why this is trustworthy.
Operational invariants
Section titled “Operational invariants”- The database is the key ring. Postgres backups matter more than vault backups: blobs without wrapped keys are noise; wrapped keys without blobs are merely useless.
- Never store the master key on the same media as archive bundles — that would turn “encrypted archive” into “archive”.
- Verify a random archived verification restores + decrypts correctly once a quarter. An archive you’ve never restored from is a hope, not a backup.