Contain backup upload credentials and prepare provider recovery gates
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
parent
08a406f2f8
commit
5ef016be01
6 changed files with 219 additions and 14 deletions
67
docs/backup-credential-recovery.md
Normal file
67
docs/backup-credential-recovery.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# 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.
|
||||
|
|
@ -32,6 +32,9 @@ There is no built-in credential fallback. Missing credentials stop execution
|
|||
before any cluster dump. Local encryption dry-runs skip upload authentication.
|
||||
Provider rotation and replacement upload/restore proof are tracked separately
|
||||
in `RPF-WP-0029`; removing the source default does not prove revocation.
|
||||
The concrete owner procedure is `docs/backup-credential-recovery.md`. Upload
|
||||
credentials and credential-bearing URLs are passed to curl through stdin,
|
||||
and backend errors never print those values. Redirects are refused.
|
||||
|
||||
Decrypt: `~/.config/age/railiance-backup.key` (same key as other Railiance backups).
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue