Appearance
Read the backup catalog
Every platform an operator runs raises the same two questions on a bad day: what is backed up? and in what order do I bring it back? plexsphere answers both as first-class, read-only surfaces. The backup catalogue projects the platform's documented coverage — which stores are backed up, how, how often, how long they are retained, and how urgent each is to restore. The restore plan projects the contiguous, ordered runbook an operator follows to recover the platform. Neither surface ever runs a backup or executes a restore; there is deliberately no backup run and no restore apply. They exist so the recovery posture is something you can read, not reconstruct from memory.
By the end of this lesson you will have read both surfaces as the platform operator and seen how the catalogue's restore priorities line up with the restore plan's ordered steps.
This lesson takes about five minutes.
Before you start
This lesson opens the platform track and does not build on the core, provisioning, or mesh tracks. You need a running, logged-in stack from Set up your local plexsphere, plus jq on your $PATH.
Both surfaces are platform-scoped, not Domain-scoped: they describe the platform as a whole, so they gate on the platform manage relation rather than any per-Domain grant. The seeded admin@example.com is a Domain admin and does not hold it — try the catalogue as your default identity and the platform turns you away:
bash
export PATH="$PWD/bin:$PATH"
export PLEXSPHERE_URL=http://localhost:8080
plexctl backup catalogtext
plexctl: Permission Denied: backup catalog: caller lacks platform manageThat is the boundary working as designed. The identity that does hold the platform grant is operator@example.com — the platform operator, the same identity that builds the provisioning catalog in Create a Cloud. Sign in as the operator and save the session under a named operator profile so your default session stays put. The --platform flag runs the Domain-independent platform sign-in — the operator's authority is platform-wide, so no Domain id is needed. Complete sign-in in the browser as operator@example.com with the password password:
bash
plexctl login --profile-name operator --platformWhen the browser opens, sign in as operator@example.com — not as the admin you used above. The approving browser session must itself be platform-scoped: if the browser reuses your admin (tenant) session, the approval is refused with a device-scope mismatch rather than silently minting the wrong identity. If that happens, open the verification URL in a private window (or sign out of the in-cluster Dex first) and complete it as the operator. Confirm the SCOPE column reads platform with plexctl whoami --profile operator before continuing.
Everything below runs with --profile operator.
Step 1 — Read the coverage catalogue
Ask the platform what it backs up:
bash
plexctl backup catalog --profile operatorThe full table is wide — each store carries its method, cadence, retention, restore priority, restore-sequence position, and notes. The two columns that tell the story at a glance are PRIORITY (how urgent the store is to recover) and RESTORE_STEP (its position in the linear restore sequence, 0 meaning it is not a discrete step). Project just those with jq:
bash
plexctl backup catalog --profile operator --output json \
| jq -r '.entries[] | "\(.priority) \(.restore_step) \(.store)"'text
P0 2 PostgreSQL
P0 1 OpenBao
P1 5 Management-fleet clusters
P2 0 Blueprint catalogue
P0 0 Object store
P3 8 Grafana Mimir
P0 8 Grafana Loki
P2 4 NATS JetStream
P2 0 Configuration-as-codeRead the priorities and the recovery design shows through. The P0 stores — OpenBao, PostgreSQL, the audit-bearing slices of the object store and Loki — are the ones nothing else works without. The blueprint catalogue and configuration-as-code are P2 with restore_step 0: they live in external Git and are re-applied, not restored from a plexsphere backup. Mimir is P3 — metrics are the last thing to come back, because a platform that serves writes without metrics is still operational.
Step 2 — Read the exclusions and recovery targets
The single text table cannot carry everything the catalogue knows. Two parts surface only in the structured output. The exclusions name what is deliberately not backed up, and why it is safe to skip:
bash
plexctl backup catalog --profile operator --output json | jq -r '.exclusions[] | "\(.name): \(.rationale)"'text
Plexd agent state on nodes: plexd is deterministic given plexsphere's source of truth.
Customer-side secret stores: Customer Vault / AWS Secrets Manager used for Adopted-K8s bootstrap-token delivery belong to the customer.
WireGuard keys on plexd nodes: Mesh keys are rotated on reconnect when needed rather than restored.
Bootstrap-token plaintext: Bootstrap tokens are short-TTL and one-time-use; only their hashes are persisted server-side.Each exclusion is a deliberate design statement: these things are reconstructed, rotated, or owned by someone else, so backing them up would be ceremony. The recovery targets state the RPO (how much data you may lose) and RTO (how long recovery takes) per plane:
bash
plexctl backup catalog --profile operator --output json | jq -r '.targets[] | "\(.plane): RPO \(.rpo) / RTO \(.rto)"'text
Data plane: RPO n/a — not affected by plexsphere DR / RTO n/a
Control-plane reads: RPO ≤ 5 min / RTO ≤ 15 min
Control-plane writes: RPO ≤ 5 min / RTO ≤ 30 min
Session-plane issuance: RPO Already-issued sessions continue to their JWT expiry; new issuance depends on Signing Service restore. / RTO ≤ 30 min
Observability ingest: RPO ≤ 15 min (plexd local buffering backfills short gaps) / RTO ≤ 1 h
Audit archival: RPO ≤ 1 h / RTO ≤ 4 h (regulatory reads)Step 3 — Read the ordered restore plan
The catalogue says what and how urgent. The companion restore plan surface says in what order — the contiguous, ascending runbook an operator follows:
bash
plexctl restore plan --profile operatorIn text mode each step projects onto ORDER, NAME, ACTION, and VERIFY. The ACTION and VERIFY columns are long; the spine of the plan is the ordered NAME list, which you can pull out on its own:
bash
plexctl restore plan --profile operator --output json | jq -r '.sequence[] | "\(.order) \(.name)"'text
1 OpenBao
2 PostgreSQL
3 Signing Service
4 NATS JetStream
5 Management-fleet clusters
6 SpiceDB
7 Core plexsphere binary + Signing Service replicas
8 Observability backendsNow the two surfaces click together. OpenBao restores first — its catalogue restore_step is 1, and nothing in plexsphere starts healthily without it. PostgreSQL is 2, because its rows reference OpenBao paths. The observability backends are last (step 8), matching Mimir and Loki carrying the highest restore_step in the catalogue. The catalogue's priorities and the plan's order are two views of one recovery design: read top-to-bottom, the plan is the sequence; read by priority, the catalogue is the justification.
When you are done, you can drop the operator session and keep only your default login:
bash
plexctl logout --profile operatortext
Logged out. Cleared profile "operator".What you learned
- Backup posture is a read-only surface, not a runbook in someone's head. The catalogue projects coverage and the restore plan projects the ordered recovery sequence; neither ever triggers a backup or runs a restore.
- Both surfaces are platform-scoped. They describe the whole platform, so they gate on the platform
managerelation — the operator holds it, a Domain admin does not. - Priority and order are two views of one design. The catalogue's
PRIORITYandRESTORE_STEPcolumns and the restore plan's ascendingORDERagree: OpenBao then PostgreSQL first, observability backends last. - The structured output carries more than the text table. The deliberate exclusions and the per-plane RPO/RTO targets surface only under
--output json/yaml.
Where to go next
- Keep learning by doing — Erase an identity from the audit log is the capstone: honour a right-to-erasure request against the hash-chained audit log the tracks above have filled, then prove the chain still verifies end to end.
- Done with the stack — Tear down your local plexsphere removes the cluster cleanly, or resets it so you can run any lesson again from a clean baseline.
Or pick the quadrant that matches what you need now:
- You want the exact contract — the
plexctl backupandplexctl restorereferences document every column, exit code, and output shape. - You want to understand why the recovery posture is shaped this way — the platform's backup and disaster-recovery design is documented in the project README's Backup & Disaster Recovery section, the single source the catalogue is transcribed from.