A multi-agent sanity audit of the freshly-merged deployment found four end-to-end blockers (and several smaller issues); all fixed here. HIGH (were blocking): - deploy.sh never called install_docker(), so `docker compose pull` hit command-not-found on any host without Docker. Now called before the compose steps. - The container's server process runs as the image's own (often non-root) user but the mounted config/TLS were root-owned 0640/0600 and the raft volume root-owned -> vault crash-looped, never binding :8200. deploy.sh now detects the image UID after pull and aligns ownership of config.hcl, ./tls and the data volume (a no-op when the image runs as root); config.hcl is installed 0644 (holds no secrets). - Docs told operators to set the daemon key `openbao_ca_cert`, but the Kanrisha daemon's key is `ca_cert` (config.go, mapstructure:"ca_cert"). The wrong key is fatal on strict unmarshal / leaves TLS unverified. Renamed in all 5 places (config.hcl, gen-tls.sh, deploy.sh x2, README). - DR backup used `docker compose cp openbao:… -`, which emits a TAR stream, so the age-encrypted snapshot was tar-wrapped and would not restore. Switched to `docker compose exec -T openbao cat` for the raw bytes, wrote the snapshot to a scratch path (not the live raft dir), and documented the matching restore. MEDIUM: - Swap detection used `swapon --show` (absent on BusyBox) and `\s` (GNU-only) -> silently no-op on Alpine, leaving swap on. Now uses /proc/swaps and [[:space:]] so mlock hardening actually holds on musl. - A Docker-published port bypasses the host INPUT firewall, so the source rule was illusory. deploy.sh now narrows OPENBAO_BIND to OPENBAO_ADDR when it is an IP, the compose/README/.env comments state the reality, and a new Exposure section + an init-immediately warning were added. - Fixed broken ../kanrisha/ and deployments/kanrisha/ links (separate repo). LOW: - OPENBAO_TLS_SANS is now honored (folded into the SAN list from the env). - .gitignore excludes *.snap / *.snap.age. - Bootstrap note clarifies bootstrap.sh needs the `bao` CLI (run it from the Kanrisha host/workstation, not this Docker-only vault host). - README multi-OS count corrected (eight stacks) + automations.sh header lists openbao. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57 lines
2.4 KiB
YAML
57 lines
2.4 KiB
YAML
# OpenBao stack — hardened tape-encryption key store for Kanrisha.
|
|
#
|
|
# Topology (same-LAN, NO reverse proxy):
|
|
# Kanrisha tape host --https--> openbao:8200 (native TLS on the vault itself)
|
|
#
|
|
# Unlike the other stacks in this repo there is no Caddy / Let's Encrypt: a
|
|
# secrets store terminates TLS itself and is reached over the LAN, not the
|
|
# public internet. TLS is a self-signed cert (deploy.sh generates it) or a
|
|
# CA-signed pair you drop in ./tls (e.g. via your Smallstep CA over ACME).
|
|
|
|
name: openbao
|
|
|
|
volumes:
|
|
openbao-data: # raft integrated storage — the vault's persistent state
|
|
|
|
services:
|
|
openbao:
|
|
image: openbao/openbao:${OPENBAO_TAG:-2.5.5}
|
|
container_name: openbao
|
|
command: server -config=/openbao/config/config.hcl
|
|
restart: unless-stopped
|
|
# mlock: keep key material off swap. IPC_LOCK + unlimited memlock let the
|
|
# process lock its memory; the HOST must also have swap disabled.
|
|
cap_add:
|
|
- IPC_LOCK
|
|
ulimits:
|
|
memlock: -1
|
|
ports:
|
|
# Native-TLS API. Publish on the LAN IP only (OPENBAO_BIND) so it is not
|
|
# exposed on unrelated interfaces. NOTE: a Docker-published port is DNAT'd
|
|
# and bypasses the host INPUT firewall, so a source restriction there does
|
|
# NOT gate it — narrow access with OPENBAO_BIND + the optional mTLS
|
|
# (tls_require_and_verify_client_cert) stanza in config.hcl, and initialise
|
|
# the vault immediately (an uninitialised vault can be init'd by anyone who
|
|
# can reach it). deploy.sh defaults OPENBAO_BIND to OPENBAO_ADDR when it is
|
|
# an IP.
|
|
- "${OPENBAO_BIND:-0.0.0.0}:8200:8200"
|
|
volumes:
|
|
- ./config.hcl:/openbao/config/config.hcl:ro
|
|
- ./tls:/openbao/tls:ro
|
|
- openbao-data:/openbao/data
|
|
environment:
|
|
# PKCS#11 auto-unseal PIN — only read when the seal "pkcs11" stanza is
|
|
# enabled in config.hcl. Harmless (unused) otherwise.
|
|
BAO_HSM_PIN: "${OPENBAO_HSM_PIN:-}"
|
|
# HA / multi-node only: advertise this node's reachable LAN address.
|
|
# BAO_API_ADDR: "https://${OPENBAO_ADDR}:8200"
|
|
# BAO_CLUSTER_ADDR: "https://${OPENBAO_ADDR}:8201"
|
|
# 0 = unsealed (healthy); 2 = sealed -> unhealthy so a node needing an unseal
|
|
# is visible. -tls-skip-verify because the listener may use a self-signed cert.
|
|
healthcheck:
|
|
test: ["CMD", "bao", "status", "-address=https://127.0.0.1:8200", "-tls-skip-verify"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 10s
|