Skip to main content

OpenBao OIDC Authentication

OIDC authentication for human access to OpenBao UI via Zitadel SSO.


Overview

OpenBao is configured to authenticate users via OIDC using Zitadel as the identity provider. This allows users to login to the OpenBao UI using their existing Zitadel credentials (Google SSO).

PropertyValue
Auth MethodOIDC
Identity ProviderZitadel
Issuerhttps://auth.ravenhelm.dev
Client ID354205344844546083
1Password ItemOpenBao OIDC - Zitadel
Default Roledefault
Token Policyadmin
Token TTL1 hour (max 4 hours)

How to Login

Web UI

  1. Navigate to vault.ravenhelm.dev
  2. In the "Method" dropdown, select OIDC
  3. Leave "Role" as default
  4. Click Sign in with OIDC provider
  5. You'll be redirected to Zitadel
  6. Authenticate with Google (or your Zitadel credentials)
  7. You'll be redirected back to OpenBao, now logged in

CLI (Local Machine)

# Login via OIDC (opens browser)
export VAULT_ADDR=https://vault.ravenhelm.dev
bao login -method=oidc

# This opens a browser window for authentication
# After auth, you'll have a token in ~/.vault-token

Configuration Details

Zitadel Application

The OIDC application was created in Zitadel's "Ravenhelm" project:

PropertyValue
App ID354205344844480547
Client ID354205344844546083
App TypeWeb
Auth MethodBasic (client secret)
Response TypesCode
Grant TypesAuthorization Code

Redirect URIs:

  • https://vault.ravenhelm.dev/ui/vault/auth/oidc/oidc/callback (UI)
  • http://localhost:8250/oidc/callback (CLI)

Post-Logout Redirect:

  • https://vault.ravenhelm.dev

OpenBao OIDC Config

# View OIDC configuration
ROOT_TOKEN=$(op item get "OpenBao Root Keys" --vault ravenmask --fields "Root Token" --reveal)
ssh ravenhelm@100.115.101.81 "docker exec -e BAO_TOKEN=$ROOT_TOKEN openbao bao read auth/oidc/config"

Output:

Key                   Value
--- -----
default_role default
oidc_client_id 354205344844546083
oidc_discovery_url https://auth.ravenhelm.dev
status valid

OIDC Role Configuration

# View default role
ssh ravenhelm@100.115.101.81 "docker exec -e BAO_TOKEN=$ROOT_TOKEN openbao bao read auth/oidc/role/default"

Key settings:

  • allowed_redirect_uris: UI and CLI callbacks
  • bound_audiences: Client ID
  • token_policies: admin
  • token_ttl: 1 hour
  • token_max_ttl: 4 hours
  • user_claim: sub

Token Management

Token TTL

OIDC tokens have:

  • Initial TTL: 1 hour
  • Max TTL: 4 hours

Tokens can be renewed before expiry up to the max TTL.

Renew Token

# Via CLI
bao token renew

# Via API
curl -X POST -H "X-Vault-Token: $TOKEN" \
https://vault.ravenhelm.dev/v1/auth/token/renew-self

Check Token Info

# Via CLI
bao token lookup

# Via API
curl -H "X-Vault-Token: $TOKEN" \
https://vault.ravenhelm.dev/v1/auth/token/lookup-self

Permissions

Users authenticated via OIDC receive the admin policy, which grants full access:

path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

This allows:

  • Reading/writing all secrets
  • Managing policies
  • Managing auth methods
  • Administrative operations

Troubleshooting

"Invalid redirect URI"

Symptom: Error during OIDC login about redirect URI

Cause: The callback URL doesn't match what's configured in Zitadel

Resolution: Verify redirect URIs in Zitadel match exactly:

  • UI: https://vault.ravenhelm.dev/ui/vault/auth/oidc/oidc/callback
  • CLI: http://localhost:8250/oidc/callback

"Invalid client credentials"

Symptom: Authentication fails with client credential error

Cause: Client secret may have changed or been rotated

Resolution:

  1. Get current credentials from 1Password: OpenBao OIDC - Zitadel
  2. Update OpenBao OIDC config:
ssh ravenhelm@100.115.101.81 "docker exec -e BAO_TOKEN=$ROOT_TOKEN openbao bao write auth/oidc/config \
oidc_discovery_url='https://auth.ravenhelm.dev' \
oidc_client_id='CLIENT_ID' \
oidc_client_secret='NEW_SECRET' \
default_role='default'"

"OIDC discovery failed"

Symptom: OpenBao can't reach Zitadel discovery endpoint

Cause: Network issue or Zitadel unavailable

Resolution:

  1. Check Zitadel is running: curl https://auth.ravenhelm.dev/.well-known/openid-configuration
  2. Check OpenBao container can reach Zitadel
  3. Use root token for emergency access

Token Expired

Symptom: "permission denied" after some time

Cause: OIDC token has expired

Resolution: Re-authenticate via OIDC:

  1. Logout from UI
  2. Login again via OIDC
  3. Or use CLI: bao login -method=oidc

Adding Additional Roles

To create a role with limited permissions:

# 1. Create a new policy
cat > /tmp/readonly.hcl << 'EOF'
path "secret/data/*" {
capabilities = ["read", "list"]
}
EOF

scp /tmp/readonly.hcl ravenhelm@100.115.101.81:/tmp/
ssh ravenhelm@100.115.101.81 "docker cp /tmp/readonly.hcl openbao:/tmp/"
ssh ravenhelm@100.115.101.81 "docker exec -e BAO_TOKEN=$ROOT_TOKEN openbao bao policy write readonly /tmp/readonly.hcl"

# 2. Create a new OIDC role
ssh ravenhelm@100.115.101.81 "docker exec -e BAO_TOKEN=$ROOT_TOKEN openbao bao write auth/oidc/role/readonly \
bound_audiences='354205344844546083' \
allowed_redirect_uris='https://vault.ravenhelm.dev/ui/vault/auth/oidc/oidc/callback' \
user_claim='sub' \
token_policies='readonly' \
token_ttl='1h'"

Users can then select "readonly" as the role when logging in.


Security Notes

  1. Client Secret: Stored securely in OpenBao config and 1Password
  2. Token Storage: Browser stores token in session; CLI stores in ~/.vault-token
  3. SSO Flow: Uses Authorization Code flow (most secure)
  4. Token Binding: Tokens are bound to the authenticated user's sub claim