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-lbLoadBalancer 192.168.1.32:8200,openbao-nodeport30820, plus ClusterIPopenbao,openbao-internal(headless),openbao-ui - Storage:
data-openbao-0PVC, 5Gi Longhorn (Raft backend) - Auto-unseal: CronJob
openbao-unsealruns 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.