Skip to main content

OpenBao Auto-Unseal with GCP KMS

OpenBao is configured to automatically unseal using Google Cloud KMS.


Overview

PropertyValue
Seal Typegcpckms
Recovery Seal Typeshamir
GCP Projectravenhelm-agent-studio-dev
Key Ringopenbao-keyring
Crypto Keyopenbao-unseal-key
Locationglobal

How It Works

  1. On startup, OpenBao contacts GCP KMS
  2. GCP KMS decrypts the root key using the crypto key
  3. OpenBao automatically unseals without manual intervention
  4. The original Shamir keys are now recovery keys
┌─────────────────┐         ┌─────────────────┐
│ OpenBao │ ──────> │ GCP KMS │
│ (sealed) │ │ │
│ │ <────── │ Decrypt key │
│ │ │ │
│ (unsealed) │ └─────────────────┘
└─────────────────┘

Recovery Keys

After auto-unseal migration, the original unseal keys become recovery keys:

PropertyValue
1Password Item"OpenBao Root Keys"
Total Keys5
Threshold3
PurposeEmergency recovery, root token generation

When to Use Recovery Keys:

  • Generate new root token if lost
  • Recover if GCP KMS is unavailable
  • Disaster recovery scenarios

Configuration

config.hcl

seal "gcpckms" {
project = "ravenhelm-agent-studio-dev"
region = "global"
key_ring = "openbao-keyring"
crypto_key = "openbao-unseal-key"
}

docker-compose.yml

services:
openbao:
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/openbao/gcp-credentials.json
volumes:
- /Users/ravenhelm/ravenhelm/secrets/gcp-openbao.json:/openbao/gcp-credentials.json:ro

GCP Resources

Service Account

PropertyValue
Emailravenmask@ravenhelm-agent-studio-dev.iam.gserviceaccount.com
Key Location~/ravenhelm/secrets/gcp-openbao.json
1Password"GCP Service Account - ravenmask"

IAM Permissions

The service account has these roles on the crypto key:

RolePurpose
roles/cloudkms.cryptoKeyEncrypterDecrypterEncrypt/decrypt root key
roles/cloudkms.viewerRead key metadata

Verification

# Check seal type
ssh ravenhelm@100.115.101.81 "docker exec openbao bao status" | grep -E "Seal Type|Sealed"

# Expected output:
# Seal Type gcpckms
# Sealed false

Testing Auto-Unseal

# Restart the container
ssh ravenhelm@100.115.101.81 "cd ~/ravenhelm/services/openbao && docker compose restart openbao"

# Wait and check status
sleep 10
ssh ravenhelm@100.115.101.81 "docker exec openbao bao status"

# Should show Sealed: false

Troubleshooting

GCP Permission Denied

Symptom: Permission 'cloudkms.cryptoKeys.get' denied

Resolution:

gcloud kms keys add-iam-policy-binding openbao-unseal-key \
--location=global \
--keyring=openbao-keyring \
--member="serviceAccount:ravenmask@ravenhelm-agent-studio-dev.iam.gserviceaccount.com" \
--role="roles/cloudkms.viewer" \
--project=ravenhelm-agent-studio-dev

GCP Credentials Not Found

Symptom: could not find default credentials

Resolution:

  1. Verify credentials file exists: ls -la ~/ravenhelm/secrets/gcp-openbao.json
  2. Check docker-compose mounts the file correctly
  3. Verify GOOGLE_APPLICATION_CREDENTIALS environment variable

Fallback to Manual Unseal

If GCP KMS is unavailable, use recovery keys:

KEY1=$(op item get "OpenBao Root Keys" --vault ravenmask --fields "Unseal Key 1" --reveal)
KEY2=$(op item get "OpenBao Root Keys" --vault ravenmask --fields "Unseal Key 2" --reveal)
KEY3=$(op item get "OpenBao Root Keys" --vault ravenmask --fields "Unseal Key 3" --reveal)

ssh ravenhelm@100.115.101.81 "docker exec openbao bao operator unseal -recovery $KEY1"
ssh ravenhelm@100.115.101.81 "docker exec openbao bao operator unseal -recovery $KEY2"
ssh ravenhelm@100.115.101.81 "docker exec openbao bao operator unseal -recovery $KEY3"

Container Won't Start

Symptom: Container crashes with KMS errors

Check logs:

ssh ravenhelm@100.115.101.81 "docker logs openbao 2>&1 | tail -30"

Common issues:

  • GCP credentials file missing or empty
  • Wrong project/keyring/key name in config
  • Service account lacks permissions

GCP KMS Key Rotation

GCP KMS handles key rotation automatically. The crypto key can have multiple versions, and GCP will use the primary version for encryption while all versions can decrypt.

To rotate the key:

gcloud kms keys versions create \
--key=openbao-unseal-key \
--keyring=openbao-keyring \
--location=global \
--project=ravenhelm-agent-studio-dev \
--primary

OpenBao doesn't need to be restarted for key rotation.


Migrating Back to Shamir

To disable auto-unseal and return to Shamir (not recommended):

  1. Remove seal stanza from config.hcl
  2. Restart with -migrate flag
  3. Use recovery keys to unseal during migration
  4. Recovery keys become unseal keys again