{ pkgs, ... }: let unsealScript = pkgs.writeShellApplication { name = "openbao-unseal"; runtimeInputs = with pkgs; [ openbao coreutils gnugrep getent ]; text = '' # Set environment to use Unix socket export BAO_ADDR='unix:///run/openbao/openbao.sock' SOCKET_PATH="/run/openbao/openbao.sock" CREDS_DIR="''${CREDENTIALS_DIRECTORY:-}" # Wait for socket to exist echo "Waiting for OpenBao socket..." for _ in {1..30}; do if [ -S "$SOCKET_PATH" ]; then echo "Socket exists" break fi sleep 1 done # Wait for OpenBao to accept connections echo "Waiting for OpenBao to be ready..." for _ in {1..30}; do output=$(timeout 2 bao status 2>&1 || true) if echo "$output" | grep -q "Sealed.*false"; then # Already unsealed echo "OpenBao is already unsealed" exit 0 elif echo "$output" | grep -qE "(Sealed|Initialized)"; then # Got a valid response, OpenBao is ready (sealed) echo "OpenBao is ready" break fi sleep 1 done # Check if already unsealed if output=$(timeout 2 bao status 2>&1 || true); then if echo "$output" | grep -q "Sealed.*false"; then echo "OpenBao is already unsealed" exit 0 fi fi # Unseal using the TPM-decrypted keys (one per line) if [ -n "$CREDS_DIR" ] && [ -f "$CREDS_DIR/unseal-key" ]; then echo "Unsealing OpenBao..." while IFS= read -r key; do # Skip empty lines [ -z "$key" ] && continue echo "Applying unseal key..." bao operator unseal "$key" # Check if unsealed after each key if output=$(timeout 2 bao status 2>&1 || true); then if echo "$output" | grep -q "Sealed.*false"; then echo "OpenBao unsealed successfully" exit 0 fi fi done < "$CREDS_DIR/unseal-key" echo "WARNING: Applied all keys but OpenBao is still sealed" exit 0 else echo "WARNING: Unseal key credential not found, OpenBao remains sealed" exit 0 fi ''; }; in { services.openbao = { enable = true; settings = { ui = true; storage.file.path = "/var/lib/openbao"; listener.default = { type = "tcp"; address = "0.0.0.0:8200"; tls_cert_file = "/run/credentials/openbao.service/cert.pem"; tls_key_file = "/run/credentials/openbao.service/key.pem"; }; listener.socket = { type = "unix"; address = "/run/openbao/openbao.sock"; }; }; }; systemd.services.openbao.serviceConfig = { LoadCredential = [ "key.pem:/var/lib/openbao/key.pem" "cert.pem:/var/lib/openbao/cert.pem" ]; # TPM2-encrypted unseal key (created manually, see setup instructions) LoadCredentialEncrypted = [ "unseal-key:/var/lib/openbao/unseal-key.cred" ]; # Auto-unseal on service start ExecStartPost = "${unsealScript}/bin/openbao-unseal"; }; }