Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
3.9 KiB
WP-0029 provider recovery procedure
Scope: invalidate the exposed Nextcloud upload predecessor and prove replacement encrypted upload and offsite recovery under CCR-2026-0004. The route is a Nextcloud file-drop share, not a platform-admin OpenBao credential. OpenBao administration does not confer Nextcloud share-owner authority.
Required owner inputs
- Nextcloud share owner/account and the reviewed share-management session.
- A replacement file-drop share/token delivered through protected custody; never chat, argv, Git or State Hub. Record only custody coordinates.
- Owner-authorized retrieval access for the encrypted offsite artifact. Do not assume an upload-only file-drop token can list or download backups.
- A protected reference to the predecessor for a bounded rejection probe, or accepted provider-side revocation evidence. Do not reconstruct it into logs.
Execution order
- Confirm current OpenBao KV version and preserve every existing field. The
lane contains
AGE_PRIVATE_KEY; replacing only upload fields must use CAS and preserve recovery escrow. Never use a partialkv putthat drops it. - Confirm the exact Nextcloud share and all backup consumers. Besides the
workstation helpers, activity-core consumes
NC_WEBDAV_TOKENandNC_WEBDAV_URLthrough ExternalSecretactcore-backup-offsite. Coordinate its next invocation so process-cached credentials cannot produce a false replacement-success claim. - Create the replacement under provider authority. Verify its permissions match the file-drop lane; no production delete/admin authority is needed. Seed both upload fields through contained OpenBao CAS and verify delivery with boolean comparisons. Keep provider secrets out of evidence.
- Upload a uniquely named age-encrypted artifact with the replacement. Require HTTP 200/201/204; redirects and network errors are not success. Record only artifact identity and safe status. A synthetic fixture can prove transport, but it does not establish Forgejo application recovery.
- Invalidate the predecessor at the provider. Verify rejection with the old credential in protected memory against the same bounded operation. A 401/403 or accepted provider invalidation receipt is evidence; a timeout is not. Preserve existing retained backup objects and access to their encryption key.
- Retrieve the newly uploaded encrypted artifact through the separate owner recovery path, decrypt in a protected temporary directory, and verify its expected content. For Forgejo restore acceptance, use a fetched real backup and the owning isolated restore procedure with repository/blob/database checks. Require the local fetched artifact to exist before invoking the historical infra drill: that script otherwise creates a fresh production dump, which cannot prove offsite recovery.
- Record provider invalidation, replacement KV version, upload/download, decryption, isolated restore and cleanup receipts. Mark T02 done only after the agreed recovery checks pass. No receipt may contain the predecessor's value, fingerprint, length or shape.
Recovery-key exposure remains separate
CCR-2026-0004 records historical exposure of the age recovery key as well as upload credentials. Upload-share rotation alone must not clear that taint. Retain old age recovery material until all retained artifacts are accounted for and any owner-approved re-encryption is complete. Do not silently rotate or discard the age key as part of this upload-token repair.
Prepared transport
lib/railiance-backup-common.sh passes curl credentials and credential-bearing
URLs via stdin configuration, disables curlrc, suppresses backend diagnostics,
requires HTTPS and rejects non-success responses. The Python backend streams
the artifact, refuses redirects and suppresses credential-bearing exception
text. These source changes are preparation; no provider rotation, upload or
restore is claimed by their tests.