Federating Keycloak with Microsoft Entra ID
This lab demonstrates setting up Keycloak as an Identity Provider (IDP) and federating it with Microsoft Entra ID for federated authentication.
Architecture Overview
┌─────────────────┐ Federation ┌─────────────────┐
│ │◄──────────────────►│ │
│ Keycloak │ SAML / OIDC │ Entra ID │
│ (Your IDP) │ │ (Microsoft) │
│ │ │ │
└────────┬────────┘ └─────────────────┘
│
│ Users authenticate
▼
┌─────────────────┐
│ Your Apps │
│ (SP/Client) │
└─────────────────┘Two Federation Scenarios:
- Entra as Identity Broker → Users sign in via Entra, Keycloak trusts Entra
- Keycloak as Identity Broker → Users sign in via Keycloak, which can redirect to Entra
Part 1: Deploy Keycloak on Render
Prerequisites
- Render account
- PostgreSQL database (Render managed or external)
Step 1: Create PostgreSQL Database on Render
- Go to Render Dashboard → New → PostgreSQL
- Configure:
- Name:
keycloak-db - Database:
keycloak - User:
keycloak - Region: Choose closest
- Plan: Free (for testing)
- Name:
- Note the Internal Database URL after creation
Step 2: Deploy Keycloak Web Service
New → Web Service → Build from Git
Connect your repo containing the Dockerfile
Configure:
Setting Value Name keycloakRegion Same as database Branch mainRoot Directory azure/az-104/01-identity-governance/labs/08-federating-keyclockRuntime Docker Instance Type Starter ($7/mo) or Free Environment Variables:
bash# Database connection (from your Render PostgreSQL) KC_DB_URL=jdbc:postgresql://<internal-hostname>:5432/keycloak KC_DB_USERNAME=keycloak KC_DB_PASSWORD=<your-db-password> # Admin credentials (CHANGE THESE!) KEYCLOAK_ADMIN=admin KEYCLOAK_ADMIN_PASSWORD=<strong-password> # Hostname (your Render URL) KC_HOSTNAME=keycloak-xxxx.onrender.comClick Create Web Service
Step 3: Verify Deployment
Once deployed, access:
- Admin Console:
https://keycloak-xxxx.onrender.com/admin - Health Check:
https://keycloak-xxxx.onrender.com/health
Part 2: Configure Keycloak Realm
Create a New Realm
- Log into Keycloak Admin Console
- Click dropdown (top-left, shows "master") → Create Realm
- Realm name:
azure-federation-lab - Click Create
Create a Test Client (Your Application)
Clients → Create client
Configure:
Setting Value Client type OpenID Connect Client ID test-appName Test ApplicationCapability config:
- Client authentication: ON
- Authorization: OFF
- Standard flow: ON (for web apps)
- Direct access grants: ON (for testing)
Login settings:
- Valid redirect URIs:
https://your-app.com/*orhttp://localhost:3000/* - Web origins:
+
- Valid redirect URIs:
Save and note the Client Secret from Credentials tab
Part 3: Federation Scenario A — Entra ID as Identity Provider in Keycloak
Users click "Sign in with Microsoft" in your Keycloak-protected app
Step 1: Register App in Entra ID
Go to Entra Admin Center → Applications → App registrations
New registration:
Setting Value Name Keycloak FederationSupported account types Accounts in this org directory only Redirect URI Web: https://keycloak-xxxx.onrender.com/realms/azure-federation-lab/broker/microsoft/endpointAfter creation, note:
- Application (client) ID
- Directory (tenant) ID
Certificates & secrets → New client secret
- Description:
Keycloak - Expires: 24 months
- Copy the Value immediately!
- Description:
API permissions → Add permission → Microsoft Graph:
openidprofileemailUser.Read
Click Grant admin consent
Step 2: Add Microsoft as Identity Provider in Keycloak
In Keycloak: Identity Providers → Add provider → Microsoft
Configure:
Setting Value Alias microsoftDisplay Name Sign in with MicrosoftClient ID <Application ID from Entra>Client Secret <Secret Value from Entra>Default Scopes openid profile emailAdvanced Settings:
- Sync mode:
import - Trust Email: ON
- Sync mode:
Save
Step 3: Test the Federation
- Open:
https://keycloak-xxxx.onrender.com/realms/azure-federation-lab/account - Click Sign in with Microsoft
- Authenticate with your Entra credentials
- You should be redirected back to Keycloak, logged in!
Part 4: Federation Scenario B — Keycloak as External IDP for Entra (SAML)
Entra trusts Keycloak as an external identity provider
Step 1: Configure Keycloak SAML Metadata
In Keycloak, access your realm's SAML metadata:
https://keycloak-xxxx.onrender.com/realms/azure-federation-lab/protocol/saml/descriptorDownload/save this XML—you'll need it for Entra
Step 2: Create Enterprise App in Entra with SAML SSO
Entra Admin Center → Enterprise applications → New application
Create your own application:
- Name:
Keycloak Federation - What are you looking to do: Integrate any other application you don't find in the gallery (Non-gallery)
- Name:
Single sign-on → SAML
Basic SAML Configuration:
Setting Value Identifier (Entity ID) https://keycloak-xxxx.onrender.com/realms/azure-federation-labReply URL (ACS) https://keycloak-xxxx.onrender.com/realms/azure-federation-lab/broker/saml/endpointSign on URL https://keycloak-xxxx.onrender.com/realms/azure-federation-lab/protocol/samlUser Attributes & Claims:
- Map
user.mail→email - Map
user.displayname→name
- Map
Download Federation Metadata XML from Entra
Step 3: Add Entra as SAML IDP in Keycloak
Identity Providers → Add provider → SAML v2.0
Import from URL:
https://login.microsoftonline.com/<tenant-id>/federationmetadata/2007-06/federationmetadata.xmlConfigure:
Setting Value Alias entra-samlDisplay Name Microsoft Entra (SAML)Service Provider Entity ID https://keycloak-xxxx.onrender.com/realms/azure-federation-labSave
Part 5: Workload Identity Federation (Advanced)
Use Keycloak-issued tokens to authenticate to Azure resources WITHOUT secrets!
The Concept
Instead of storing Azure service principal secrets in Keycloak, configure Azure to trust tokens issued by Keycloak:
┌─────────────────┐ ┌─────────────────┐
│ Keycloak │──Issues JWT Token───►│ │
│ (Token │ │ Azure │
│ Issuer) │ │ Resource │
│ │ │ (trusts KC) │
└─────────────────┘ └─────────────────┘Step 1: Create App Registration with Federated Credential
Entra Admin Center → App registrations → New registration
- Name:
Keycloak-Workload-Identity - Account types: Single tenant
- Name:
Certificates & credentials → Federated credentials → Add credential
Configure:
Setting Value Federated credential scenario Other issuer Issuer https://keycloak-xxxx.onrender.com/realms/azure-federation-labSubject identifier <client-id-of-your-keycloak-client>Name keycloak-federationAudience api://AzureADTokenExchangeNote the Application (client) ID and Tenant ID
Step 2: Assign Azure RBAC to the App
- Go to a resource (e.g., Storage Account)
- Access control (IAM) → Add role assignment
- Role:
Storage Blob Data Reader - Members: Select the
Keycloak-Workload-Identityapp
Step 3: Exchange Keycloak Token for Azure Token
# 1. Get token from Keycloak
KEYCLOAK_TOKEN=$(curl -s -X POST \
"https://keycloak-xxxx.onrender.com/realms/azure-federation-lab/protocol/openid-connect/token" \
-d "client_id=test-app" \
-d "client_secret=<your-client-secret>" \
-d "grant_type=client_credentials" \
-d "scope=openid" | jq -r '.access_token')
# 2. Exchange for Azure token
AZURE_TOKEN=$(curl -s -X POST \
"https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token" \
-d "client_id=<keycloak-workload-identity-app-id>" \
-d "scope=https://storage.azure.com/.default" \
-d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
-d "client_assertion=$KEYCLOAK_TOKEN" \
-d "grant_type=client_credentials" | jq -r '.access_token')
# 3. Use Azure token to access resources
curl -H "Authorization: Bearer $AZURE_TOKEN" \
-H "x-ms-version: 2020-04-08" \
"https://<storage-account>.blob.core.windows.net/<container>?restype=container&comp=list"Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| Keycloak won't start on Render | Check KC_DB_URL format, ensure PostgreSQL is running |
| "Invalid redirect URI" | Ensure exact match including trailing slashes |
| SAML signature validation failed | Download fresh metadata, re-import |
| Token exchange fails | Verify issuer URL matches exactly (no trailing slash) |
| "AADSTS50020" error | Check tenant ID and audience configuration |
Useful Debug URLs
| Purpose | URL |
|---|---|
| Keycloak OIDC Config | /realms/{realm}/.well-known/openid-configuration |
| Keycloak SAML Metadata | /realms/{realm}/protocol/saml/descriptor |
| Entra OIDC Config | https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration |
| Entra SAML Metadata | https://login.microsoftonline.com/{tenant}/federationmetadata/2007-06/federationmetadata.xml |
Clean Up
- Render: Delete web service and database
- Entra: Delete app registrations created for this lab
- RBAC: Remove any role assignments