Files
OpenBAO/docker-compose.yml
Lutz Finsterle d3c7d2445f Audit-Log einrichten: deklarativ, mit Rotation und haltbarem Pfad
Bis jetzt gab es kein Audit-Device - also keinerlei Aufzeichnung, wer welches
Geheimnis gelesen hat. Bei der Fehlersuche an der Identitaet "claude" am
2026-10-03 haette ein Blick ins Audit-Log die Ursache sofort gezeigt, weil die
beim Login vergebenen Policies darin stehen.

Deklarativ in openbao.hcl statt per `bao audit enable`: OpenBAO 2.x lehnt den
API-Weg ausdruecklich ab ("cannot enable audit device via API; use declarative,
config-based audit device management instead") - anders als Vault. Der Block
wird bei Neustart und bei SIGHUP uebernommen, der Reload lief daher ohne
Ausfall und ohne Entsiegeln.

log_raw bleibt auf dem Standard false: sensible Werte werden gehasht. Im Log
steht nachgeprueft ein HMAC statt des client_token, dazu Operation, Pfad,
display_name, policies und entity_id.

Dazu zwei Dinge, die das betriebssicher machen:
- /openbao/logs war ein ANONYMES Volume aus dem Image, nicht in der compose
  deklariert. Es haette ein `docker compose down -v` nicht ueberlebt. Jetzt ein
  Bind-Mount auf ./logs (uid 100 = openbao im Container). Der Pfad im Container
  bleibt gleich, der audit-Block muss dafuer nicht angepasst werden. Greift beim
  naechsten `docker compose up -d openbao`.
- logrotate: taeglich, 30 Generationen, zusaetzlich maxsize 100M. Das ist
  Pflicht, nicht Komfort - Audit-Devices sind blockierend, bei voller Platte
  weist OpenBAO Anfragen ab. SIGHUP im postrotate statt copytruncate, damit
  keine Zeilen verloren gehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FXUoNtUh1qEdZXSzQeSos4
2026-10-03 10:54:58 +02:00

68 lines
2.2 KiB
YAML

services:
openbao:
image: openbao/openbao:2.6.2
container_name: openbao
restart: unless-stopped
# The image entrypoint already runs `bao server -config=/openbao/config`
# (the whole config dir), so we only pass the subcommand here.
command: server
ports:
# Plaintext API bound to loopback only — local CLI/admin use. LAN clients
# reach OpenBAO via Traefik (TLS) at https://openbao.famfi.home instead.
- "127.0.0.1:8200:8200"
environment:
BAO_ADDR: "http://127.0.0.1:8200"
networks:
- default
- traefik_proxy
volumes:
- ./config:/openbao/config:ro
- openbao-data:/openbao/file
# Audit-Log auf den Host: /openbao/logs war vorher ein anonymes
# Volume aus dem Image und haette ein `down -v` nicht ueberlebt.
- ./logs:/openbao/logs
healthcheck:
# 200 = unsealed+active. Accept sealed (501) and standby (429) too,
# so the container is "healthy" once the API is responding at all.
test: ["CMD", "bao", "status", "-address=http://127.0.0.1:8200"]
interval: 30s
timeout: 5s
retries: 5
start_period: 10s
depends_on:
- openbao-unsealer
# Minimal sidecar instance that provides transit auto-unseal for the main
# node above. Shamir-sealed itself; only reachable on the internal network.
openbao-unsealer:
image: openbao/openbao:2.6.2
container_name: openbao-unsealer
restart: unless-stopped
command: server
# No host port published — only the main node needs it, over the default net.
environment:
BAO_ADDR: "http://127.0.0.1:8200"
networks:
- default
volumes:
- ./config-unsealer:/openbao/config:ro
- openbao-unsealer-data:/openbao/file
healthcheck:
test: ["CMD", "bao", "status", "-address=http://127.0.0.1:8200"]
interval: 30s
timeout: 5s
retries: 5
start_period: 10s
networks:
# Project-internal network (default).
default:
# Shared with the Traefik stack so Traefik can reach this container by name
# (http://openbao:8200). Created by the Traefik compose project.
traefik_proxy:
external: true
volumes:
openbao-data:
openbao-unsealer-data: