Home / Docs / DCA Hardened Secrets Manager — for OpenBao™ / Configuration
OpenBao 2.7 initialized on each VM's first boot with its own Shamir unseal keys, root token and TLS certificate, behind a loopback TLS listener.
On this page: Installed version · First-boot credentials · Log in · Unsealing (Shamir: 5 shares, 3 needed) · Network access · Data and logs · Upgrades · Backup and restore
OpenBao 2.7.1 — the upstream linux_amd64 release binary, verified when the image was built against the release's GPG-signed checksums.txt (OpenBao release key) and a pinned sha256, installed as /usr/local/bin/bao. Storage is integrated raft. The server runs as the openbao user under openbao.service. Base OS: Ubuntu 24.04 LTS. Image built 2026-10-07; every build is gated on zero fixable HIGH or CRITICAL vulnerability findings, including the Go standard library.
bao versionNothing secret ships in the image. On this VM's first boot, openbao-firstboot.service creates the TLS key and certificate for the listener; then openbao-init-firstboot initializes OpenBao with 5 Shamir key shares and a threshold of 3, writes the unseal keys and root token to a root-only file, unseals the server, and proves that the root token works and a bogus token is refused.
| File | Owner / mode | Contents |
|---|---|---|
/root/openbao-init.json | root:root 0600 | unseal_keys_b64 (5 keys), unseal_keys_hex, unseal_threshold (3), root_token, and a _SECURITY_NOTICE |
/etc/openbao/tls/tls.key | root:openbao 0640 | Private key (EC P-256) of this VM's self-signed certificate |
/etc/openbao/tls/tls.crt | root:openbao 0644 | The certificate, valid 10 years. Subject alternative names: localhost, 127.0.0.1, ::1, the short hostname, and the VM's internal DNS name and internal IP as read from the metadata server at first boot |
/etc/profile.d/openbao.sh | 0644 | Sets BAO_ADDR=https://127.0.0.1:8200 and BAO_CACERT=/etc/openbao/tls/tls.crt for login shells |
Then do what the file's notice says: move it to a secure secret store, give the unseal keys to separate people, create named admin identities and policies, and revoke the root token (bao token revoke). bao operator rekey replaces the unseal keys if you want new ones.
gcloud compute ssh INSTANCE_NAME --zone ZONE --tunnel-through-iap. The deployment package enables OS Login, so IAM decides who can SSH in; reading the credential files needs sudo, which OS Login grants to principals with the OS Admin Login role (roles/compute.osAdminLogin). IAP TCP forwarding needs a firewall rule that allows 35.235.240.0/20 to tcp:22 on the VM's network — the deployment package does not create one.bao status # Initialized true, Sealed false
export BAO_TOKEN="$(sudo python3 -c 'import json; print(json.load(open("/root/openbao-init.json"))["root_token"])')"
bao token lookupui = true). Forward the port, open https://localhost:8200/ui/ and sign in with the Token method. Your browser warns about the certificate because it is this VM's own self-signed one (/etc/openbao/tls/tls.crt).gcloud compute ssh INSTANCE_NAME --zone ZONE --tunnel-through-iap -- -L 8200:127.0.0.1:8200OpenBao starts sealed after every systemctl restart openbao and every reboot — upstream behaviour for a Shamir seal. The image deliberately does not unseal itself from keys stored next to the data, because that would make the seal meaningless. While sealed it serves nothing but status: bao status shows Sealed true.
sudo openbao-unseal submits the threshold of keys from /root/openbao-init.json, or from an init file you name: sudo openbao-unseal /path/to/init.json.bao operator unseal and enter their key.sudo openbao-unseal
# or, three times, each with a different key from your store:
bao operator unsealFor unattended restarts, let a Cloud KMS key protect OpenBao's root key instead (the gcpckms seal). It is an option you set up, not a default, because it needs a key and IAM in your project.
gcloud kms keyrings create openbao --location us-central1
gcloud kms keys create unseal --keyring openbao --location us-central1 --purpose encryptioncloud-platform scope (or attach a dedicated service account), start it, and grant that account the encrypter/decrypter role on the key:gcloud compute instances stop VM --zone ZONE
gcloud compute instances set-service-account VM --zone ZONE \
--service-account SA_EMAIL --scopes cloud-platform
gcloud compute instances start VM --zone ZONE
gcloud kms keys add-iam-policy-binding unseal --keyring openbao --location us-central1 \
--member serviceAccount:SA_EMAIL --role roles/cloudkms.cryptoKeyEncrypterDecrypter/etc/openbao/openbao.hcl (sudo):seal "gcpckms" {
project = "PROJECT_ID"
region = "us-central1"
key_ring = "openbao"
crypto_key = "unseal"
}-migrate:sudo systemctl restart openbao
bao operator unseal -migrate # three times, one key eachcloudkms.googleapis.com (through the default ephemeral external IP, or Private Google Access or Cloud NAT if you removed it). Losing access to the KMS key means losing access to the data.| Port | Bound to | Deployment package |
|---|---|---|
| 8200 (API + UI, TLS) | 127.0.0.1 — the listener "tcp" block in /etc/openbao/openbao.hcl | tcp:8200 toggle, off by default |
| 8201 (cluster) | 127.0.0.1 | none (single node) |
| 22 (SSH) | all interfaces | no rule — your VPC's own firewall rules apply |
To serve clients on your VPC:
/etc/openbao/openbao.hcl (sudo): set the listener address to 0.0.0.0:8200 and api_addr to the address clients will use. 0.0.0.0 keeps 127.0.0.1 working, which sudo openbao-unseal and the pre-set BAO_ADDR rely on; if you bind only the internal IP, point BAO_ADDR at it and unseal with bao operator unseal.api_addr = "https://10.128.0.5:8200" # your VM's internal IP or DNS name
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "127.0.0.1:8201"
tls_cert_file = "/etc/openbao/tls/tls.crt"
tls_key_file = "/etc/openbao/tls/tls.key"
}sudo systemctl restart openbao
sudo openbao-unsealDEPLOYMENT-tcp-8200, allowing tcp:8200 from those ranges to VMs tagged DEPLOYMENT-deployment (DEPLOYMENT is your deployment name; the VM is DEPLOYMENT-vm). Use the narrowest ranges that work — 0.0.0.0/0, which the field shows only as a format example, would publish the port through the VM's external IP. Already deployed without the toggle? Create the same rule yourself:gcloud compute firewall-rules create DEPLOYMENT-tcp-8200 \
--network NETWORK --direction INGRESS --allow tcp:8200 \
--source-ranges 10.10.0.0/24 --target-tags DEPLOYMENT-deployment/etc/openbao/tls/tls.crt to the client. Or install a certificate from your own CA at the same two paths (key owned root:openbao, mode 0640) and restart.export BAO_ADDR=https://10.128.0.5:8200
export BAO_CACERT=/path/to/tls.crt
bao statusdefault network that still has its pre-created default-allow-internal rule (all ports from 10.128.0.0/9), every VM in that network can connect as soon as the service listens on the internal IP — toggle or not. And the deployment package gives the VM an ephemeral external IP by default (its External IP field), so a rule open to 0.0.0.0/0 would put the service on the internet. Put authentication in place first, then open the narrowest range that works.To renew the self-signed certificate (for example after changing the VM's internal IP or hostname), delete it and let the first-boot unit mint a new one: sudo rm /etc/openbao/tls/tls.key /etc/openbao/tls/tls.crt && sudo systemctl restart openbao-firstboot openbao && sudo openbao-unseal.
| What | Where |
|---|---|
| Storage (integrated raft) | /var/lib/openbao/raft (openbao, 0700) |
| Logs | the systemd journal — journalctl -u openbao -f. No audit device is enabled by default; enable one with bao audit enable if you need an audit trail |
| Configuration | /etc/openbao/openbao.hcl (root:openbao 0640) |
| Disk | The deployment package creates one boot disk (default 50 GB, balanced persistent disk) and no separate data disk, so the data above lives on the boot disk — size it for your data, or mount a persistent disk at the data path. |
bao operator raft snapshot save), and restore it on the new one with bao operator raft snapshot restore -force. After that the new VM holds the old data and is unsealed with the OLD VM's unseal keys.apt nor unattended-upgrades (enabled, for Ubuntu's own updates) ever changes it. Take a snapshot, download the newer linux_amd64 release and its signed checksums.txt from OpenBao's GitHub releases, verify them, replace /usr/local/bin/bao, sudo systemctl restart openbao, and unseal. Read OpenBao's release notes first.bao operator raft snapshot save openbao.snap with a token allowed to take snapshots (the root token can), then copy the file off the VM. Snapshots are encrypted by OpenBao itself: restoring one needs the unseal keys that were current when it was taken. A boot-disk snapshot works too.
bao status → Initialized true, Sealed false — wire this into an uptime check or your monitoring agent.google-logging-enable=0, google-monitoring-enable=0), and the image pre-installs no monitoring agent. Install the Google Cloud Ops Agent if you want logs and metrics in Cloud Logging and Cloud Monitoring; nothing phones home by default.More: install · troubleshooting · security notes · support card. Questions: support@dcassociatesgroup.com — first response within 1 business day.
OpenBao™ names the open-source software this image packages. Derek Coleman & Associates Inc is not affiliated with or endorsed by the OpenBao project.