OpenBao - Hardened Self-Hosted Secrets Management
by Lynxroute
OpenBao - CIS Level 1 hardened secrets manager on Ubuntu 24.04 LTS. SBOM and CIS Report.
What is OpenBao
OpenBao is an open-source secrets management platform, forked from HashiCorp Vault 1.14 and now hosted by the Linux Foundation. Written in Go and shipped as a single static binary, OpenBao gives applications and operators a central place to store, generate, and rotate secrets: static key-value secrets (KV v1 / v2), dynamic database credentials for Postgres, MySQL, MongoDB and Redis, cloud credentials, x509 certificates through the PKI engine, encryption as a service through the transit engine, SSH certificate authorities, JWT/OIDC issuance, and TOTP. Identity is unified through pluggable auth methods - userpass, AppRole, JWT/OIDC, Kubernetes, LDAP, GitHub - and access is gated by ACL policies against fine-grained paths. The Web UI ships built in. State is held in a pluggable storage backend: file, integrated raft, or external. MPL-2.0 license, fully auditable, no vendor lock-in.
Why self-host OpenBao
Secrets are the highest-value data in any infrastructure - database passwords, API tokens, signing keys, customer-data encryption keys. Sending them to a managed third-party vault means trusting an external operator with the keys to your kingdom. Self-hosting OpenBao keeps every secret inside your own tenant, lets you align with data residency requirements such as GDPR, HIPAA and ISO 27001, and removes per-token and per-request fees typical of managed offerings. The MPL-2.0 license guarantees you can audit every line of code and avoid vendor lock-in.
What this VM image adds
Security hardening:
- API on loopback only - OpenBao binds to 127.0.0.1:8200 and is reachable only through the Nginx reverse proxy on TCP 443 with TLS
- Auto-initialised at first boot - 5 unseal key shares with threshold 3; initial root token plus all 5 unseal keys written to /root/openbao-credentials.txt (mode 0600, root-only)
- Auto-unseal on every reboot - root-only cached subset of unseal keys at /var/lib/openbao/.unseal-keys; operators do not have to SSH in and unseal manually after a reboot
- Production migration path documented - revoke the root token, replace the TLS certificate, move to KMS or Transit auto-unseal, delete the on-disk cache; the full checklist ships inside the credentials file
- Nginx reverse proxy - TLS with HTTP-to-HTTPS redirect, security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy), long-poll timeouts tuned for OpenBao blocking endpoints
- UFW firewall - only TCP 22, 80 and 443 are exposed; OpenBao on TCP 8200 stays loopback-only; Azure IMDS and WireServer egress pre-configured
- fail2ban - SSH brute-force protection
- AppArmor - mandatory access control
- CVE scan - every image is scanned with Trivy before release
OS hardening (CIS Level 1):
- CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
- auditd for system call auditing of critical paths
- SSH hardening - PasswordAuthentication disabled, key-only access, PermitRootLogin no, LoginGraceTime 60
- Kernel hardening - SYN cookies, ASLR, rp_filter, kexec disabled, IPv6 off
- /tmp as tmpfs with nosuid, nodev, noexec
Compliance artifacts (inside the VM):
- SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json with OpenBao pinned by version, PURL, MPL-2.0 license, supplier, and SHA-256 hash of the binary
- CIS Conformance Report at /etc/lynxroute/cis-report.html (OpenSCAP, Azure tailoring profile, 0 FAIL rules)
- Tailored CIS profile at /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
- Operator credentials file at /root/openbao-credentials.txt (mode 0600) with the initial root token, all 5 unseal keys, the Web UI URL, and the production migration checklist
Quick Start
- Deploy VM from Azure Marketplace (Standard_D2s_v3 recommended, Standard_B2s minimum)
- Open NSG: TCP 443 from your operator network; TCP 22 from your management IPs only
- SSH: ssh -i key.pem azureuser@<PUBLIC_IP>, then sudo cat /root/openbao-credentials.txt for the initial root token and unseal keys
- Open https://<PUBLIC_IP>/ and accept the self-signed certificate warning
- Sign in with the initial root token; enable userpass / AppRole / OIDC, create scoped tokens, then revoke the root token
- Replace the self-signed TLS certificate with sudo certbot --nginx -d YOUR_DOMAIN and migrate to KMS or Transit auto-unseal before production, then delete /var/lib/openbao/.unseal-keys