No description
  • Go 84.2%
  • TypeScript 12.2%
  • PowerShell 1.7%
  • Shell 1.5%
  • CSS 0.2%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-24 14:44:27 +02:00
api Address audit review findings 2026-08-09 17:05:12 +02:00
build Preserve accumulated local work 2026-08-24 07:53:28 +02:00
cmd Harden target binding and persistence recovery 2026-08-09 17:39:56 +02:00
configs Preserve accumulated local work 2026-08-24 07:53:28 +02:00
docs Preserve accumulated local work 2026-08-24 07:53:28 +02:00
internal Prepare v1.2.0 release 2026-08-09 19:58:12 +02:00
trust release: prepare v1.0.0 2026-07-27 06:25:34 +02:00
web Update dependencies 2026-08-24 13:34:18 +02:00
.gitattributes Prepare v1.2.0 release 2026-08-09 19:58:12 +02:00
.gitignore Ignore local qualification and tooling scratch files 2026-07-28 09:14:42 +02:00
buf.gen.yaml release: prepare v1.0.0 2026-07-27 06:25:34 +02:00
go.mod Update dependencies 2026-08-24 13:34:18 +02:00
go.sum Update dependencies 2026-08-24 13:34:18 +02:00
LICENSE release: prepare v1.0.0 2026-07-27 06:25:34 +02:00
README.md Add Windows system backup and recovery 2026-07-31 09:29:58 +02:00

kBackup

kBackup is a self-contained, cross-platform (Windows + Linux) deduplicating, content-addressed, encrypted, block-level backup suite: a background service owns all scheduling and job execution, and a terminal UI is a thin client to it. It targets file-tree and raw volume/disk image sources, local/S3/SFTP repositories, and uses only embedded local storage (no external/server databases).

The implemented and tested surface includes repository CRUD and durable configuration overlays, scheduling and progress, notifications, maintenance operations, service settings, file and image backup/restore, file extraction, and snapshot mounts, exposed through kbackupd over named-pipe/unix-socket gRPC, the terminal UI, and an optional embedded web UI.

On Windows, an exclusion-aware system source captures the OS volume through required VSS consistency and records recovery metadata for a fresh-disk WinPE restore. It remains preview pending the qualification described in docs/system-backup-windows.md.

Operational and qualification status

kBackup currently supports one active host/process per repository. Repository lock objects are advisory conflict detection, not backend-enforced fenced leases; concurrent writers on independent hosts are unsupported.

Safe-host tests, deterministic Linux/Windows release preflights, and scoped disposable Linux and Windows development-artifact qualification have passed for the recorded cells. This includes Debian/Fedora package and device exercises, Windows Go/installer exercises, and an exact q37.3 WinPE build, Secure Boot, negative-target, dry-run, whole-disk restore, and complete logical-byte comparison. See docs/qualification.md for the exact scope and evidence identities.

The project is still not production-ready. The initial v1.0.0 target is a controlled-distribution, amd64, local-backend, file-tree profile on the exact Windows 11 Enterprise 25H2/NTFS and Debian 13/ext4 cells that pass final acceptance. Its remaining blockers are the offline public trust ceremony, exact self-managed-signed artifacts, destructive local-repository fault tests, measured scale limits, independent release-worker reproducibility, and final Windows/Debian acceptance. S3/SFTP, RPM/Fedora, raw image/CBT, mounts, rescue, physical hardware, pre-release repository migration, and other unqualified cells are preview/unsupported rather than v1.0.0 blockers. See the initial support profile.

Operator documentation:

Architecture summary

kbackupd (the service) owns a chunk/pack/index repository engine (keyed BLAKE3 content addressing, zstd+AEAD packs, binary sorted index segments, with a rebuildable Pebble local cache), a scheduler and job queue, and a gRPC IPC surface (named pipe on Windows, unix socket on Linux). kbackup (the TUI, Bubble Tea-based) is a thin client over that IPC surface. Backup sources are either file trees (FastCDC chunking) or raw volume/disk images (fixed-size cluster-aligned blocks, changed-block tracking); all full/differential/incremental runs produce independently restorable, deduplicated snapshots under one repository format. Full design, the milestone build order (M0-M14), and rationale live in the project's approved architecture plan (kept outside this repo, in the maintainer's local plan store).

Repository layout

  • cmd/ contains the service, terminal client, and support command entrypoints.
  • internal/ contains private Go packages grouped by subsystem.
  • api/proto/ defines the RPC contract; api/gen/ contains generated Go code.
  • web/ contains the web client source, tests, and generated API bindings.
  • configs/ contains example runtime configuration.
  • build/ contains release, packaging, signing, CI, and qualification tooling.
  • trust/ contains public release trust material and its authenticated manifest.
  • docs/ contains operator, release, recovery, support, and qualification guides.

Build & test

go build ./...
go vet ./...
go test ./...

The web UI's compiled assets (web/dist) are generated and ignored. Release builds recreate them and embed them into kbackupd. For a local release-style daemon build:

cd web
npm ci
npm run typecheck && npm run lint && npm run test && npm run build
cd ..
go build -tags webdist ./cmd/kbackupd

Ordinary Go builds use a small fallback page so the Go toolchain does not depend on Node. The platform release drivers perform the production web build automatically.

During development, run the Vite dev server (it proxies /api to a locally running kbackupd with the web UI enabled on 127.0.0.1:9898):

cd web && npm run dev

Web UI

kbackupd can serve an embedded React web UI (management parity with the terminal client) over its own HTTP(S) listener. It is disabled by default. On the TUI's first connection, choose Enable for the local-only default (127.0.0.1:9898). The TUI then shows a one-time owner setup link. Open it to choose the administrator password; the token is carried in the URL fragment, removed from the address bar immediately, and never sent in an HTTP request. The TUI Settings tab can enable or disable the listener and edit its advanced TLS/proxy settings while it is disabled.

The owner-only <state_dir>/web-setup-token file remains a manual fallback. The daemon logs only that file's path, never the token. A web: block in the base config can also provide the initial settings (see configs/kbackup.example.yaml); later TUI edits are stored in the service overlay without rewriting the base file.

Loopback listeners serve plain HTTP; any other bind address requires TLS (web.tls) or an explicit web.insecure_http: true acknowledgment. Sessions are in-memory, so restarting the service signs everyone out. To reset a lost admin password, stop the service, delete <state_dir>/web-auth.json, and start it again to get a fresh setup token (this resets only the web login, never repository encryption keys).

Notifications

Notification channels are deliberately limited to transports whose complete send path can be bounded: smtp, webhook, and eventlog. Generic provider router URLs are rejected because their cancellation behavior cannot be proven. SMTP destinations use this form:

smtp://[user:password@]host[:port]/?from=sender@example.com&to=recipient@example.com
smtps://[user:password@]host[:port]/?from=sender@example.com&to=recipient@example.com

smtp:// requires STARTTLS (default port 587); smtps:// starts TLS immediately (default port 465). Repeat to for additional recipients. Webhooks accept absolute HTTP(S) URLs, never follow redirects, optionally sign the JSON body with the configured HMAC secret, and reject response bodies over 64 KiB.

Delivery is best effort and does not change a completed job result. The daemon uses four workers and a queue of 64 deliveries, makes one bounded attempt and at most one retry, and logs a drop if the queue is full or shutdown has stopped admission. A shutdown deadline that expires while a delivery is still active is reported as a service failure; it is not treated as successful cancellation. Returned errors expose no provider details. Internal logs retain provider detail only after removing URLs, credentials, and signatures and bounding it to 8 KiB. The configuration file still contains channel credentials and must retain owner-only permissions.

Check a config file

go run ./cmd/kbackupd --check-config --config configs/kbackup.example.yaml

Repair scheduler catch-up state

A missing scheduler-state.json is valid on a fresh installation, but an existing zero-byte, truncated, malformed, unsupported, unreadable, or invalid file fails daemon startup rather than silently discarding catch-up history. Preserve the reported file for incident analysis. If the history cannot be recovered, stop the daemon and explicitly reset it:

kbackupd repair-scheduler-state --config /path/to/kbackup.yaml --confirm-loss-of-catch-up-history

The command atomically archives the original beside it as scheduler-state.json.pre-repair, refuses to overwrite an earlier archive, and writes a valid empty versioned state. The reset cannot reconstruct missed runs; review affected schedules and run required jobs manually before restarting the daemon.

Regenerating the gRPC/protobuf code

api/gen/*.go and web/src/gen/*.ts are generated from api/proto/*.proto and checked in. Generator versions are pinned in build/ci/tool-versions.env and the web lockfile. Install the locked Buf package and exact Go plugins, then regenerate after editing a .proto file:

npm ci --prefix web
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.6.2
$env:PATH = "$PWD\web\node_modules\.bin;$env:USERPROFILE\go\bin;$env:PATH"
pwsh api/gen.ps1
npm --prefix web run generate:proto

api/gen.ps1 verifies the pinned tool versions and atomically replaces the Go output so deleted schemas cannot leave stale bindings. CI regenerates both output trees in a temporary directory and rejects any difference.

Running kbackupd

kbackupd is the background service; install/uninstall/start/stop register/control it as an OS service (Windows Service Control Manager / systemd), and run executes it directly in the foreground:

go run ./cmd/kbackupd run --config configs/kbackup.example.yaml

License

Copyright (c) Leon Stöwer. kBackup is licensed under the WTFPL, version 2.