--- title: "OIDC for S3 Keycloak Guide" slug: "oidc-for-s3-keycloak-guide" description: "Configure OIDC-based STS federation with Keycloak as your identity provider. Follow this guide for Keycloak-specific differences from Azure Entra ID." updated: 2026-10-28T20:02:03Z published: 2026-10-28T20:02:03Z canonical: "docs.vastdata.com/oidc-for-s3-keycloak-guide" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.vastdata.com/llms.txt > Use this file to discover all available pages before exploring further. # OIDC for S3 Keycloak Guide This guide covers configuring OIDC-based STS federation using Keycloak as the identity provider. It follows the same process as the Azure Entra ID guide, highlighting differences where they occur. > **Prerequisite:** Read the main [OIDC S3 Federation Guide](/kb/docs/oidc-s3-federation-guide-for-vast-with-azure-entra-id) first. This document only covers Keycloak-specific differences. --- ## Concept Mapping: Azure vs Keycloak | Concept | Azure Entra ID | Keycloak | | --- | --- | --- | | Identity provider instance | Azure Tenant | Realm | | Application definition | App Registration | Client | | Application identifier | Application (Client) ID | Client ID | | User directory | Azure AD | Realm Users | | Admin interface | Azure Portal | Keycloak Admin Console | --- ## Configuration Variables (Keycloak) ```bash # Keycloak Configuration KEYCLOAK_HOST="keycloak.example.com" KEYCLOAK_REALM="vast-federation" KEYCLOAK_CLIENT_ID="vast-oidc-client" # VAST Configuration (same as Azure guide) VAST_TENANT_NAME="" VAST_TENANT_ID= VAST_VIP="" ``` --- ## Step 1: Create Keycloak Client *Parallels Azure Step 1: Create App Registration* ### 1.1 Access Keycloak Admin Console Navigate to: `<https://<KEYCLOAK_HOST>>/admin/` Log in with admin credentials. ### 1.2 Select or Create a Realm 1. From the realm dropdown (top-left), select your realm or create a new one 2. Note the realm name - this is your `KEYCLOAK_REALM` **Validate**: Realm name appears in the top-left dropdown. ### 1.3 Create a Client 1. Navigate to **Clients** → **Create client** 2. Set the following: - **Client type**: OpenID Connect - **Client ID**: `vast-oidc-client` (this is your `KEYCLOAK_CLIENT_ID`) 3. Click **Next** ### 1.4 Configure Client Authentication 1. **Client authentication**: OFF (public client, like Azure's public client flow) 2. **Authorization**: OFF 3. **Authentication flow**: Check **Standard flow** and **Direct access grants** 4. Click **Next**, then **Save** **Validate**: Client appears in the Clients list. > **Azure equivalent**: This is similar to enabling "public client flows" (`--is-fallback-public-client true`) in Azure. ### 1.5 Enable Device Code Flow (Optional) If you want to use device code flow (like Azure's device login): 1. Navigate to **Realm settings** → **Login** 2. Enable **OAuth 2.0 Device Authorization Grant** Alternatively, use **Direct Access Grants** (resource owner password) for testing. ### 1.6 Record the Discovery URL ```plaintext https:///realms//.well-known/openid-configuration ``` **Validate**: Open this URL in a browser - you should see JSON with `issuer`, `authorization_endpoint`, `jwks_uri`. > **Key difference from Azure**: > > - Azure: `<https://login.microsoftonline.com/<TENANT>>/v2.0/.well-known/openid-configuration` > - Keycloak: `<https://<KEYCLOAK_HOST>>/realms/<REALM>/.well-known/openid-configuration` --- ## Step 2: Create OIDC Provider on VAST *Same process as Azure, different URL* ```bash vcli: admin> oidc create \  --name "keycloak-oidc" \  --discovery-url "https:///realms//.well-known/openid-configuration" \  --user-jwt-attribute "email" ``` **Validate**: `vcli: oidc list` shows State = `OK` > **Note**: Keycloak must be reachable from the VAST cluster. If using self-signed certificates, ensure VAST trusts the CA. --- ## Steps 3-5: VAST Configuration *Identical to the Azure guide* - Step 3: Associate OIDC Provider with Tenant (Web UI) - Step 4: Ensure Tenant Has a VIP Pool - Step 5: Create Identity Policy No changes needed - follow the main guide. --- ## Step 6: Create IAM Role with Trust Policy *Same process, different* `iss` format The trust policy must match Keycloak's `iss` claim format: | Provider | `iss` claim format | Trust policy `Principal.Federated` | | --- | --- | --- | | Azure v2.0 | `<https://login.microsoftonline.com/<TENANT>>/v2.0` | `oidc-provider/login.microsoftonline.com/<TENANT>/v2.0` | | Keycloak | `<https://<KEYCLOAK_HOST>>/realms/<REALM>` | `oidc-provider/<KEYCLOAK_HOST>/realms/<REALM>` | ### 6.1 Create the IAM Role ```bash vcli: admin> iamrole create \  --name "keycloak-s3-role" \  --tenant-id \  --description "Role for Keycloak OIDC federated S3 access" \  --identity-policies-ids \  --trust-policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Federated":"oidc-provider//realms/"},"Action":"sts:AssumeRoleWithWebIdentity","Condition":{"StringEquals":{"/realms/:aud":""}}}]}' ``` **Example with real values:** ```bash vcli: admin> iamrole create \  --name "keycloak-s3-role" \  --tenant-id 1 \  --description "Role for Keycloak OIDC federated S3 access" \  --identity-policies-ids 5 \  --trust-policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Federated":"oidc-provider/keycloak.example.com/realms/vast-federation"},"Action":"sts:AssumeRoleWithWebIdentity","Condition":{"StringEquals":{"keycloak.example.com/realms/vast-federation:aud":"vast-oidc-client"}}}]}' ``` --- ## Step 7: Create S3 Bucket *Identical to the Azure guide* No changes needed - follow the main guide. --- ## Step 8: Authenticate and Get JWT Token *Different authentication endpoints* ### Option A: Direct Access Grants (Password Flow) This is the simplest method for testing (requires user credentials): ```bash curl -s -X POST \  -H "Content-Type: application/x-www-form-urlencoded" \  -d "client_id=" \  -d "username=" \  -d "password=" \  -d "grant_type=password" \  -d "scope=openid" \  "https:///realms//protocol/openid-connect/token" ``` **Validate**: Response contains `id_token`, `access_token`, etc. Extract the `id_token`: ```bash echo "$TOKEN_RESPONSE" | jq -r .id_token > /tmp/jwt_token.txt ``` ### Option B: Device Code Flow If device authorization is enabled in Keycloak: **8.1 Request device code:** ```bash curl -s -X POST \  -H "Content-Type: application/x-www-form-urlencoded" \  -d "client_id=" \  -d "scope=openid" \  "https:///realms//protocol/openid-connect/auth/device" ``` **Validate**: Response contains `device_code`, `user_code`, `verification_uri`. **8.2 User authenticates:** 1. Open the `verification_uri` in a browser 2. Enter the `user_code` 3. Log in and approve **8.3 Exchange for token:** ```bash curl -s -X POST \  -H "Content-Type: application/x-www-form-urlencoded" \  -d "client_id=" \  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \  -d "device_code=" \  "https:///realms//protocol/openid-connect/token" ``` ### 8.4 Verify Token Claims ```bash cat /tmp/jwt_token.txt | cut -d'.' -f2 | base64 -d 2>/dev/null | jq . ``` **Validate** that these claims match your configuration: | Claim | Expected Value | | --- | --- | | `iss` | `<https://<KEYCLOAK_HOST>>/realms/<KEYCLOAK_REALM>` | | `aud` | `<KEYCLOAK_CLIENT_ID>` | | `exp` | Unix timestamp in the future | > **Key difference from Azure**: > > - Azure `iss`: `<https://login.microsoftonline.com/<TENANT>>/v2.0` > - Keycloak `iss`: `<https://<KEYCLOAK_HOST>>/realms/<REALM>` --- ## Steps 9-10: Assume Role and Test S3 *Same process, different role ARN* ### 9.1 Assume Role ```bash aws sts assume-role-with-web-identity \  --duration-seconds 900 \  --role-arn "arn:vast:::role/keycloak-s3-role" \  --role-session-name "keycloak-test" \  --web-identity-token "$(cat /tmp/jwt_token.txt)" \  --endpoint-url "https://" \  --no-verify-ssl ``` ### 9.2 Export and Test Follow the main guide Steps 9.2-9.3 and Step 10 - the process is identical once you have the STS credentials. --- ## Keycloak-Specific Troubleshooting ### "InvalidIdentityToken" with Keycloak **Common causes:** 1. **Self-signed certificate not trusted** If Keycloak uses a self-signed cert, VAST may fail to fetch the JWKS. **Check**: `vcli: oidc list` - if State is not `OK`, there may be a certificate issue. 2. `aud` claim doesn't match Keycloak's default `aud` claim contains the client ID. Verify: ```bash cat /tmp/jwt_token.txt | cut -d'.' -f2 | base64 -d 2>/dev/null | jq '.aud' ``` This might be a string or an array. The trust policy condition must match exactly. 3. **Realm name case sensitivity** Keycloak realm names are case-sensitive. Ensure the realm name in your discovery URL and trust policy match exactly. ### Keycloak Token Lifetime Configure token lifetimes in Keycloak Admin Console: 1. Navigate to **Realm settings** → **Tokens** 2. Adjust: - **Access Token Lifespan**: Default 5 minutes (consider increasing for testing). - **SSO Session Idle**: How long before re-authentication is required. --- ## Quick Reference: Azure vs Keycloak | Configuration Item | Azure Entra ID | Keycloak | | --- | --- | --- | | Discovery URL | `<https://login.microsoftonline.com/<TENANT>>/v2.0/.well-known/openid-configuration` | `<https://<HOST>>/realms/<REALM>/.well-known/openid-configuration` | | `iss` claim | `<https://login.microsoftonline.com/<TENANT>>/v2.0` | `<https://<HOST>>/realms/<REALM>` | | `aud` claim | Azure App ID (GUID) | Keycloak Client ID (string) | | Trust policy principal | `oidc-provider/login.microsoftonline.com/<TENANT>/v2.0` | `oidc-provider/<HOST>/realms/<REALM>` | | Device code endpoint | `oauth2/v2.0/devicecode` | `protocol/openid-connect/auth/device` | | Token endpoint | `oauth2/v2.0/token` | `protocol/openid-connect/token` | | Public client setting | `--is-fallback-public-client true` | Client authentication = OFF | | Admin interface | Azure Portal | Keycloak Admin Console |