Skip to content

Identity Providers (IDPs)

Identity Providers allow Keycloak to delegate authentication to external systems, enabling Single Sign-On (SSO) and user federation from providers like GitHub, Google, Azure AD, or custom OIDC/SAML providers.

Table of Contents

Overview

The operator supports configuring identity providers through the KeycloakRealm custom resource. Identity providers are configured in the identityProviders field of the realm spec.

When a user tries to log in to your Keycloak realm, they'll see buttons for each enabled identity provider on the login page, allowing them to authenticate through external systems.

Supported Providers

The operator supports all Keycloak built-in identity providers:

  • Social Providers: GitHub, Google, Facebook, LinkedIn, Stack Overflow, Microsoft, etc.
  • Enterprise Providers: OIDC (OpenID Connect), SAML 2.0
  • Keycloak-to-Keycloak: Federation between Keycloak instances

Configuration

GitHub OAuth

GitHub OAuth allows users to sign in with their GitHub accounts.

Prerequisites: 1. Create a GitHub OAuth App: - Go to Settings → Developer settings → OAuth Apps → New OAuth App - Set Authorization callback URL to: https://your-keycloak-domain/realms/your-realm/broker/github/endpoint - Note your Client ID and Client Secret

Example:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
  namespace: my-app
spec:
  realmName: my-realm
  operatorRef:
    namespace: keycloak-operator

  identityProviders:
    - alias: github
      providerId: github
      enabled: true
      trustEmail: false
      firstBrokerLoginFlowAlias: first broker login
      config:
        clientId: your-github-oauth-app-client-id
        clientSecret: your-github-oauth-app-client-secret
        defaultScope: "user:email"
        syncMode: IMPORT

Important Configuration Options:

  • alias: Unique identifier for this IDP (will be part of the callback URL)
  • trustEmail: Whether to trust email addresses from GitHub (set to false for security)
  • syncMode: How to sync users (IMPORT, FORCE, or LEGACY)
  • IMPORT: Create new users, update on first login only
  • FORCE: Update user data on every login
  • LEGACY: Don't update existing users

Google OAuth

Google OAuth allows users to sign in with their Google accounts.

Prerequisites: 1. Create a Google Cloud Project and OAuth 2.0 Client: - Go to Google Cloud Console - Create a project → APIs & Services → Credentials → Create OAuth Client ID - Application type: Web application - Authorized redirect URIs: https://your-keycloak-domain/realms/your-realm/broker/google/endpoint - Note your Client ID and Client Secret

Example:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
  namespace: my-app
spec:
  realmName: my-realm
  operatorRef:
    namespace: keycloak-operator

  identityProviders:
    - alias: google
      providerId: google
      enabled: true
      trustEmail: true
      firstBrokerLoginFlowAlias: first broker login
      config:
        clientId: your-google-oauth-client-id.apps.googleusercontent.com
        clientSecret: your-google-oauth-client-secret
        hostedDomain: ""  # Optional: restrict to specific domain (e.g., "company.com")
        defaultScope: "openid profile email"
        syncMode: IMPORT

Domain Restriction:

To restrict logins to a specific Google Workspace domain:

config:
  hostedDomain: "company.com"

Azure AD (Microsoft Entra ID)

Azure AD integration allows users to sign in with their Microsoft work or school accounts.

Prerequisites: 1. Register an application in Azure AD: - Go to Azure Portal → Azure Active Directory → App registrations → New registration - Set Redirect URI: https://your-keycloak-domain/realms/your-realm/broker/azure-ad/endpoint - Create a client secret in Certificates & secrets - Note your Application (client) ID, Directory (tenant) ID, and client secret

Example:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
  namespace: my-app
spec:
  realmName: my-realm
  operatorRef:
    namespace: keycloak-operator

  identityProviders:
    - alias: azure-ad
      providerId: oidc
      enabled: true
      trustEmail: true
      firstBrokerLoginFlowAlias: first broker login
      config:
        clientId: your-azure-app-client-id
        clientSecret: your-azure-app-client-secret
        authorizationUrl: https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/authorize
        tokenUrl: https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token
        userInfoUrl: https://graph.microsoft.com/oidc/userinfo
        jwksUrl: https://login.microsoftonline.com/YOUR_TENANT_ID/discovery/v2.0/keys
        issuer: https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0
        defaultScope: "openid profile email"
        syncMode: IMPORT
        validateSignature: "true"
        useJwksUrl: "true"

Replace YOUR_TENANT_ID with your Azure AD tenant ID.

Custom OIDC Provider

For any OpenID Connect-compliant identity provider.

Example:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
  namespace: my-app
spec:
  realmName: my-realm
  operatorRef:
    namespace: keycloak-operator

  identityProviders:
    - alias: custom-oidc
      providerId: oidc
      enabled: true
      trustEmail: false
      firstBrokerLoginFlowAlias: first broker login
      config:
        clientId: your-client-id
        clientSecret: your-client-secret
        authorizationUrl: https://idp.example.com/oauth2/authorize
        tokenUrl: https://idp.example.com/oauth2/token
        userInfoUrl: https://idp.example.com/oauth2/userinfo
        jwksUrl: https://idp.example.com/oauth2/keys
        issuer: https://idp.example.com
        defaultScope: "openid profile email"
        syncMode: IMPORT
        validateSignature: "true"
        useJwksUrl: "true"

Discovery Endpoint:

Most OIDC providers support auto-discovery. You can find URLs at:

https://idp.example.com/.well-known/openid-configuration

SAML Provider

For SAML 2.0 identity providers.

Example:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
  namespace: my-app
spec:
  realmName: my-realm
  operatorRef:
    namespace: keycloak-operator

  identityProviders:
    - alias: saml-idp
      providerId: saml
      enabled: true
      trustEmail: false
      firstBrokerLoginFlowAlias: first broker login
      config:
        singleSignOnServiceUrl: https://idp.example.com/saml/sso
        singleLogoutServiceUrl: https://idp.example.com/saml/logout
        backchannelSupported: "true"
        nameIDPolicyFormat: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
        principalType: SUBJECT
        signatureAlgorithm: RSA_SHA256
        xmlSigKeyInfoKeyNameTransformer: NONE
        syncMode: IMPORT

IDP Mappers

Note: Currently, protocol mappers are supported for client scopes, but IDP-specific mappers (attribute importers) will be added in a future release.

Protocol mappers allow you to customize the claims/attributes in tokens. Here's an example of protocol mappers on a client scope:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
spec:
  realmName: my-realm
  operatorRef:
    namespace: keycloak-operator

  clientScopes:
    - name: custom-claims
      protocol: openid-connect
      protocolMappers:
        - name: groups-mapper
          protocol: openid-connect
          protocolMapper: oidc-group-membership-mapper
          config:
            claim.name: groups
            full.path: "false"
            id.token.claim: "true"
            access.token.claim: "true"
            userinfo.token.claim: "true"

For IDP attribute mappers (to import user attributes from the IDP), this functionality is planned for a future release.

Complete Examples

Multi-IDP Setup

A realm with multiple identity providers:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: multi-idp-realm
  namespace: my-app
spec:
  realmName: multi-idp
  operatorRef:
    namespace: keycloak-operator

  identityProviders:
    # GitHub for developers
    - alias: github
      providerId: github
      enabled: true
      trustEmail: false
      config:
        clientId: github-client-id
        clientSecret: github-client-secret
        defaultScope: "user:email"
        syncMode: IMPORT

    # Google Workspace for employees
    - alias: google
      providerId: google
      enabled: true
      trustEmail: true
      config:
        clientId: google-client-id.apps.googleusercontent.com
        clientSecret: google-client-secret
        hostedDomain: "company.com"
        defaultScope: "openid profile email"
        syncMode: FORCE

    # Azure AD for enterprise SSO
    - alias: azure-ad
      providerId: oidc
      enabled: true
      trustEmail: true
      config:
        clientId: azure-client-id
        clientSecret: azure-client-secret
        authorizationUrl: https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize
        tokenUrl: https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token
        userInfoUrl: https://graph.microsoft.com/oidc/userinfo
        jwksUrl: https://login.microsoftonline.com/TENANT_ID/discovery/v2.0/keys
        issuer: https://login.microsoftonline.com/TENANT_ID/v2.0
        defaultScope: "openid profile email"
        syncMode: FORCE
        validateSignature: "true"
        useJwksUrl: "true"

Using Secrets for Credentials

Best Practice: Store IDP client secrets in Kubernetes Secrets instead of hardcoding them in the CR.

Note: This feature is planned for a future release. Currently, secrets must be included in the config directly.

Planned syntax (coming soon):

identityProviders:
  - alias: github
    providerId: github
    enabled: true
    trustEmail: false
    config:
      clientId: my-github-client-id
      clientSecretRef:  # Reference to Kubernetes Secret
        name: github-oauth-secret
        key: client-secret
      defaultScope: "user:email"
      syncMode: IMPORT

Troubleshooting

Common Issues

1. "Invalid redirect URI" error: - Verify your redirect URI in the IDP matches exactly: https://your-keycloak-domain/realms/your-realm/broker/{alias}/endpoint - Check for trailing slashes and protocol (http vs https)

2. Users can't log in: - Check that enabled: true is set - Verify client ID and secret are correct - Check IDP logs for authentication failures

3. User attributes not syncing: - Set syncMode: FORCE to update on every login - Verify the requested scopes include the attributes you need - Check IDP mapper configuration

4. Email not trusted: - Set trustEmail: true only for trusted providers - If false, users must verify their email after first login

Checking IDP Status

Verify IDP configuration through the CRD status:

# Check realm status includes IDP configuration
kubectl get keycloakrealm <name> -n <namespace> -o yaml

# Check operator logs for IDP reconciliation
kubectl logs -n keycloak-operator-system -l app=keycloak-operator \
  | grep "identity.*provider"

See Also