Backup and restore
What an MSSP backs up, how often, and how to restore. SocTalk holds three layers of state; each has its own backup and restore path.
This page expands on Daily Operations, Database restore, which is the same procedure documented at runbook level. Use this page to plan the strategy; use ops for the keystrokes.
What to back up
1. Postgres (the control plane)
soctalk-system-postgres-0 holds:
- Tenant rows + lifecycle events
- Users, sessions, roles
- Investigations, cases, runs, proposals
- Settings (LLM, integrations, branding)
- Append-only
audit_logand event-sourcedcase_events - Outbox rows pending executor consumption
Loss tolerance: zero. A lost Postgres = lost audit history, no recoverable investigations.
2. Kubernetes Secrets in soctalk-system
| Secret (chart-rendered name) | What's in it |
|---|---|
soctalk-system-llm-api-key | LLM provider API key (install-wide default) |
soctalk-system-bootstrap-admin | Initial admin email + password (if install.bootstrapAdmin.password set in values) |
soctalk-system-jwt-signing-key | Session token signing key |
soctalk-system-adapter-signing-key | Adapter-token signing key |
soctalk-system-postgres-admin-creds | Postgres soctalk_admin (migrations) creds |
soctalk-system-postgres-app-creds | Postgres soctalk_app (runtime) creds |
soctalk-system-postgres-mssp-creds | Postgres soctalk_mssp (cross-tenant queries) creds |
soctalk-slack-creds | Slack tokens (env-provided; not chart-rendered) |
soctalk-thehive-creds | TheHive API key (env-provided) |
soctalk-cortex-creds | Cortex API key (env-provided) |
A regenerated set of Secrets is recoverable, but in-flight sessions break and integration creds need re-pasting.
3. Per-tenant PVCs
For each tenant-<slug> namespace:
| PVC | What's in it |
|---|---|
wazuh-indexer-data | All Wazuh alert and event history |
wazuh-manager-data | Wazuh agent registrations + manager state |
cortex-data | Cortex Elasticsearch (if Cortex enabled) |
thehive-data | TheHive Cassandra (if TheHive enabled) |
poc-profile tenants use local-path, which has no real persistence guarantee: a node restart can lose data. persistent-profile tenants use whatever StorageClass the install marks default; back up according to that provisioner's documentation.
Cadence
| Layer | Suggested cadence | Retention |
|---|---|---|
Postgres logical backup (pg_dump) | daily | 30 days |
| Postgres WAL archiving | continuous | 7 days |
| Kubernetes Secrets snapshot | weekly + on every rotation | 90 days |
| Per-tenant PVCs | matches your customer SLA (typically daily for compliance work) | per-contract |
Compliance customers (PCI, HIPAA, SOC 2) often require longer retention. Treat the above as the floor.
Postgres backup
pg_dump (logical)
Runs against the live database, no downtime. Slower restore than physical backup but compresses well and is portable.
kubectl -n soctalk-system exec soctalk-system-postgres-0 -- \
pg_dump -U soctalk_app -d soctalk -Fc -Z 9 \
> soctalk-$(date +%Y%m%d).pgdumpPipe to your usual offsite store (S3, GCS, Azure Blob).
WAL archiving (point-in-time)
Not wired through the chart in this release. The soctalk-system chart does not expose a postgres.archiveCommand value, so PITR requires a Postgres deployment outside the chart's bundled StatefulSet. Two paths:
- Run Postgres externally (managed RDS / Cloud SQL / Azure Database for PostgreSQL). Configure WAL archiving / PITR per the provider's docs. Pointing the chart at an external Postgres is not wired through values in V1: the chart hard-codes the bundled StatefulSet's connection details into the role-creds Secrets. Today this means either running your own helm overlay that patches the API Deployment's
DATABASE_URLenv, or modifyingsoctalk-system-postgres-app-creds/-mssp-creds/-admin-credsafter install. Apostgres.externalvalues knob is on the roadmap. - Sidecar archiver in your own helm overlay (e.g.,
spiloorwal-gas a sidecar). Out of scope for the chart; runs as a separate Deployment that streams WAL to object storage.
Either way, the SocTalk side is unchanged, the data plane treats Postgres as an external dependency. Wiring a chart-side archiveCommand is tracked for a future release.
Restore (Postgres)
See the runbook. Summary:
- Scale API to zero so nothing is writing (the V1 chart bundles the orchestrator into the API pod, one Deployment).
pg_restorethe dump (clean DB first).- If using WAL: replay WAL to the desired point-in-time.
- Scale API back up.
After restore, the API pod (which embeds the orchestrator in the V1 chart) may need a kick to re-pick up pending runs:
kubectl -n soctalk-system rollout restart deploy soctalk-system-apiSecrets backup
K8s Secrets are tedious to back up safely because of the secret material. Two patterns:
Sealed Secrets (recommended)
Install Bitnami sealed-secrets once per cluster. Convert your Secrets to SealedSecret resources; commit those to git. The cluster's controller decrypts them at install time. Loss of a Secret is recoverable from git.
Velero with restic / kopia
Velero backs up Kubernetes resources (including Secrets) plus PVCs to object storage. Use the in-tree CSI snapshotter for PVCs and standard resource backup for Secrets.
velero backup create soctalk-system-daily \
--include-namespaces soctalk-system \
--snapshot-volumes \
--schedule "0 2 * * *"Per-tenant PVC backup
persistent-profile tenants use real StorageClass; use that provisioner's snapshot tools:
- Longhorn: built-in scheduled backups to S3
- Rook/Ceph: RBD snapshots or
cephfs-mirror - CSI cloud volumes (EBS/Persistent Disk/Azure Disk): native snapshot APIs
For Velero users, velero backup create tenant-<slug>-daily --include-namespaces tenant-<slug> --snapshot-volumes covers both the PVCs and the K8s objects in one go.
Per-tenant restore
- Decommission the existing tenant (if any), this deletes the namespace.
- Restore the PVCs to a fresh namespace from the snapshot.
- Onboard a tenant with the same slug and profile via
POST /api/mssp/tenants/onboard: provisioning is idempotent on the namespace, so the Helm install will adopt the restored PVCs. - Verify Wazuh sees existing agents (no re-enrollment needed if PVC restore was clean).
If only the data plane is corrupted (not the SocTalk control plane), the simpler path is helm rollback tenant-<slug> then restore the PVCs in-place.
Restore drill
Run a restore drill quarterly. Pick a non-prod cluster or a temporarily-quiesced tenant. Time-box at 4 h. Document what failed and update this page.
Common failures the drill catches:
- WAL gap (archiving fell behind during a node failure)
- Secrets that were rotated since the last backup
- StorageClass mismatch between cluster and snapshot
- Network policy blocking the restored pod from reaching the new Postgres
What's not covered here
- Cluster-wide disaster recovery (control plane node loss, etc.), that's Kubernetes operations, not SocTalk-specific. See your distribution's documentation.
- LLM provider credential recovery, out of scope; manage with your normal secret-rotation runbook.
- Customer-side endpoint backups, the customer's responsibility, not the MSSP's.
