2026-06-11 14:55:34 +02:00
2026-05-11 19:17:12 +02:00

Backup Tool v2

A self-hosted, integrity-first backup appliance for local and hardened SSH sources.

Backup Tool creates signed, content-addressed backups, supports encrypted repositories and offline recovery, and runs as isolated web, scheduler, worker, migration, and admin roles. v2.0 supports local and SSH sources, local repositories, restore, encrypted recovery, email, and signed webhooks.

What is supported

  • Signed full and incremental backups, restore, retention, verification, and recovery.
  • AES-256-GCM repository encryption with key epochs and offline Argon2id recovery bundles.
  • Local sources and SSH sources using private-key-only, pinned-host-key, forced-SFTP chroot access.
  • Durable, at-least-once webhook and STARTTLS SMTP notifications.
  • A generated OpenAPI TypeScript client and operator UI.

Never use an SSH source with a shell, password, agent forwarding, remote commands, or an unchrooted account. See SSH source requirements.

Quick local verification

Prerequisites: Docker Compose, Python 3.123.14, Node/npm, and a working virtual environment.

make setup
make check
make test-e2e
make test-ssh-integration

make test-e2e creates temporary test-only keys and source data, starts the complete Compose stack, checks readiness/metrics/restart behavior, and tears it down. make test-ssh-integration builds a separate forced-SFTP fixture and verifies key-authenticated SSH probe, backup, verification, and restore.

Run locally with Docker Compose

The production Compose topology binds the proxy to 127.0.0.1:8080; put a TLS reverse proxy in front of it for remote access.

mkdir -p secrets sources
head -c 32 /dev/urandom > secrets/master.key
chmod 600 secrets/master.key
# The container runs as UID 10001; grant that UID read access to the key.
chown 10001:10001 secrets/master.key

# Put test source data below ./sources, then start the isolated roles.
docker compose build --pull
docker compose run --rm migrate upgrade
docker compose up -d
curl -fsS http://127.0.0.1:8080/readyz
curl -fsS http://127.0.0.1:8080/metrics

On a fresh non-loopback deployment, set BACKUP_TOOL_PUBLIC_BASE_URL to the externally reachable HTTPS URL and set BACKUP_TOOL_BOOTSTRAP_SECRET before first setup. Never expose a fresh setup endpoint without bootstrap protection.

Stop the local stack with:

docker compose down
# Add --volumes only when intentionally discarding local metadata and repositories.

Operator workflow

  1. Open http://127.0.0.1:8080 and create the first administrator.
  2. Create a local or encrypted repository.
  3. Create a local source, or configure a hardened SSH source as documented in SSH sources.
  4. Create a job, run a probe, enqueue a backup, verify it, then perform a test restore.
  5. Configure notification subscriptions and test them before relying on delivery.
  6. Export and validate a recovery bundle after encrypted repository creation and each key rotation.

The browser exposes recovery status and the CLI procedure only; it never transfers recovery bundles or passphrases.

Configuration

Compose supplies the core runtime variables. The important host paths are:

Setting Compose value Purpose
BACKUP_TOOL_MASTER_KEY_FILE /run/backup-tool-secrets/master.key Service-owned 0600 master key
BACKUP_TOOL_SOURCES_DIR ./sources Read-only local-source bind mount
BACKUP_TOOL_PUBLIC_BASE_URL http://localhost:8080 External URL and bootstrap policy
BACKUP_TOOL_PORT 8080 Loopback proxy port

Use absolute, allowlisted paths for repositories, sources, and restores. The service rejects unsafe paths, symlinks where they violate the contract, missing key files, and non-current schemas.

Operations and security

Development

make setup
make test-fast
make test-integration
make test-fault
make test-security
npm --prefix frontend test -- --run
npm --prefix frontend exec playwright test

OpenAPI and the generated browser client are committed artifacts:

.venv/bin/python tools/export_openapi.py --check openapi/v2.json
npm --prefix frontend run api:generate
git diff --exit-code -- openapi/v2.json frontend/src/api/generated

Release evidence

Milestone evidence, the SBOM, provenance, and synthetic scale report live in docs/release. M15 certification is synthetic metadata certification on the reference CI host; it does not claim a physical 10 TiB transfer.

License

MIT — see LICENSE.

S
Description
No description provided
Readme MIT 30 MiB
Languages
Python 82.5%
TypeScript 13.2%
HTML 3.5%
Dockerfile 0.4%
Makefile 0.2%