fix(openbao): sanity-audit fixes — 4 blockers + hardening

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>
This commit is contained in:
57_WolveandClaude Opus 4.8 committed 2026-07-08 19:11:37 -05:00
1 parent 2efc9dbffb
commit 0812f345a8
9 files changed
+216 -112

No files matched your search

+8 -2
View File
@@ -26,8 +26,14 @@ services:
ulimits:
memlock: -1
ports:
# Native-TLS API. Bind to the LAN IP (OPENBAO_BIND) to avoid exposing it on
# every interface; firewall it to the tape host (deploy.sh does this).
# 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