Record verified Backup account activation and consumer refresh
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
parent
b6d648bfbe
commit
cb6396caab
7 changed files with 160 additions and 6 deletions
|
|
@ -30,6 +30,7 @@
|
|||
| task | RPF-WP-0027-T06 | wait | — | workplans/RPF-WP-0027-keycape-live-secret-exposure-recovery.md |
|
||||
| task | RPF-WP-0029-T01 | done | — | workplans/RPF-WP-0029-backup-credential-default-removal.md |
|
||||
| task | RPF-WP-0029-T02 | wait | — | workplans/RPF-WP-0029-backup-credential-default-removal.md |
|
||||
| task | RPF-WP-0029-T03 | done | — | workplans/RPF-WP-0029-backup-credential-default-removal.md |
|
||||
| task | RPF-WP-0035-T01 | done | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T02 | wait | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T03 | wait | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ request_type: workload-kv-read
|
|||
title: Railiance offsite backup lane (Nextcloud WebDAV + age recovery)
|
||||
status: active
|
||||
created: '2026-07-07'
|
||||
updated: '2026-07-16'
|
||||
updated: '2026-09-05'
|
||||
requester:
|
||||
agent: grok
|
||||
reason: Move railiance-backup / forgejo-backup credentials from hardcoded script
|
||||
|
|
@ -72,6 +72,12 @@ risk:
|
|||
classification: high
|
||||
notes:
|
||||
- NC_WEBDAV_TOKEN grants upload to the offsite backup file drop.
|
||||
- Since 2026-09-05 the file drop belongs to Backup, folder /railiance-backups,
|
||||
with create-only permissions and a server-enforced 10 GiB account quota.
|
||||
- Operator credentials remain in KVv2 operators/nextcloud/backup, fields
|
||||
BACKUP_USERNAME and BACKUP_PASSWORD; never deliver them to production.
|
||||
- Existing Bernd-owned retained backups and recovery access remain separate;
|
||||
historical predecessor invalidation and age-key exposure are still open.
|
||||
- "AGE_PRIVATE_KEY decrypts all age-encrypted backup artifacts \u2014 recovery escrow\
|
||||
\ only."
|
||||
- Credentials must not be stored on production hosts with delete permission.
|
||||
|
|
@ -117,6 +123,17 @@ verification:
|
|||
- 'Field presence via JSON key inventory only (NC_WEBDAV_TOKEN, NC_WEBDAV_URL, AGE_PRIVATE_KEY); lengths recorded, values not printed.'
|
||||
- 'EXPOSED taint set: custom_metadata exposed_at=2026-07-16T00:00:00Z exposed_version=2 (WP-0026 T05).'
|
||||
- 'ops-warden catalog promoted draft→active; fetch_command pinned to NC_WEBDAV_TOKEN; resolvable=true; risk=high.'
|
||||
- at: '2026-09-05'
|
||||
actor: codex
|
||||
kind: dedicated_backup_account_cutover
|
||||
result: passed
|
||||
details:
|
||||
- User authorized dedicated Backup account and operator custody coordinates.
|
||||
- Verified 10737418240-byte quota and Backup-owned create-only share.
|
||||
- Encrypted fixture PUT 201, owner download and escrow decryption passed;
|
||||
runtime GET and DELETE returned 405 on the actual upload endpoint.
|
||||
- CAS advanced workload KV version 2 to 3, preserving age escrow and other fields.
|
||||
- Evidence docs/evidence/RPF-WP-0029-backup-account-2026-09-05.json.
|
||||
|
||||
lifecycle:
|
||||
deactivate: Disable ops-warden catalog entry and detach OIDC role policy; rotate
|
||||
|
|
|
|||
|
|
@ -65,3 +65,36 @@ 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.
|
||||
|
||||
## Dedicated Backup account (2026-09-05)
|
||||
|
||||
The operator-provisioned account is `Backup` on `nx4069.your-storageshare.de`.
|
||||
Its credentials remain in OpenBao KVv2 `operators/nextcloud/backup`, fields
|
||||
`BACKUP_USERNAME` and `BACKUP_PASSWORD` (API `operators/data/nextcloud/backup`).
|
||||
The UI's `secrets/` prefix is not a separate KV mount.
|
||||
|
||||
Future uploads use the account's `/railiance-backups` folder through a dedicated
|
||||
create-only share. Only its derived `NC_WEBDAV_TOKEN` and `NC_WEBDAV_URL` enter
|
||||
the existing workload lane and activity-core ExternalSecret; the account password
|
||||
is not a production credential. Recovery download and cleanup use operator
|
||||
account authority. Preserve `AGE_PRIVATE_KEY` and all unrelated KV fields with CAS.
|
||||
|
||||
The server-reported quota is **10 GiB (10,737,418,240 bytes)**. This is a hard
|
||||
capacity limit shared by the account's files. Retention counts such as 14 daily
|
||||
and four weekly backups do not guarantee they fit. Check quota before large
|
||||
uploads; a quota rejection is a failed backup. Pruning retained backups requires
|
||||
an explicit retention decision and operator authority; upload jobs cannot delete.
|
||||
Existing Bernd-owned backups remain in their original location and require their
|
||||
existing recovery access. This cutover neither migrates them nor revokes Bernd's
|
||||
personal account or old share.
|
||||
|
||||
`scripts/migrate_nextcloud_backup_account.py` performs the attended account,
|
||||
quota, create-only share, encrypted fixture recovery and CAS checks. Run it only
|
||||
through `warden access openbao-platform-admin-login --exec -- ...`, with a fresh
|
||||
private receipt path and `--confirm 'MIGRATE TO Backup'`. The helper is silent;
|
||||
receipts contain only status and metadata. Review a failed receipt before retrying:
|
||||
a failure can leave the dedicated folder/share or an identified test fixture, and
|
||||
a cleanup failure after CAS can occur after credentials have already changed.
|
||||
Refresh `actcore-backup-offsite`, verify delivery by contained comparison, and
|
||||
restart its three environment consumers (`actcore-api`, `actcore-event-router`,
|
||||
`actcore-worker`). Record their readiness and loaded-value comparisons.
|
||||
|
|
|
|||
60
docs/evidence/RPF-WP-0029-backup-account-2026-09-05.json
Normal file
60
docs/evidence/RPF-WP-0029-backup-account-2026-09-05.json
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"date": "2026-09-05",
|
||||
"cutover": {
|
||||
"schema": "platform.nextcloud-backup-account-cutover.v1",
|
||||
"status": "account_cutover_verified_pending_consumer_refresh",
|
||||
"quota_before": {
|
||||
"quota_bytes": 10737418240,
|
||||
"used_bytes": 2506112,
|
||||
"available_bytes": 10734912128
|
||||
},
|
||||
"previous_kv_version": 2,
|
||||
"share_id": "19",
|
||||
"observed_permissions": 4,
|
||||
"owner_matches": true,
|
||||
"path_matches": true,
|
||||
"share_owner": "Backup",
|
||||
"share_permissions": 4,
|
||||
"fixture_name": "account-acceptance-ee8a5e360afd26b7dc7b9b4c.age",
|
||||
"upload_http_status": 201,
|
||||
"runtime_get_http_status": 405,
|
||||
"runtime_delete_http_status": 405,
|
||||
"encrypted_upload": true,
|
||||
"owner_download": true,
|
||||
"escrow_decryption": true,
|
||||
"runtime_read_denied": true,
|
||||
"runtime_delete_denied": true,
|
||||
"kv_version": 3,
|
||||
"escrow_preserved": true,
|
||||
"fixture_removed": true,
|
||||
"quota_after": {
|
||||
"quota_bytes": 10737418240,
|
||||
"used_bytes": 2506112,
|
||||
"available_bytes": 10734912128
|
||||
}
|
||||
},
|
||||
"consumers": {
|
||||
"status": "verified",
|
||||
"kv_version": 3,
|
||||
"eso_delivery_matches": true,
|
||||
"deployments": {
|
||||
"actcore-api": {
|
||||
"ready": true,
|
||||
"environment_matches": true
|
||||
},
|
||||
"actcore-event-router": {
|
||||
"ready": true,
|
||||
"environment_matches": true
|
||||
},
|
||||
"actcore-worker": {
|
||||
"ready": true,
|
||||
"environment_matches": true
|
||||
}
|
||||
},
|
||||
"previous_test_fixtures_removed": [
|
||||
"account-acceptance-e820d52ac48dc28766c39eef.age",
|
||||
"account-acceptance-f88f8dcc3bea4ea199aeeebd.age"
|
||||
]
|
||||
},
|
||||
"status": "verified"
|
||||
}
|
||||
|
|
@ -40,6 +40,12 @@ Decrypt: `~/.config/age/railiance-backup.key` (same key as other Railiance backu
|
|||
|
||||
## Nextcloud layout
|
||||
|
||||
Since 2026-09-05, uploads go to user `Backup`, folder `/railiance-backups`,
|
||||
through a create-only share delivered from OpenBao. The account has **10 GiB**
|
||||
total capacity; the retention target below is subject to available space.
|
||||
Operator credentials stay in `operators/nextcloud/backup`; workload jobs receive
|
||||
only the derived upload grant. See [account and recovery procedure](backup-credential-recovery.md).
|
||||
|
||||
```
|
||||
forgejo/forgejo-dump-<timestamp>.zip.age
|
||||
forgejo/forgejo-db-<timestamp>.sql.age
|
||||
|
|
|
|||
29
history/2026-09-05-nextcloud-backup-account-cutover.md
Normal file
29
history/2026-09-05-nextcloud-backup-account-cutover.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Dedicated Nextcloud Backup account activated — 2026-09-05
|
||||
|
||||
User authorized replacing Bernd's personal upload lane with the new Backup
|
||||
account. Resolved UI custody notation to KVv2 operators/nextcloud/backup
|
||||
(BACKUP_USERNAME/BACKUP_PASSWORD). Native WebDAV confirmed Backup and a
|
||||
10,737,418,240-byte account quota.
|
||||
|
||||
Created /railiance-backups and backup prefix folders, with a Backup-owned public
|
||||
share granting create only (permissions 4). Account password remains operator-only.
|
||||
An initial publicUpload option broadened the share; verification rejected it and
|
||||
removed that share before touching workload custody. Explicit permissions alone
|
||||
produced the required grant. The actual file-drop endpoint denies GET and DELETE
|
||||
with HTTP 405. Three encrypted synthetic fixtures exercised transport/recovery;
|
||||
all were removed using owner authority after verification.
|
||||
|
||||
Uploaded with HTTP 201, downloaded as owner, and decrypted with existing age
|
||||
escrow. CAS advanced the workload lane from version 2 to 3, changing only the
|
||||
upload token and URL. Forced actcore-backup-offsite refresh and compared values
|
||||
in protected memory. Restarted actcore-api, actcore-event-router and actcore-worker;
|
||||
all ready with new values loaded. No password or token appears in source/evidence.
|
||||
|
||||
10 GiB is a hard account limit, not assurance that 14 daily plus four weekly
|
||||
backups fit. No retained backup deletion or automatic pruning was performed.
|
||||
Existing Bernd-owned backups and recovery access remain where they were.
|
||||
T03 is done; T02 remains waiting for old share invalidation and a real offsite
|
||||
application restore. Upload rotation does not clear historical age-key exposure.
|
||||
|
||||
Validation: 196 repository tests passed. Live evidence is in
|
||||
`docs/evidence/RPF-WP-0029-backup-account-2026-09-05.json`.
|
||||
|
|
@ -4,7 +4,7 @@ type: workplan
|
|||
title: "Remove backup credential default and verify governed replacement"
|
||||
domain: financials
|
||||
repo: railiance-platform
|
||||
status: active
|
||||
status: blocked
|
||||
owner: codex
|
||||
created: "2026-09-05"
|
||||
updated: "2026-09-05"
|
||||
|
|
@ -44,11 +44,12 @@ state_hub_task_id: "b3f3402f-890b-5781-9b3e-1c9c0d28cea8"
|
|||
Provider-side invalidation and replacement custody need the attended provider owner and CCR-2026-0004 lifecycle procedure. Record only non-secret invalidation, encrypted upload and restore receipts. No provider authority or replacement receipt was available; source removal alone does not close the reported exposure. Never record the predecessor value, fingerprint, length, or shape.
|
||||
|
||||
Prepared owner execution procedure: `docs/backup-credential-recovery.md`.
|
||||
Awaiting the Nextcloud share owner/account and replacement custody coordinates;
|
||||
OpenBao authority is not provider share-management authority. Activity-core is
|
||||
The dedicated Backup account cutover is complete under T03. Awaiting owner
|
||||
authority for invalidating the old Bernd-owned share and a real offsite restore. Activity-core is
|
||||
also a consumer of this upload lane. Preserve AGE_PRIVATE_KEY and historical
|
||||
exposure evidence; upload-token rotation cannot clear recovery-key taint.
|
||||
No provider mutation, backup upload or restore has been run in this continuation.
|
||||
T03 proves encrypted fixture transport and decryption; full application restore
|
||||
and historical predecessor invalidation remain open.
|
||||
|
||||
## Portfolio review — 2026-09-05
|
||||
|
||||
|
|
@ -64,7 +65,7 @@ here until its evidence is accepted. No rotation was executed in this review.
|
|||
|
||||
```task
|
||||
id: RPF-WP-0029-T03
|
||||
status: progress
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "f85b1b4e-9a20-56e2-9e7d-d1d6f1c77bd9"
|
||||
```
|
||||
|
|
@ -78,3 +79,10 @@ for workload delivery, and preserve the existing age escrow and retained data.
|
|||
Prove encrypted upload/download/decryption and workload delivery. No automatic
|
||||
pruning or personal-account revocation is inferred from this account change.
|
||||
The historical predecessor invalidation obligation in T02 remains separate.
|
||||
|
||||
Completed 2026-09-05: Backup-owned share permissions 4; upload HTTP 201,
|
||||
owner download/decryption passed, runtime GET/DELETE denied with HTTP 405.
|
||||
Workload KV CAS 2→3 preserved age escrow. ExternalSecret delivery and all three
|
||||
activity-core deployments verified ready with new credentials loaded. All test
|
||||
fixtures removed. Account quota is enforced by Nextcloud; no automatic pruning.
|
||||
Evidence: `docs/evidence/RPF-WP-0029-backup-account-2026-09-05.json`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue