Authenticate HashiCorp Vault to Keycloak via OIDC

This guide shows how to integrate HashiCorp Vault with Keycloak using OIDC (OpenID Connect) for authentication, using a Vault role named default with limited, safe permissions.


Related Setup Guides

Before starting, make sure you have both services installed and accessible:


Prerequisites

  • Vault is initialized, unsealed, and reachable (e.g., https://vault.maksonlee.com)
  • Keycloak is running with:
    A realm (e.g., maksonlee.com)
    At least one user account

  1. Create a Keycloak Client for Vault

To allow Vault to authenticate users via Keycloak, you need to create a confidential OpenID Connect (OIDC) client in your Keycloak realm.

Follow these steps in the Keycloak Admin Console:

  1. General Settings
  • Go to Clients → Create Client
  • Set
    Client type: OpenID Connect
    Client ID: vault
    Name: vault
    Leave Description blank or enter a note
    Keep Always display in UI turned ON
  • Click Next
  1. Capability Config
  • Client authentication: On
  • Authorization: Off
  • Authentication flow: Check only Standard flow
  • Do not enable:
    Implicit flow
    Direct access grants
    Service accounts
    Token Exchange
    CIBA, Device Grant, etc.
  • Click Next
  1. Login Settings
  • Root URL:
https://vault.maksonlee.com
  • Home URL:
https://vault.maksonlee.com
  • Valid Redirect URIs:
https://vault.maksonlee.com/ui/vault/auth/oidc/oidc/callback
  • Leave the rest empty (unless needed for logout redirect or Web origins)
  • Click Save
  1. Get the Client Secret

After saving:

  • Go to the Credentials tab
  • Copy the Client Secret — you’ll use this in Vault’s OIDC config

  1. Configure Vault to Use OIDC with Keycloak

Switch to your Vault server terminal:

  • Enable OIDC Auth Method
vault auth enable oidc
  • Set OIDC Config with Keycloak

Replace <client-secret> with the secret from Keycloak:

vault write auth/oidc/config \
  oidc_discovery_url="https://keycloak.maksonlee.com/realms/maksonlee.com" \
  oidc_client_id="vault" \
  oidc_client_secret="<client-secret>" \
  default_role="default"

  1. Create the default Role

This role is not built-in, you must define it manually.

vault write auth/oidc/role/default \
  user_claim="preferred_username" \
  allowed_redirect_uris="https://vault.maksonlee.com/ui/vault/auth/oidc/oidc/callback" \
  bound_audiences="vault" \
  token_policies="default" \
  ttl="1h"

It maps authenticated users to the built-in default Vault policy, no access to secrets by default

vault policy read default
# Allow tokens to look up their own properties
path "auth/token/lookup-self" {
    capabilities = ["read"]
}

# Allow tokens to renew themselves
path "auth/token/renew-self" {
    capabilities = ["update"]
}

# Allow tokens to revoke themselves
path "auth/token/revoke-self" {
    capabilities = ["update"]
}

# Allow a token to look up its own capabilities on a path
path "sys/capabilities-self" {
    capabilities = ["update"]
}

# Allow a token to look up its own entity by id or name
path "identity/entity/id/{{identity.entity.id}}" {
  capabilities = ["read"]
}
path "identity/entity/name/{{identity.entity.name}}" {
  capabilities = ["read"]
}


# Allow a token to look up its resultant ACL from all policies. This is useful
# for UIs. It is an internal path because the format may change at any time
# based on how the internal ACL features and capabilities change.
path "sys/internal/ui/resultant-acl" {
    capabilities = ["read"]
}

# Allow a token to renew a lease via lease_id in the request body; old path for
# old clients, new path for newer
path "sys/renew" {
    capabilities = ["update"]
}
path "sys/leases/renew" {
    capabilities = ["update"]
}

# Allow looking up lease properties. This requires knowing the lease ID ahead
# of time and does not divulge any sensitive information.
path "sys/leases/lookup" {
    capabilities = ["update"]
}

# Allow a token to manage its own cubbyhole
path "cubbyhole/*" {
    capabilities = ["create", "read", "update", "delete", "list"]
}

# Allow a token to wrap arbitrary values in a response-wrapping token
path "sys/wrapping/wrap" {
    capabilities = ["update"]
}

# Allow a token to look up the creation time and TTL of a given
# response-wrapping token
path "sys/wrapping/lookup" {
    capabilities = ["update"]
}

# Allow a token to unwrap a response-wrapping token. This is a convenience to
# avoid client token swapping since this is also part of the response wrapping
# policy.
path "sys/wrapping/unwrap" {
    capabilities = ["update"]
}

# Allow general purpose tools
path "sys/tools/hash" {
    capabilities = ["update"]
}
path "sys/tools/hash/*" {
    capabilities = ["update"]
}

# Allow checking the status of a Control Group request if the user has the
# accessor
path "sys/control-group/request" {
    capabilities = ["update"]
}

# Allow a token to make requests to the Authorization Endpoint for OIDC providers.
path "identity/oidc/provider/+/authorize" {
    capabilities = ["read", "update"]
}

  1. Log in via Vault Web UI
  • Visit https://vault.maksonlee.com
  • In the login method dropdown, select OIDC
  • You will be redirected to Keycloak
  • Log in with your Keycloak username and password
  • You will be redirected back and logged into Vault

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top