Skip to content

OpenBao

OpenBao is the heezy secrets manager (self-hosted HashiCorp Vault fork).

Access

URL: https://openbao.heezy.info

Internal only — resolves via dnsmasq to 192.168.1.25 (SWAG). Never goes through Cloudflare.

Prerequisite: DNS

Your machine must use 192.168.1.29 as its DNS server.

macOS: System Settings → Network → active interface → Details → DNS → add 192.168.1.29

Verify: dig openbao.heezy.info should return 192.168.1.25

Get a Login Token

OpenBao uses AppRole for machine auth. For the UI, generate a short-lived token (expires 1 hour):

curl -sk -X POST https://openbao.heezy.info/v1/auth/approle/login \
  -H 'Content-Type: application/json' \
  -d "{\"role_id\":\"$VAULT_ROLE_ID\",\"secret_id\":\"$VAULT_SECRET_ID\"}" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['auth']['client_token'])"

VAULT_ROLE_ID and VAULT_SECRET_ID come from the q-mcp/.env file the MCP container reads, not from this page. In the UI: select Token, paste the token, click Sign In. The MCP agent can also generate one on demand.

This page used to publish the AppRole credentials

A literal role_id and secret_id pair were pasted into this command until 2026-08-11. They remain in the git history of heezy-docs and, per mcp-server.js, the same values are the hardcoded fallback used when the env vars are absent. Rotate that AppRole, then update q-mcp/.env. A Vault AppRole rotation silently breaks postgres_query, fortinet_config, and the Cisco switch SSH path until .env is updated, so do both in the same change.

Architecture

Browser → https://openbao.heezy.info
  → dnsmasq: openbao.heezy.info → 192.168.1.25 (SWAG VIP)
  → SWAG terminates TLS → openbao.openbao.svc.cluster.local:8200
  → OpenBao pod (openbao namespace)
  • K8s namespace: openbao
  • Services: openbao-lb LoadBalancer 192.168.1.32:8200, openbao-nodeport 30820, plus ClusterIP openbao, openbao-internal (headless), openbao-ui
  • Storage: data-openbao-0 PVC, 5Gi Longhorn (Raft backend)
  • Auto-unseal: CronJob openbao-unseal runs every 5 min

Secret Paths

All secrets are KV v2 under secret/data/. Verified 2026-08-11 against the ExternalSecrets in heezy-k8s and the roles in ansible-heezy.

Consumed by ExternalSecrets in the cluster

Path Contents
production/heezy/postgres/heezy-credentials Postgres credentials for heezy-finance and receipts
production/heezy/gitea/postgres Gitea's Postgres credentials
production/heezy/gmail/oauth Gmail OAuth client id, secret, refresh token
production/heezy/receipts/aws-credentials Textract IAM creds
all/heezy/discord/webhooks Discord webhooks, including claude-code and budget alerts
production/heezy/gluetun/nordvpn NordVPN credentials for the gluetun sidecars
production/heezy/slskd slskd API key
production/heezy/tailscale Tailscale auth key
production/heezy/swag/cloudflare SWAG DNS-01 token
production/heezy/heezy-blog/cloudflare, production/heezy/heezy-info/cloudflare cloudflared tunnel tokens
production/heezy/oauth-callback/config OAuth callback service config

Consumed by Ansible, Terraform, and the MCP server

Path Contents
production/heezy/terraform/fortigate/secret FortiGate API credentials (Terraform)
production/heezy/network/fortigate FortiGate credentials (fortinet_config MCP tool)
production/heezy/network/ruckus Ruckus credentials
production/heezy/cisco-switch/secret Cisco switch password (sshpass path in mcp-server.js)
production/heezy/ssh/mcp-admin-private-key MCP admin SSH private key
production/heezy/backup/aws-credentials S3 backup IAM creds
production/heezy/github/runner-token, production/heezy/github_runner/aws_credentials Runner registration and AWS access
production/heezy/microk8s/aws_credentials ECR pull credentials refresher
production/heezy/grafana/discord-webhook, .../discord-events-webhook Grafana contact points
production/heezy/big-boi/plex, .../steam-headless, .../discord big-boi compose service secrets
production/heezy/ubuntu/cloud-init-credentials Ubuntu VM default credentials
production/heezy/windows/administrator/credentials Windows admin credentials
production/heezy/uptime-kuma Uptime Kuma credentials

Paths that used to be documented here and do not exist

production/heezy/postgres-credentials, production/heezy/gmail/oauth-credentials, production/heezy/gitea/runner-pat, all/heezy/aws/ecr-credentials, and production/heezy/cloudflare/pages-token. The first two were renamed; the rest have no consumer in any repo. all/heezy/ubuntu/cloud-init-credentials is under production/, not all/.

Troubleshooting

Can't reach the URL: - dig openbao.heezy.info must return 192.168.1.25 - If not, set DNS to 192.168.1.29

Token expired: - Generate a new one with the curl command above

Sealed:

curl -sk https://openbao.heezy.info/v1/sys/health \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print('sealed:', d['sealed'])"
sealed: False = healthy. The unseal CronJob recovers it within 5 minutes automatically.