Files
treatvault/README.md

3.3 KiB

TreatVault

TreatVault manages Barkstack's namespaced secrets. It keeps an age-encrypted source-of-truth file on disk, watches it for changes, and reconciles its contents with Docker Swarm secrets.

Model

  • The Barkfile treatvault block names the encrypted file (a bind-mounted path) and the bootstrap Docker secret holding the age X25519 identity (barkstack_<reference>).
  • The encrypted file is safe to commit and back up: contents are age-encrypted with the X25519 identity; only the identity secret itself stays outside source control.
  • Each logical secret is stored as a versioned record. Sync creates one immutable Docker secret per record revision, named barkstack_tv_<vaultId>_<revision>, labeled with the logical name and vault ID.
  • Consumers mount secrets at the stable target path barkstack_<name>; rotations swap the mounted source and update the service, leaving a rollback path.
  • Obsolete Barkstack-managed secret objects are deleted; objects still mounted by a managed service are reported in the sync status and refused for deletion via the API until their consumers are updated.

CLI

treatvault keygen --identity ./treatvault-identity.txt
treatvault init --file ./secrets.age --identity ./treatvault-identity.txt
treatvault set --name database_password --file ./secrets.age --identity ./treatvault-identity.txt   # value on stdin
treatvault list --file ./secrets.age --identity ./treatvault-identity.txt
treatvault delete --name database_password --file ./secrets.age --identity ./treatvault-identity.txt
treatvault serve --file ./secrets.age --identity ./treatvault-identity.txt --listen :9090

HTTP API

  • GET /barkstack/ui/manifest.json - Barkstack plugin manifest (id treatvault, mount /treatvault).
  • GET /barkstack/api/secrets - secret names, sync state, consumers; never returns values.
  • PUT /barkstack/api/secrets/{name} - create or rotate ({"value":"..."}); triggers an immediate sync.
  • DELETE /barkstack/api/secrets/{name} - delete; 409 Conflict while a managed service still mounts the secret.
  • GET /healthz - ready/degraded sync state.

Barkstack deployment

Add a treatvault block to the Barkfile and run barkstack init on a Swarm manager:

treatvault {
    file ./secrets.age
    identity_secret treatvault_identity
}

barkstack init provisions the barkstack-treatvault service (manager-constrained) with the encrypted file bind-mounted read-write at its host path, the Docker socket, the barkstack_treatvault_identity secret mounted at /run/secrets/barkstack_treatvault_identity, and no published ports; the console reaches it over the overlay network at :9090.

Services that consume vault secrets carry the io.barkstack.treatvault.secrets=true label plus an io.barkstack.treatvault.names label listing the logical names they need; barkstack init labels the PawSQL service automatically. Each sync mounts the current revision at the stable /run/secrets/barkstack_<name> target, so consumers read the same path across rotations.

The Barkstack console automatically gains a TreatVault page (plugin id treatvault) for creating, rotating, and deleting secrets. Deletion is refused with 409 Conflict while a labeled service still mounts the secret.

Build

cd ui && bun install && bun run build && cd ..
go build -o treatvault ./cmd/treatvault
docker build -t treatvault .