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>
52 lines
2.3 KiB
HCL
52 lines
2.3 KiB
HCL
# OpenBao — hardened, same-LAN tape-encryption key store for Kanrisha.
|
|
#
|
|
# Native TLS on the listener (no reverse proxy in front), integrated raft
|
|
# storage (clean snapshot-based DR), and mlock enabled. This vault is the SOLE
|
|
# recovery path for encrypted tapes — losing the OpenBao data AND the unseal
|
|
# material loses every encrypted tape. Back it up (raft snapshots) and store the
|
|
# unseal keys/root token out of band (see the README + DR runbook).
|
|
|
|
storage "raft" {
|
|
path = "/openbao/data"
|
|
node_id = "openbao-1"
|
|
}
|
|
|
|
# TLS-terminating listener. tls.crt/tls.key are self-signed by deploy.sh on first
|
|
# run, or a CA-signed pair you drop in ./tls (e.g. issued by your Smallstep CA
|
|
# over ACME — see the README). The Kanrisha daemon trusts this via
|
|
# [encryption.openbao].ca_cert.
|
|
listener "tcp" {
|
|
address = "0.0.0.0:8200"
|
|
tls_cert_file = "/openbao/tls/tls.crt"
|
|
tls_key_file = "/openbao/tls/tls.key"
|
|
# Optional mTLS — require + verify a client cert from the tape host:
|
|
# tls_require_and_verify_client_cert = true
|
|
# tls_client_ca_file = "/openbao/tls/client-ca.crt"
|
|
}
|
|
|
|
# mlock keeps key material off swap — REQUIRED. Needs cap_add: [IPC_LOCK] +
|
|
# ulimits memlock unlimited (docker-compose.yml) and swap disabled on the host.
|
|
# Do NOT add `disable_mlock = true`.
|
|
|
|
# Single-node raft: advertising 127.0.0.1 is fine because a lone node is always
|
|
# ACTIVE and never redirects clients (they connect straight to the LAN address).
|
|
# For HA / multiple nodes, set BAO_API_ADDR + BAO_CLUSTER_ADDR to each node's
|
|
# reachable LAN address in the compose env instead.
|
|
api_addr = "https://127.0.0.1:8200"
|
|
cluster_addr = "https://127.0.0.1:8201"
|
|
ui = false
|
|
|
|
# ── Auto-unseal (optional) — DEFAULT IS MANUAL UNSEAL ────────────────────────
|
|
# With no seal stanza OpenBao starts SEALED and needs `bao operator unseal` (x3)
|
|
# after every restart. To auto-unseal against a PKCS#11 HSM/token, uncomment and
|
|
# fill this in, mount the PKCS#11 module + device into the container, and set
|
|
# OPENBAO_HSM_PIN in .env:
|
|
#
|
|
# seal "pkcs11" {
|
|
# lib = "/usr/lib/softhsm/libsofthsm2.so"
|
|
# slot = "0"
|
|
# pin = "env://BAO_HSM_PIN"
|
|
# key_label = "kanrisha-unseal"
|
|
# mechanism = "0x1087" # CKM_AES_GCM
|
|
# }
|