disaster-control/RTO-RPO-Matrix.md

96 lines
5.2 KiB
Markdown
Raw Permalink Normal View History

# RTO / RPO Matrix
**Updated:** 2026-07-07
**Owner:** Bernd
**Scope:** Backup lanes — initial seed (DISCTL-WP-0003-T03)
**Related:** `AssetRegister.yaml` · `BackupPolicy.md` · `DataRegister.yaml`
Recovery Time Objective (RTO): maximum acceptable downtime.
Recovery Point Objective (RPO): maximum acceptable data loss (time since last good backup).
**Status legend:**
| Status | Meaning |
| --- | --- |
| `adopted` | Operator-confirmed target; policy applies |
| `draft` | Proposed from assessment; pending operator confirmation |
| `degraded` | Target adopted but current posture cannot meet it |
Global baseline (from `specs/ResilienceControlSetup.md` §3): **RPO ≤ 24h everywhere**;
**RTO ≤ 1 day** for full recovery; **RTO ≤ 48h** for code/content/control plane.
---
## Backup lane targets
| System | Register ID | RPO target | RTO target | Status | Evidence basis | Current posture |
| --- | --- | --- | --- | --- | --- | --- |
| Forgejo git + packages | `backup-forgejo-production` | 24h | 4h | **adopted** | Decision #7; drills 2026-07-04/07 | **operational** — daily cron; promotion gate (Nextcloud restore) open |
| `forgejo-db` CNPG | `backup-forgejo-production` | 24h (Phase 1 logical dump) | 4h | **adopted** | Decision #7; forgejo-backup pg_dump | **operational** — daily cron; promotion gate open |
| Gitea (canonical until cutover) | `backup-gitea-canonical` | 24h | 48h | draft | Assessment §suggested targets | **degraded** — no automated backup |
| k3s cluster state (S2) | `backup-s2-k8s-runtime` | 24h | 48h | draft | `railiance-backup-s2` local retention | Manual backup; on-node only |
| S1 OS config | `backup-s1-os-config` | 24h | 48h | draft | Manual `make backup`; no schedule | Manual backup; on-node only |
| Dev workstation custodian DB | `backup-dev-workstation` | 24h | 4h | draft | Daily cron 02:00; preflight gate | Operational — meets target if cron healthy |
| Dev workstation operator config | `backup-dev-workstation` | 24h | 4h | draft | Daily cron 02:00; preflight gate | Operational — meets target if cron healthy |
| S3 platform PostgreSQL | `backup-s3-platform` | 24h | 4h | **adopted** | Decision #7 (extends platform lane) | **degraded** — tool missing |
| `apps-pg` CNPG | `backup-apps-pg` | 24h | 48h | draft | `railiance-platform/docs/apps-pg.md` | **degraded** — no ScheduledBackup CR |
| Adjacent SSO/MFA stack | `backup-adjacent-sso` | 24h | 48h | draft | Daily CronJobs on railiance01 | Operational — scheduled daily |
---
## Measured results (restore drills)
| Date | System | RPO achieved | RTO achieved | Result | Evidence |
| --- | --- | --- | --- | --- | --- |
| 2026-07-04 | Forgejo (isolated restore, manual dump) | Point-in-time of manual `forgejo dump` | ~35 min (isolated namespace) | success | `TestEvidence/restore-drill-2026-07-04-forgejo.md` |
| 2026-07-07 | Forgejo (automated backup decrypt) | ~47 min (backup 18:08Z, drill 18:55Z) | 7 sec (decrypt + validate) | success | `TestEvidence/restore-drill-2026-07-07-forgejo-automated.md` |
Next drills: S2 k8s decrypt, dev workstation cold restore, Gitea dump (see `TestEvidence/README.md`). Next drills should produce
dated files under `TestEvidence/` (DISCTL-WP-0003-T05).
---
## Adopted vs operational gap
Systems marked **adopted** with **degraded** posture are policy violations until
the promotion gate in `BackupPolicy.md` §7 is met:
1. Automated daily backups succeed for 7 consecutive days.
2. One restore drill uses a Nextcloud artifact (not workstation `/tmp`).
| System | Adopted RPO/RTO | Blocker to operational |
| --- | --- | --- |
| Forgejo git + packages | 24h / 4h | Promotion gate: 7-day success + restore from Nextcloud artifact |
| `forgejo-db` CNPG | 24h / 4h | Promotion gate (daily pg_dump via forgejo-backup is wired) |
| S3 platform PostgreSQL | 24h / 4h | `railiance-backup` tool absent for non-Forgejo platform DBs |
---
## Draft targets pending operator confirmation
The following rows use assessment-suggested values. Confirm or adjust:
| System | Proposed RPO | Proposed RTO | Question for operator |
| --- | --- | --- | --- |
| Gitea canonical | 24h | 48h | Accept 24h RPO until cutover, or require mirror + hourly? |
| k3s cluster state (S2) | 24h | 48h | Accept manual-only S2 backup, or require daily cron + offsite? |
| S1 OS config | 24h | 48h | Accept manual-only, or require scheduled + offsite? |
| Dev workstation | 24h | 4h | Confirm daily cron meets RPO; any need for sub-daily? |
| `apps-pg` | 24h | 48h | Confirm before app production-trust gates |
| Adjacent SSO | 24h | 48h | Confirm daily CronJob retention and restore path |
---
## Cross-references
| Artifact | Link |
| --- | --- |
| Stream inventory | `AssetRegister.yaml``backup_streams` |
| Data classes | `DataRegister.yaml``data_classes` |
| Backup mechanisms | `BackupPolicy.md` §6§7 |
| Forgejo adoption | `the-custodian/docs/forgejo-production-decisions.md` |
| Gap assessment | `history/2026-07-04-forgejo-backup-strategy-assessment.md` |
**Follow-up:** `ResiliencePolicy.md` (operating principle, drill cadence) remains
in `DISCTL-WP-0002-T03`. Broader non-backup systems (Bubble, Stripe, DNS) will
be added when `DISCTL-WP-0002-T02` expands the registers.