Establish railiance backup credentials in OpenBao (CCR-2026-0004).
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run

Add workload KV lane for Nextcloud WebDAV token, URL, and age recovery
escrow at platform/workloads/railiance/backup/offsite-lane. Apply read
policy and OIDC role railiance-backup-workload-kv-read; wire forgejo-backup
to load credentials from OpenBao when env is unset.
This commit is contained in:
tegwick 2026-07-07 17:16:30 +02:00
parent f428940da8
commit 0055e8f3f7
8 changed files with 430 additions and 1 deletions

61
docs/forgejo-backup.md Normal file
View file

@ -0,0 +1,61 @@
# Forgejo backup (railiance01)
Workplan: `RAIL-HO-WP-0005` T04/T09 · Decision: Option A (Nextcloud + age)
## What is backed up
| Artifact | Source | Format |
| --- | --- | --- |
| Blob state | `forgejo dump` in production pod | zip → age |
| PostgreSQL | `pg_dump -Fc` from CNPG `forgejo-db` | custom dump → age |
Covers git repos, packages (OCI/npm/generic), attachments, LFS, avatars, and DB metadata.
## Operator commands
```bash
cd ~/railiance-platform
make forgejo-backup-dry-run # local encrypt only, no upload
make forgejo-backup # encrypt + upload to Nextcloud forgejo/
make forgejo-backup-status # last success + 7-day gate hint
```
Requires: `kubectl`, `age`, `curl`, `KUBECONFIG=~/.kube/config-hosteurope`.
Decrypt: `~/.config/age/railiance-backup.key` (same key as other Railiance backups).
## Nextcloud layout
```
forgejo/forgejo-dump-<timestamp>.zip.age
forgejo/forgejo-db-<timestamp>.sql.age
forgejo/forgejo-dump-weekly-<timestamp>.zip.age # Sundays only
forgejo/forgejo-db-weekly-<timestamp>.sql.age
```
Retention target: **14 daily + 4 weekly** on Nextcloud (operator may prune old
objects in the WebDAV folder; local cache keeps 7 per type).
## Cron (workstation)
```cron
# Daily 02:15 UTC — Forgejo backup (RPO 24h)
15 2 * * * cd $HOME/railiance-platform && make forgejo-backup >>$HOME/.cache/railiance/backups/forgejo/cron.log 2>&1
```
## Promotion gate (tier-3 cutover)
Do not promote further production repos until:
1. `make forgejo-backup` succeeds **7 consecutive days** (check `success-log`).
2. One restore drill uses a Nextcloud artifact (not `/tmp/forgejo-drill/`).
## Restore
See `railiance-infra`:
- `tools/forgejo-restore-drill.sh`
- `docs/forgejo-restore-drill-evidence.md`
Download and decrypt a dump from Nextcloud, set `BACKUP_LOCAL` to the zip path,
then run the drill script.

View file

@ -228,3 +228,44 @@ runbook: docs/workload-kv-access-lanes.md
Until positive and negative caller verification are complete, ops-warden should
keep the catalog entry in `applied-pending-verify`/non-active state with
`resolvable=false`.
## Railiance offsite backup lane (`CCR-2026-0004`)
Workstation and platform backup tools (`railiance-backup`, `forgejo-backup`) upload
age-encrypted artifacts to the Nextcloud file drop (Option A, 2026-07-09).
| Item | Value |
| --- | --- |
| CCR | `CCR-2026-0004-railiance-backup-offsite-lane` |
| KV mount | `platform` |
| OpenBao CLI path | `platform/workloads/railiance/backup/offsite-lane` |
| Fields | `NC_WEBDAV_TOKEN`, `NC_WEBDAV_URL`, `AGE_PRIVATE_KEY` |
| Read policy | `workload-kv-read-railiance-backup-offsite-lane` |
| Policy file | `openbao/policies/workload-kv-read-railiance-backup-offsite-lane.hcl` |
| OIDC auth mount | `netkingdom` |
| OIDC role | `railiance-backup-workload-kv-read` |
| Bound claim | `groups=net-kingdom-admins` (confirmed via live `platform-admin` role) |
| ops-warden catalog id | `railiance-backup-offsite-lane` (draft until front door verified) |
Caller login:
```bash
bao login -method=oidc -path=netkingdom role=railiance-backup-workload-kv-read
```
Fetch upload token for a backup run (do not log the value):
```bash
export RAILIANCE_BACKUP_NC_TOKEN=$(
bao kv get -field=NC_WEBDAV_TOKEN platform/workloads/railiance/backup/offsite-lane
)
export RAILIANCE_BACKUP_NC_WEBDAV_URL=$(
bao kv get -field=NC_WEBDAV_URL platform/workloads/railiance/backup/offsite-lane
)
```
Or let `lib/railiance-backup-common.sh` load from OpenBao after login when env is unset.
Recovery escrow (`AGE_PRIVATE_KEY`) is stored in the same path for disaster
recovery; prefer the password-manager copy on restore drills per
`railiance-cluster/docs/backup-restore.md`. Fetch only in attended sessions.