diff --git a/hosts/h001/mods/openbao.nix b/hosts/h001/mods/openbao.nix index 5c1722be..0e600754 100644 --- a/hosts/h001/mods/openbao.nix +++ b/hosts/h001/mods/openbao.nix @@ -1,10 +1,12 @@ { + config, pkgs, ... }: { environment.variables = { - BAO_ADDR = "http://localhost:8200"; + # For CLI + BAO_ADDR = "http://127.0.0.1:8200"; }; services.nginx = { @@ -46,9 +48,9 @@ }; # Ensure the data directory exists with proper permissions - systemd.tmpfiles.rules = [ - "d /var/lib/openbao 0700 openbao openbao - -" - ]; + # systemd.tmpfiles.rules = [ + # "d /var/lib/openbao 0700 openbao openbao - -" + # ]; # Additional systemd service hardening systemd.services.openbao = { @@ -65,4 +67,66 @@ LimitNPROC = 4096; }; }; + + # AUTO UNSEAL + systemd.services.openbao-auto-unseal = { + description = "Auto-unseal OpenBao using stored unseal key shares"; + after = [ "openbao.service" ]; + wants = [ "openbao.service" ]; + # Run once at boot; doesn't restart + serviceConfig = { + Type = "oneshot"; + # run as the same user as the openbao service + # User = config.systemd.services.openbao.User; + # Group = config.systemd.services.openbao.Group; + # /run/keys/... are usually readable by root only; you might prefer to run as root + User = "root"; + Group = "root"; + + # Only needs network access to 127.0.0.1 + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = true; + ReadOnlyPaths = [ "/" ]; + # allow reading /run/keys and talking to localhost + ReadWritePaths = [ "/run" ]; + NoNewPrivileges = true; + + ExecStart = pkgs.writeShellScript "openbao-auto-unseal" '' + #!/usr/bin/env bash + set -euo pipefail + + export BAO_ADDR="http://127.0.0.1:8200" + + # Wait for OpenBao to be listening + # (systemd "after" ensures start order but not readiness) + for i in {1..30}; do + if bao status >/dev/null 2>&1; then + break + fi + sleep 1 + done + + # If it's already unsealed, exit + if bao status 2>/dev/null | grep -q 'sealed *false'; then + exit 0 + fi + + # Apply each unseal key share; ignore "already unsealed" errors + # TODO change this back to /run/agenix instead of /root/bao-keys + for key in /root/bao-keys/openbao-unseal-*; do + if [ -f "$key" ]; then + bao operator unseal "$(cat "$key")" || true + fi + done + + # Check final status; fail if still sealed + if bao status 2>/dev/null | grep -q 'sealed *true'; then + echo "OpenBao is still sealed after applying unseal keys" >&2 + exit 1 + fi + ''; + }; + wantedBy = [ "multi-user.target" ]; + }; }