Complete DISCTL-WP-0003-T01: seed asset and data registers
Add AssetRegister.yaml and DataRegister.yaml documenting the railiance-backup tool family, backup lanes, data classes, gaps, and RTO/RPO targets. Mark T01 done.
This commit is contained in:
parent
57161a1b02
commit
9649ae3490
3 changed files with 449 additions and 1 deletions
239
AssetRegister.yaml
Normal file
239
AssetRegister.yaml
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
# Resilience Control Plane — asset register (initial seed)
|
||||
# DISCTL-WP-0003-T01 — railiance-backup tool family and backup lanes
|
||||
# Broader T0/T4 inventory (domains, Stripe, Bubble, etc.) follows in DISCTL-WP-0002-T02.
|
||||
|
||||
schema_version: "0.1"
|
||||
updated: "2026-07-07"
|
||||
register_scope: backup_lanes
|
||||
|
||||
tier_definitions:
|
||||
T0: "Identity / trust / money — recoverable even after breach"
|
||||
T1: "Irreplaceable source of truth — strong backups, tested restore"
|
||||
T2: "Runtime platforms — rebuild from IaC + restore data"
|
||||
T3: "Derived / rebuildable — recompute where possible"
|
||||
T4: "External dependencies — export, monitor, document limits"
|
||||
|
||||
backup_streams:
|
||||
- id: backup-dev-workstation
|
||||
name: Dev workstation custodian state
|
||||
tool: railiance-backup
|
||||
tool_path: railiance-cluster/tools/cmd/railiance-backup
|
||||
owner_repo: railiance-cluster
|
||||
operator: Bernd
|
||||
tier: T1
|
||||
host: bnt-lap001
|
||||
backup_mechanism: >-
|
||||
pg_dump from Docker container infra-postgres-1 (custodian DB);
|
||||
tar of ~/.claude, ~/.claude.json, ~/.gitconfig; age encrypt; upload via curl PUT
|
||||
destination:
|
||||
primary: Nextcloud WebDAV file drop (off-node)
|
||||
local_cache: ~/.cache/railiance/backups/
|
||||
backup_schedule: "daily 02:00 UTC (cron)"
|
||||
retention: "7 local copies per artifact type"
|
||||
encryption: age
|
||||
recovery_method: >-
|
||||
Download artifacts from Nextcloud; age -d with ~/.config/age/railiance-backup.key;
|
||||
restore PostgreSQL volume; unpack config tar. See railiance-cluster/docs/backup-restore.md
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
status: operational
|
||||
gaps: []
|
||||
evidence:
|
||||
restore_tested: false
|
||||
last_drill: null
|
||||
references:
|
||||
- railiance-cluster/docs/backup-restore.md
|
||||
- railiance-cluster/tools/cmd/railiance-backup
|
||||
|
||||
- id: backup-s1-os-config
|
||||
name: S1 OS and provisioning config
|
||||
tool: railiance-backup-s1
|
||||
tool_path: railiance-infra/tools/cmd/railiance-backup-s1
|
||||
owner_repo: railiance-infra
|
||||
operator: Bernd
|
||||
tier: T2
|
||||
host: railiance01
|
||||
backup_mechanism: >-
|
||||
Tar of Ansible-managed OS files (sshd, ufw, fail2ban, hosts, hostname,
|
||||
apt sources) plus dpkg --get-selections; age encrypt
|
||||
destination:
|
||||
primary: /opt/backup/railiance/infra/ (on-node local only)
|
||||
offsite: none
|
||||
backup_schedule: manual (make backup in railiance-infra)
|
||||
retention: "7 local copies per artifact type"
|
||||
encryption: age (SOPS key pair)
|
||||
recovery_method: >-
|
||||
age -d with ~/.config/sops/age/keys.txt; restore files to /etc/ or re-apply
|
||||
via Ansible playbooks
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
status: operational
|
||||
gaps:
|
||||
- "No scheduled automation — manual make backup only"
|
||||
- "No off-cluster upload — lost if host is destroyed"
|
||||
evidence:
|
||||
restore_tested: false
|
||||
last_drill: null
|
||||
references:
|
||||
- railiance-infra/tools/cmd/railiance-backup-s1
|
||||
|
||||
- id: backup-s2-k8s-runtime
|
||||
name: S2 Kubernetes runtime state
|
||||
tool: railiance-backup-s2
|
||||
tool_path: railiance-cluster/tools/cmd/railiance-backup-s2
|
||||
owner_repo: railiance-cluster
|
||||
operator: Bernd
|
||||
tier: T1
|
||||
host: railiance01
|
||||
backup_mechanism: >-
|
||||
sqlite3 hot backup of k3s state.db; tar of Helm release values (all namespaces);
|
||||
kubeconfig copy; age encrypt
|
||||
destination:
|
||||
primary: /opt/backup/railiance/cluster/ (on-node local only)
|
||||
offsite: none
|
||||
backup_schedule: manual (make backup in railiance-cluster)
|
||||
retention: "7 local copies per artifact type"
|
||||
encryption: age (SOPS key pair)
|
||||
recovery_method: >-
|
||||
age -d; restore k3s state.db or redeploy from Helm values + kubeconfig.
|
||||
Prefer rebuild-from-manifests where possible.
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
status: operational
|
||||
gaps:
|
||||
- "No scheduled automation — manual make backup only"
|
||||
- "No off-cluster upload — lost if host is destroyed"
|
||||
evidence:
|
||||
restore_tested: false
|
||||
last_drill: null
|
||||
references:
|
||||
- railiance-cluster/tools/cmd/railiance-backup-s2
|
||||
- history/2026-07-04-forgejo-backup-strategy-assessment.md
|
||||
|
||||
- id: backup-s3-platform
|
||||
name: S3 platform services (PostgreSQL, Valkey)
|
||||
tool: railiance-backup
|
||||
tool_path: railiance-platform/tools/cmd/railiance-backup
|
||||
owner_repo: railiance-platform
|
||||
operator: Bernd
|
||||
tier: T1
|
||||
host: railiance01
|
||||
backup_mechanism: >-
|
||||
Intended pg_dump of platform PostgreSQL HA and Valkey state; age encrypt;
|
||||
upload to Nextcloud WebDAV (same lane as dev workstation pattern)
|
||||
destination:
|
||||
primary: Nextcloud WebDAV file drop (intended, off-node)
|
||||
local_cache: TBD
|
||||
backup_schedule: TBD
|
||||
retention: "14 daily + 4 weekly rotations (adopted 2026-07-09 for Forgejo lane)"
|
||||
encryption: age
|
||||
recovery_method: >-
|
||||
Not operational — tool absent. Makefile target exists but
|
||||
tools/cmd/railiance-backup was never relocated from railiance-cluster
|
||||
(RAIL-PL-WP-0001-T05 cancelled).
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
status: missing
|
||||
gaps:
|
||||
- "tools/cmd/railiance-backup absent from railiance-platform"
|
||||
- "make backup target references missing implementation"
|
||||
- "Relocation from railiance-cluster planned but never completed"
|
||||
evidence:
|
||||
restore_tested: false
|
||||
last_drill: null
|
||||
references:
|
||||
- railiance-platform/Makefile
|
||||
- railiance-platform/docs/postgresql-ha.md
|
||||
- history/2026-07-04-forgejo-backup-strategy-assessment.md
|
||||
|
||||
- id: backup-forgejo-production
|
||||
name: Forgejo production (git, packages, DB)
|
||||
tool: forgejo dump + CNPG pg_dump
|
||||
tool_path: null
|
||||
owner_repo: railiance-platform
|
||||
operator: Bernd
|
||||
tier: T1
|
||||
host: railiance01
|
||||
backup_mechanism: >-
|
||||
Daily forgejo dump zip (repos, packages OCI/npm/generic, attachments, LFS,
|
||||
avatars) plus daily pg_dump from CNPG forgejo-db; age encrypt; Nextcloud upload
|
||||
destination:
|
||||
primary: Nextcloud WebDAV file drop (decided 2026-07-09, not wired)
|
||||
drill_archive: workstation /tmp only (T09 drill)
|
||||
backup_schedule: daily (intended — not implemented)
|
||||
retention: "14 daily + 4 weekly rotations"
|
||||
encryption: age (platform backup public key)
|
||||
recovery_method: >-
|
||||
forgejo-restore-drill.sh — unzip dump, copy files, psql import, isolated Helm
|
||||
deploy. Proven 2026-07-04 (RAIL-HO-WP-0005-T09); not yet from automated backup.
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
status: not_wired
|
||||
gaps:
|
||||
- "No scheduled forgejo dump CronJob"
|
||||
- "No CNPG ScheduledBackup CR on forgejo-db"
|
||||
- "No automated upload to Nextcloud — decision #7 adopted but not implemented"
|
||||
- "Promotion gate: 7 consecutive daily successes + restore from Nextcloud artifact"
|
||||
evidence:
|
||||
restore_tested: true
|
||||
last_drill: "2026-07-04"
|
||||
evidence_ref: railiance-infra/docs/forgejo-restore-drill-evidence.md
|
||||
references:
|
||||
- the-custodian/docs/forgejo-production-decisions.md
|
||||
- railiance-infra/tools/forgejo-restore-drill.sh
|
||||
- history/2026-07-04-forgejo-backup-strategy-assessment.md
|
||||
|
||||
- id: backup-gitea-canonical
|
||||
name: Gitea canonical source forge (pre-cutover)
|
||||
tool: gitea dump / git mirror
|
||||
tool_path: null
|
||||
owner_repo: railiance-infra
|
||||
operator: Bernd
|
||||
tier: T1
|
||||
host: coulombcore
|
||||
backup_mechanism: >-
|
||||
Manual gitea dump before migration waves; git mirror to offsite provider (intended).
|
||||
Bundled PostgreSQL + gitea-shared-storage PVC; no automated CronJob evidenced.
|
||||
destination:
|
||||
primary: none automated
|
||||
mirror: TBD (GitHub private mirror or secondary host)
|
||||
backup_schedule: pre-cutover manual only
|
||||
retention: point-in-time of last manual dump
|
||||
encryption: not standardized
|
||||
recovery_method: gitea dump restore per Gitea docs; safety contract requires fresh
|
||||
dump before each Forgejo migration wave
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
status: at_risk
|
||||
gaps:
|
||||
- "No automated Gitea backup CronJob on coulombcore"
|
||||
- "Package blob backup not evidenced"
|
||||
- "disaster-control itself not yet mirrored off primary Gitea (DISCTL-WP-0002-T01)"
|
||||
evidence:
|
||||
restore_tested: false
|
||||
last_drill: null
|
||||
references:
|
||||
- history/2026-07-04-forgejo-backup-strategy-assessment.md
|
||||
- specs/ResilienceControlSetup.md
|
||||
|
||||
related_streams:
|
||||
# Operational on cluster but outside T01 minimum table — tracked for completeness.
|
||||
- id: backup-adjacent-sso
|
||||
name: Adjacent SSO/MFA stack
|
||||
tools:
|
||||
- privacyidea-backup
|
||||
- authelia-backup
|
||||
- lldap-backup
|
||||
owner_repo: railiance-platform
|
||||
tier: T2
|
||||
host: railiance01
|
||||
backup_schedule: daily CronJobs on railiance01
|
||||
status: operational
|
||||
note: "Only scheduled backup CronJobs found on cluster as of 2026-07-04 assessment"
|
||||
|
||||
- id: backup-apps-pg
|
||||
name: apps-pg shared CloudNativePG cluster
|
||||
owner_repo: railiance-platform
|
||||
tier: T1
|
||||
status: not_wired
|
||||
note: "Documented follow-up in railiance-platform/docs/apps-pg.md; no ScheduledBackup CR"
|
||||
209
DataRegister.yaml
Normal file
209
DataRegister.yaml
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
# Resilience Control Plane — data register (initial seed)
|
||||
# DISCTL-WP-0003-T01 — data classes covered by railiance-backup lanes
|
||||
# Full data inventory (Bubble, Stripe exports, member data, etc.) follows in DISCTL-WP-0002-T02.
|
||||
|
||||
schema_version: "0.1"
|
||||
updated: "2026-07-07"
|
||||
register_scope: backup_lane_data_classes
|
||||
|
||||
data_classes:
|
||||
- id: data-custodian-state-hub
|
||||
name: Custodian State Hub database
|
||||
tier: T1
|
||||
source_of_truth: Docker volume infra_pg_data (container infra-postgres-1)
|
||||
description: >-
|
||||
Workstreams, tasks, decisions, progress history, messages — operational
|
||||
memory of the custodian control plane
|
||||
backup_stream: backup-dev-workstation
|
||||
backup: pg_dump via railiance-backup
|
||||
recovery_method: Restore PostgreSQL from age-decrypted dump
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
|
||||
- id: data-operator-dev-config
|
||||
name: Operator development environment config
|
||||
tier: T1
|
||||
source_of_truth: ~/.claude/, ~/.claude.json, ~/.gitconfig on bnt-lap001
|
||||
description: >-
|
||||
Claude project memory, MCP registration, agent settings, git identity —
|
||||
not in git repos; loss slows all agent sessions
|
||||
backup_stream: backup-dev-workstation
|
||||
backup: config tar via railiance-backup
|
||||
recovery_method: Unpack age-decrypted tar to $HOME
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
|
||||
- id: data-s1-os-config
|
||||
name: S1 OS and firewall configuration state
|
||||
tier: T2
|
||||
source_of_truth: Live /etc/ on railiance01 (Ansible-managed, may drift)
|
||||
description: sshd, ufw, fail2ban, hosts, hostname, installed package selections
|
||||
backup_stream: backup-s1-os-config
|
||||
backup: os-config tar + packages list via railiance-backup-s1
|
||||
recovery_method: Restore files or re-apply Ansible; package list aids apt reconciliation
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
gaps:
|
||||
- "On-node only — no off-cluster copy"
|
||||
|
||||
- id: data-k3s-cluster-state
|
||||
name: k3s cluster control plane state
|
||||
tier: T1
|
||||
source_of_truth: /var/lib/rancher/k3s/server/db/state.db (SQLite mode)
|
||||
description: >-
|
||||
Kubernetes object state for single-node k3s — deployments, services,
|
||||
secrets metadata, CRDs
|
||||
backup_stream: backup-s2-k8s-runtime
|
||||
backup: sqlite3 hot backup via railiance-backup-s2
|
||||
recovery_method: Restore state.db or rebuild cluster from Helm values
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
gaps:
|
||||
- "On-node only — no off-cluster copy"
|
||||
- "PV/PVC data not included — application data needs separate streams"
|
||||
|
||||
- id: data-helm-release-values
|
||||
name: Helm release configuration
|
||||
tier: T2
|
||||
source_of_truth: Live Helm releases on k3s
|
||||
description: Per-release values.yaml for all namespaces — redeploy baseline
|
||||
backup_stream: backup-s2-k8s-runtime
|
||||
backup: helm get values export via railiance-backup-s2
|
||||
recovery_method: helm upgrade --install from decrypted values files
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
gaps:
|
||||
- "On-node only — no off-cluster copy"
|
||||
|
||||
- id: data-kubeconfig
|
||||
name: Cluster admin kubeconfig
|
||||
tier: T0
|
||||
source_of_truth: /etc/rancher/k3s/k3s.yaml
|
||||
description: Cluster admin credentials — trust boundary asset
|
||||
backup_stream: backup-s2-k8s-runtime
|
||||
backup: file copy via railiance-backup-s2
|
||||
recovery_method: Restore to /etc/rancher/k3s/ or regenerate from k3s
|
||||
rpo: 24h
|
||||
rto: 2h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
gaps:
|
||||
- "On-node only — no off-cluster copy"
|
||||
|
||||
- id: data-platform-postgresql
|
||||
name: Platform PostgreSQL HA databases
|
||||
tier: T1
|
||||
source_of_truth: railiance-platform PostgreSQL HA cluster
|
||||
description: >-
|
||||
Legacy platform relational data including services not yet on CNPG —
|
||||
intended target of S3 railiance-backup
|
||||
backup_stream: backup-s3-platform
|
||||
backup: none
|
||||
recovery_method: Not operational — awaiting railiance-backup tool restoration
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
owner: Bernd
|
||||
status: missing
|
||||
gaps:
|
||||
- "railiance-platform/tools/cmd/railiance-backup absent"
|
||||
|
||||
- id: data-forgejo-git-repos
|
||||
name: Forgejo git repositories and metadata
|
||||
tier: T1
|
||||
source_of_truth: Forgejo application PVC + forgejo-db PostgreSQL
|
||||
description: >-
|
||||
All git repos, org structure, issues, PRs, webhooks — canonical forge
|
||||
post-cutover
|
||||
backup_stream: backup-forgejo-production
|
||||
backup: manual forgejo dump only (automated not wired)
|
||||
recovery_method: forgejo-restore-drill.sh path — proven 2026-07-04
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
owner: Bernd
|
||||
status: manual_only
|
||||
gaps:
|
||||
- "No scheduled backup job"
|
||||
- "RPO today is point-in-time of last manual dump"
|
||||
|
||||
- id: data-forgejo-packages
|
||||
name: Forgejo OCI/npm/generic packages
|
||||
tier: T1
|
||||
source_of_truth: Forgejo package storage on application PVC
|
||||
description: Container images, npm packages, generic artifacts published to forgejo.coulomb.social
|
||||
backup_stream: backup-forgejo-production
|
||||
backup: included in forgejo dump (when run); not scheduled
|
||||
recovery_method: Restored as part of forgejo dump restore
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
owner: Bernd
|
||||
status: manual_only
|
||||
|
||||
- id: data-forgejo-db
|
||||
name: forgejo-db CNPG database
|
||||
tier: T1
|
||||
source_of_truth: CloudNativePG cluster forgejo-db (databases namespace)
|
||||
description: Forgejo relational metadata — users, repos index, package registry DB
|
||||
backup_stream: backup-forgejo-production
|
||||
backup: none automated (intended daily pg_dump per 2026-07-09 decision)
|
||||
recovery_method: psql import from dump (proven in T09 drill)
|
||||
rpo: 24h
|
||||
rto: 4h
|
||||
owner: Bernd
|
||||
status: not_wired
|
||||
gaps:
|
||||
- "No CNPG ScheduledBackup CR"
|
||||
- "Split-brain risk: DB-only restore misses git blobs on app PVC"
|
||||
|
||||
- id: data-gitea-repos
|
||||
name: Gitea repositories and instance data
|
||||
tier: T1
|
||||
source_of_truth: coulombcore Gitea instance (bundled PG + gitea-shared-storage PVC)
|
||||
description: >-
|
||||
Canonical source forge until Forgejo cutover — all coulomb/* repos including
|
||||
disaster-control
|
||||
backup_stream: backup-gitea-canonical
|
||||
backup: none automated
|
||||
recovery_method: gitea dump restore; manual dump required before migration waves
|
||||
rpo: 24h
|
||||
rto: 4-8h
|
||||
owner: Bernd
|
||||
status: at_risk
|
||||
gaps:
|
||||
- "No automated backup"
|
||||
- "Package blob backup not evidenced"
|
||||
|
||||
- id: data-age-backup-keys
|
||||
name: age encryption keys for backup artifacts
|
||||
tier: T0
|
||||
source_of_truth: >-
|
||||
Operational ~/.config/age/railiance-backup.key (dev lane);
|
||||
~/.config/sops/age/keys.txt (S1/S2 lane)
|
||||
description: >-
|
||||
Private keys required to decrypt all age-encrypted backups — loss makes
|
||||
backups undecryptable
|
||||
backup_stream: null
|
||||
backup: password manager recovery copy (required); not in backup streams
|
||||
recovery_method: Retrieve from password manager; regenerate only with key rotation plan
|
||||
rpo: immediate
|
||||
rto: 2h
|
||||
owner: Bernd
|
||||
status: operational
|
||||
gaps:
|
||||
- "Not inventoried in AssetRegister T0 section yet — DISCTL-WP-0002-T02 follow-up"
|
||||
|
||||
status_legend:
|
||||
operational: "Backup mechanism exists and has run successfully"
|
||||
manual_only: "Restore path exists but backup is operator-triggered only"
|
||||
not_wired: "Decision or design exists; automation not implemented"
|
||||
missing: "No working backup mechanism"
|
||||
at_risk: "Known gap with high exposure; no reliable recovery point"
|
||||
|
|
@ -40,7 +40,7 @@ in `railiance-platform`, `railiance-apps`, and `railiance-infra`.
|
|||
|
||||
```task
|
||||
id: DISCTL-WP-0003-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "da37bcf1-2d7c-4f6b-88c4-08c0bad91151"
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue