Deploy OpenBao
Store and share API keys, passwords and certificates securely
Just deployed
/var/lib/postgresql/data
openbao
Just deployed
Deploy and Host OpenBao on Railway
OpenBao is an open-source secrets manager: one audited place to keep API keys, database passwords, TLS certificates and encryption keys, and to hand them to applications over an HTTP API instead of through .env files and shared password managers. It is a community fork of HashiCorp Vault, created after Vault moved to the Business Source License, and is developed under open governance at the Linux Foundation's OpenSSF.
Deploy OpenBao on Railway and you get a working secrets manager on first boot rather than a server waiting to be initialised. The template runs two services: the OpenBao server, published on a Railway domain and serving the REST API and web UI, and a PostgreSQL database acting as its storage backend. Every secret is encrypted before it reaches Postgres, so the database holds ciphertext only. The server unseals itself at startup from a key held as a Railway variable, initialises itself on the first boot, creates an admin account and a versioned key/value store, and audits every request. Self-host OpenBao this way and there are no unseal shares to paste in after a redeploy.

Getting Started with OpenBao on Railway
Open the deployed URL and you land on the sign-in page. Change the Method dropdown from Token to Username, then sign in with the values of BAO_ADMIN_USERNAME and BAO_ADMIN_PASSWORD on the OpenBao service — that account is created during the first boot, so there is nothing to register and no default password to change. The first screen is Secrets engines, already carrying a key/value store at secret/. Open it, choose Create secret, and write a path such as apps/billing-api/production to confirm writes are reaching Postgres.
Then mint a recovery key and keep it outside the deployment — it is what issues a new root token if the admin login is lost: after bao login -method=userpass username=admin, run bao write -f sys/rotate/recovery/init secret_shares=1 secret_threshold=1. Give each application its own auth method rather than sharing the broad admin account, and enable further engines from Secrets engines → Enable new engine: transit, pki, or database.



About Hosting OpenBao
OpenBao solves a problem that grows quietly: as a system gains services, credentials multiply across CI settings, container environments and laptops, and nobody can say who read which secret or when it was rotated. OpenBao centralises them behind one API, encrypts them at rest, and records every read.
- Versioned key/value storage — every write keeps history, so a bad rotation can be rolled back.
- Dynamic secrets — a database user created on request and revoked when its lease expires, so no long-lived password can leak.
- Transit encryption — apps send plaintext and get ciphertext back; the key never leaves OpenBao.
- Built-in PKI — an internal CA issuing short-lived TLS certificates.
- Policies and identity — HCL policies scoped by path, attached to userpass, AppRole, JWT/OIDC, LDAP or Kubernetes logins.
- Audit devices — a structured request log with sensitive fields hashed.
The Railway architecture is deliberately small. The OpenBao service is the only public one and keeps nothing on disk: PostgreSQL holds the encryption barrier, mount table, tokens, leases and secrets in tables OpenBao creates on first connect. That backend is high-availability aware, which is what makes redeploys clean — the incoming container starts as a standby and takes the lock as the old one shuts down.
Why Deploy OpenBao on Railway
Railway removes the work that makes a secrets manager unpleasant to run:
- Managed PostgreSQL with backups, provisioned and wired up for you.
- Automatic unsealing on every restart — no unseal ceremony after deploys.
- HTTPS and a public domain issued automatically; the database stays private.
- Private networking between the server and its storage.
- One-click redeploys with a clean handover between containers.
Common Use Cases
- Application secrets for a whole project — services read credentials from OpenBao at boot instead of duplicating them across environments.
- Short-lived database credentials — CI jobs request a Postgres user that expires within the hour.
- Encryption-as-a-service — an app encrypts personal data through the transit engine, storing ciphertext.
- Internal PKI — short-lived TLS certificates for internal services.
Dependencies for OpenBao
- OpenBao server — built from gridalpha/openbao-railway, a thin layer over
openbao/openbao:2.6.2that renders the server configuration from environment variables at boot. API and UI on port 8200. - PostgreSQL — the storage backend, holding encrypted data only; database access alone reveals no secret without the unseal key.
Environment Variables Reference
| Variable | Required | Description |
|---|---|---|
BAO_UNSEAL_KEY | Yes | 32-byte AES-256 auto-unseal key, as 64 hex characters. Losing it makes stored data unreadable. |
BAO_ADMIN_PASSWORD | Yes | First admin's password. Read only on the first boot. |
BAO_ADMIN_USERNAME | No | That account's username. Defaults to admin. |
DATABASE_URL | Yes | Connection string, referenced from the database service. |
PORT | No | API listen port. Defaults to 8200. |
BAO_AUDIT_STDOUT | No | Audit log to the container output. Defaults to true. |
Deployment Dependencies
- Source: github.com/openbao/openbao
- Image:
openbao/openbao - Docs: openbao.org/docs
Hardware Requirements for Self-Hosting OpenBao
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 0.5 vCPU | 1–2 vCPU |
| RAM | 512 MB | 1–2 GB |
| Storage | 1 GB on PostgreSQL, none on the server | 5 GB on PostgreSQL |
| Runtime | Go binary in a container | Go binary in a container |
OpenBao is frugal: memory tracks active leases and tokens rather than stored secrets, so a small instance serves a team.
Self-Hosting OpenBao with Docker
The quickest local run is development mode, which keeps everything in memory and prints a root token — fine for trying the API, never for real data:
docker run --rm -p 8200:8200 openbao/openbao:2.6.2
A persistent instance needs a config file with a storage backend and a seal — PostgreSQL for storage, a static key for automatic unsealing:
ui = true
disable_mlock = true
api_addr = "https://bao.example.com"
storage "postgresql" {
ha_enabled = "true"
}
listener "tcp" {
address = "[::]:8200"
tls_disable = "true"
}
seal "static" {}
Supply the connection string as BAO_PG_CONNECTION_URL, a 32-byte key as BAO_STATIC_SEAL_CURRENT_KEY (64 hex characters) and a BAO_STATIC_SEAL_CURRENT_KEY_ID that changes whenever the key does. Run bao server -config=/openbao/config, then initialise once with bao operator init — or with an initialize stanza, as the template does.
How Much Does OpenBao Cost to Self-Host?
OpenBao is free and open source under the Mozilla Public License 2.0. There is no paid tier, no seat licensing and no enterprise-only feature set held back — automatic unsealing, licensed separately in Vault Enterprise, is included. On Railway you pay only for the compute and storage the two services use.
FAQ
What is OpenBao and how is it different from HashiCorp Vault? OpenBao is a secrets manager forked from Vault in 2023, after Vault's licence changed to the Business Source License. It keeps Vault's API, CLI and concepts, is MPL 2.0, and is governed by the Linux Foundation's OpenSSF rather than one vendor.
What does this Railway template deploy? Two services: the OpenBao server with its API and web UI on a public Railway domain, and a private PostgreSQL database as its storage backend. The server initialises itself on first boot, creating an admin login and a key/value store.
Why does the template include a PostgreSQL database? OpenBao has to persist its encrypted data somewhere, and PostgreSQL is a production-ready, high-availability-capable backend whose managed Railway instance brings backups. The database never sees plaintext.
Do I have to unseal OpenBao by hand after every deploy?
No. Automatic unsealing uses the key in BAO_UNSEAL_KEY, so the server unseals itself when the container starts. Keep a copy of that key safe: without it the stored data cannot be decrypted.
How do I authenticate an application against self-hosted OpenBao? Enable an auth method under Access — AppRole for machine clients, JWT/OIDC for workloads with an identity token, userpass for humans — write a policy granting only the paths that client needs, and attach it.
Can I run more than one OpenBao instance on Railway? Yes. The PostgreSQL backend supports high availability, so extra replicas start as standbys and one takes over if the active instance goes away. The template ships one because failover is the only benefit.
Template Content

