Skip to content

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_log and event-sourced case_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-keyLLM provider API key (install-wide default)
soctalk-system-bootstrap-adminInitial admin email + password (if install.bootstrapAdmin.password set in values)
soctalk-system-jwt-signing-keySession token signing key
soctalk-system-adapter-signing-keyAdapter-token signing key
soctalk-system-postgres-admin-credsPostgres soctalk_admin (migrations) creds
soctalk-system-postgres-app-credsPostgres soctalk_app (runtime) creds
soctalk-system-postgres-mssp-credsPostgres soctalk_mssp (cross-tenant queries) creds
soctalk-slack-credsSlack tokens (env-provided; not chart-rendered)
soctalk-thehive-credsTheHive API key (env-provided)
soctalk-cortex-credsCortex 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:

PVCWhat's in it
wazuh-indexer-dataAll Wazuh alert and event history
wazuh-manager-dataWazuh agent registrations + manager state
cortex-dataCortex Elasticsearch (if Cortex enabled)
thehive-dataTheHive 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

LayerSuggested cadenceRetention
Postgres logical backup (pg_dump)daily30 days
Postgres WAL archivingcontinuous7 days
Kubernetes Secrets snapshotweekly + on every rotation90 days
Per-tenant PVCsmatches 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.

bash
kubectl -n soctalk-system exec soctalk-system-postgres-0 -- \
  pg_dump -U soctalk_app -d soctalk -Fc -Z 9 \
  > soctalk-$(date +%Y%m%d).pgdump

Pipe 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:

  1. 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_URL env, or modifying soctalk-system-postgres-app-creds / -mssp-creds / -admin-creds after install. A postgres.external values knob is on the roadmap.
  2. Sidecar archiver in your own helm overlay (e.g., spilo or wal-g as 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:

  1. Scale API to zero so nothing is writing (the V1 chart bundles the orchestrator into the API pod, one Deployment).
  2. pg_restore the dump (clean DB first).
  3. If using WAL: replay WAL to the desired point-in-time.
  4. 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:

bash
kubectl -n soctalk-system rollout restart deploy soctalk-system-api

Secrets backup

K8s Secrets are tedious to back up safely because of the secret material. Two patterns:

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.

bash
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

  1. Decommission the existing tenant (if any), this deletes the namespace.
  2. Restore the PVCs to a fresh namespace from the snapshot.
  3. 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.
  4. 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.

Released under the Apache 2.0 License.