Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
67 lines
3.9 KiB
Markdown
67 lines
3.9 KiB
Markdown
# 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
|
|
|
|
1. 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 partial `kv put` that drops it.
|
|
2. Confirm the exact Nextcloud share and all backup consumers. Besides the
|
|
workstation helpers, activity-core consumes `NC_WEBDAV_TOKEN` and
|
|
`NC_WEBDAV_URL` through ExternalSecret `actcore-backup-offsite`. Coordinate
|
|
its next invocation so process-cached credentials cannot produce a false
|
|
replacement-success claim.
|
|
3. 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.
|
|
4. 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.
|
|
5. 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.
|
|
6. 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.
|
|
7. 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.
|