Malspark

Operations

Backups

What carries state that cannot be rebuilt, how to back it up, and how to restore it.

Two things carry state that cannot be rebuilt: the Postgres volume (pgdata) and the MinIO volume (minio_data). The Qdrant volume holds long-term memory, which is derived from past analyses; the ATT&CK cache volume is purely derived.

cd docker
docker compose exec -T postgres pg_dump -U malspark malspark > malspark-$(date +%F).sql

Back up MinIO by copying the bucket out with any S3 client, or by snapshotting the minio_data volume while the stack is down.

A database dump is not enough on its own: every secret in the settings store is encrypted with SETTINGS_ENCRYPTION_KEY, which is not in the dump. Store the key with the backup, or the restored instance comes up with every credential unreadable. A JSON export (see Export and import) is a useful complement — it is safe to keep next to the dump precisely because it carries no credentials.

What to keep

WhatWhereRebuildable
Jobs, reports, the sealed ledger, settings, users, the audit chainPostgres, volume pgdataNo
Samples and uploaded sandbox reportsMinIO, volume minio_dataNo
SETTINGS_ENCRYPTION_KEY, JWT_SECRET_KEY and the rest of docker/.envYour secret storeNo
Long-term memory of past casesQdrant, volume qdrant_dataOnly by rerunning the analyses
The ATT&CK cacheVolume attck_cacheYes, fetched again
Ghidra projectsVolume ghidra_projectsYes, analysed again

Restoring

Start Postgres alone, with the same POSTGRES_PASSWORD the dump's instance used:

cd docker && docker compose up -d postgres

Load the dump:

docker compose exec -T postgres psql -U malspark -d malspark < malspark-2026-11-06.sql

Put the MinIO objects back, and the same SETTINGS_ENCRYPTION_KEY in docker/.env.

Start the stack with make docker-up. The migrate service brings an older dump up to the current schema.

After a restore, check a stored report's ledger seal with GET /api/v1/jobs/{job_id}/evidence/verify. If you keep the audit chain's anchor outside the database (AUDIT_ANCHOR), back the anchor up with the dump; see The bootstrap contract.

Edit on GitHub

On this page