Skip to content

Operations

Scope: Resource management in Keycloak. Does not describe which services use Keycloak for authentication.


Table of Contents

  1. Day 2: Runtime Operations
  2. Organization Onboarding
  3. User Management
  4. User Queries
  5. Configuration Reference
  6. Flow Diagrams

Day 2: Runtime Operations

Operations performed by controllers and services after initial deployment.

Organization Onboarding

Component: security-operator (IDP Subroutine) Source: security-operator/internal/subroutine/idp/subroutine.go Trigger: IdentityProviderConfiguration CR created

What It Does

Operation Description
Create Realm One realm per organization with configurable settings
Register Clients Uses OIDC Dynamic Client Registration (RFC 7591)
Store Secrets Registration access tokens and client secrets in K8s
Finalize Deletes realm and clients when CR is deleted

Realm Configuration Applied

RealmConfig{
  LoginWithEmailAllowed:       true,
  RegistrationEmailAsUsername: true,
  RegistrationAllowed:         config.IDP.RegistrationAllowed,  // default: false
  AccessTokenLifespan:         config.IDP.AccessTokenLifespan,  // default: 28800 (8h)
  SMTPServer:                  config.IDP.SMTP...,              // if configured
}

Workspace Binding

Bootstrap (root workspace):

  • Component: platform-mesh-operator
  • Source: platform-mesh-operator/manifests/kcp/workspace-authentication-configuration.yaml
  • Property: .spec.issuer.url

Organization Workspaces (runtime):

  • Component: security-operator (Workspace Auth Subroutine)
  • Source: security-operator/internal/subroutine/workspace_authorization.go
  • Trigger: LogicalCluster reconciliation

When a new organization workspace is created, the security-operator's workspace auth subroutine:

  1. Retrieves the IdentityProviderConfiguration CR for the workspace
  2. Collects all registered OIDC client IDs as JWT audiences
  3. Creates/updates a WorkspaceAuthenticationConfiguration resource with:
  4. Issuer URL pointing to the organization's Keycloak realm
  5. Audiences from all managed clients
  6. Claim mappings for username and groups
  7. Patches the workspace types ({org}-org and {org}-acc) to reference this authentication configuration

Resulting issuer URL format:

issuerURL: https://{baseDomain}/keycloak/realms/{org-realm}

Configuration (security-operator)

Source: security-operator/internal/config/config.go

Config Key Description Default
idp-access-token-lifespan Token validity in seconds 28800 (8h)
idp-registration-allowed Allow self-registration false
idp-smtp-* SMTP settings for email actions
base-domain Domain for redirect URI construction

User Management

Component: security-operator (Invite Subroutine) Source: security-operator/internal/subroutine/invite/subroutine.go Trigger: Invite CR created

Invitation Flow

  1. Check if user exists in realm (by email)
  2. If missing, create user with required actions:
  3. VERIFY_EMAIL
  4. UPDATE_PASSWORD (optional)
  5. Send invite email via /execute-actions-email endpoint
  6. Redirect URI: https://{realm}.{baseDomain}/

User Completes Onboarding

  1. Receives invite email
  2. Verifies email address
  3. Sets password
  4. Account becomes active

Configuration

Config Key Description Default
invite-keycloak-base-url Keycloak URL for invite operations
invite-keycloak-client-id Client ID for invite subroutine security-operator
invite-keycloak-client-secret Client secret (from env)

User Queries

Component: iam-service Source: iam-service/pkg/keycloak/service.go

Consumes Keycloak Admin API to query user information for other platform services.

Methods

Method Description
UserByMail(email) Fetch single user with caching
GetUsers() Paginated fetch of all users
GetUsersByEmails(emails) Batch lookup with cache
EnrichUserRoles(userRoles) Populate user details from Keycloak

Features

  • OAuth2 client credentials authentication
  • Per-realm, per-email caching (default TTL: 1h)
  • Parallel user fetching with context cancellation
  • Brief representation for list operations
  • Pagination (default: 100 users/page)

Configuration (iam-service)

Source: iam-service/pkg/config/config.go

Config Default Description
KEYCLOAK_BASE_URL https://portal.dev.local:8443/keycloak Keycloak server URL
KEYCLOAK_CLIENT_ID iam OAuth2 client ID
KEYCLOAK_CLIENT_SECRET From environment
KEYCLOAK_PAGE_SIZE 100 Users per page
KEYCLOAK_CACHE_TTL 1h User cache duration

Configuration Reference

Authentication Chain

Component Phase Auth Method Credentials Source
Security Operator Day 2 Client credentials security-operator-client-secret
IAM Service Day 2 Client credentials iam-service-client-secret

Client Types

Type Use Case Settings
Confidential Service accounts (operators) publicClient: false, serviceAccountsEnabled: true
Public Web/mobile apps (SPAs) publicClient: true, no client secret

Flow Diagrams

Day 2: Organization Onboarding

sequenceDiagram
    participant CR as IdentityProviderConfig CR
    participant IDP as IDP Subroutine
    participant KC as Keycloak
    participant K8s as K8s Secrets
    participant PMO as platform-mesh-operator

    CR->>IDP: CR created (new org)
    IDP->>KC: Create realm
    IDP->>KC: Configure realm settings
    loop For each OIDC client
        IDP->>KC: Register client (RFC 7591)
        IDP->>K8s: Store client credentials
        IDP->>K8s: Store registration access token
    end
    IDP->>CR: Update status
    PMO->>PMO: Configure workspace issuer URL
Hold "Alt" / "Option" to enable pan & zoom

Day 2: User Invitation

sequenceDiagram
    participant CR as Invite CR
    participant Inv as Invite Subroutine
    participant KC as Keycloak
    participant User

    CR->>Inv: Invite created
    Inv->>KC: Check user exists (by email)
    alt User missing
        Inv->>KC: Create user
        Inv->>KC: Set required actions
        Inv->>KC: POST /execute-actions-email
        KC->>User: Send invite email
        User->>KC: Complete VERIFY_EMAIL
        User->>KC: Complete UPDATE_PASSWORD
    end
    Inv->>CR: Update status
Hold "Alt" / "Option" to enable pan & zoom

Crossplane Integration

No Crossplane claims are used for Keycloak bootstrap, user onboarding, or realm creation in production paths.

A Crossplane provider reference exists only in test fixtures:

  • platform-mesh-operator/test/e2e/kind/yaml/platform-mesh-resource/platform-mesh.yaml
  • Provider: xpkg.upbound.io/crossplane-contrib/provider-keycloak