Derek Coleman & Associates Inc logoDerek Coleman & Associates Inc

Home / Docs / DCA Hardened Secrets Manager — for OpenBao™ / Configuration

Configure DCA Hardened Secrets Manager — for OpenBao™

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

Loopback only by default: the API and web UI answer over TLS on 127.0.0.1:8200 and the cluster port on 127.0.0.1:8201; nothing but SSH listens beyond loopback. OpenBao uses a Shamir seal, so it starts sealed after every restart or reboot until you unseal it — see Unsealing.

Installed version

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 version

First-boot credentials

Nothing 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.

FileOwner / modeContents
/root/openbao-init.jsonroot:root 0600unseal_keys_b64 (5 keys), unseal_keys_hex, unseal_threshold (3), root_token, and a _SECURITY_NOTICE
/etc/openbao/tls/tls.keyroot:openbao 0640Private key (EC P-256) of this VM's self-signed certificate
/etc/openbao/tls/tls.crtroot:openbao 0644The 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.sh0644Sets 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.

Log in

  1. Connect with 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.
  2. The CLI is pre-configured for login shells. Check the server, then authenticate with the root token for your first setup steps:
    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 lookup
  3. The web UI is enabled (ui = 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:8200

Unsealing (Shamir: 5 shares, 3 needed)

OpenBao 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.
  • Once the init file is off the VM, as it should be, three key holders each run bao operator unseal and enter their key.
sudo openbao-unseal
# or, three times, each with a different key from your store:
bao operator unseal

Optional: Cloud KMS auto-unseal

For 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.

  1. Create a key ring and key:
    gcloud kms keyrings create openbao --location us-central1
    gcloud kms keys create unseal --keyring openbao --location us-central1 --purpose encryption
  2. Let the VM's service account use the key. The deployment package runs the VM as the project's Compute Engine default service account with narrow access scopes (Cloud Storage read-only, Logging and Monitoring write, user accounts read-only), none of which covers Cloud KMS. Stop the VM, give it the cloud-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
  3. Add a seal stanza to /etc/openbao/openbao.hcl (sudo):
    seal "gcpckms" {
      project    = "PROJECT_ID"
      region     = "us-central1"
      key_ring   = "openbao"
      crypto_key = "unseal"
    }
  4. Restart, then migrate the seal by entering three of the existing unseal keys with -migrate:
    sudo systemctl restart openbao
    bao operator unseal -migrate      # three times, one key each
  5. From then on OpenBao unseals itself through Cloud KMS on every start, and the five Shamir keys become recovery keys — keep them. The VM must reach cloudkms.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.

Network access

PortBound toDeployment package
8200 (API + UI, TLS)127.0.0.1 — the listener "tcp" block in /etc/openbao/openbao.hcltcp:8200 toggle, off by default
8201 (cluster)127.0.0.1none (single node)
22 (SSH)all interfacesno rule — your VPC's own firewall rules apply

To serve clients on your VPC:

  1. Edit /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"
    }
  2. Restart and unseal:
    sudo systemctl restart openbao
    sudo openbao-unseal
  3. Open the port with the deployment package's firewall toggle: in its Networking section, tick "Allow TCP port 8200 traffic from the Internet" and enter your clients' CIDR ranges under "Source IP ranges for TCP port 8200 traffic". The toggle creates one VPC firewall rule, DEPLOYMENT-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
  4. Clients verify TLS against this VM's certificate, whose names already include the VM's internal IP and internal DNS name: copy /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 status
Two more things decide who can reach an opened port on Google Cloud. If the VM sits on a default 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.

Data and logs

WhatWhere
Storage (integrated raft)/var/lib/openbao/raft (openbao, 0700)
Logsthe 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)
DiskThe 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.

Upgrades

  • Recommended: deploy the newest image version, take a snapshot on the old VM (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.
  • In place: OpenBao is not an apt package on this image, so neither 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.

Backup and restore

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.

Monitoring

  • Health: bao status → Initialized true, Sealed false — wire this into an uptime check or your monitoring agent.
  • The deployment package disables the Cloud Logging and Monitoring agents in instance metadata (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.