Skip to content

Deployment & Configuration

Scope: Deployment, configuration, and resource management for non-sample repositories. Does not describe which services use Keycloak for authentication.


Table of Contents

  1. Day 1: Deployment
    1. Keycloak Instance
    2. Gateway Exposure
    3. Init Container Bootstrap
  2. Configuration Reference
  3. Flow Diagrams

Day 1: Deployment

Everything that happens during initial platform deployment via Helm.

Keycloak Instance

Source: helm-charts/charts/platform-mesh-operator-components/values.yaml

Uses the Bitnami Keycloak Helm chart with minimal customizations. All other settings (themes, providers, caching, replicas, metrics, logging, TLS, realm import, etc.) use Bitnami defaults.

Customized Values

Setting Value Purpose
image.registry ghcr.io/platform-mesh Custom image registry
image.repository upstream-images/keycloak Custom image
httpRelativePath /keycloak/ URL path prefix
auth.adminUser keycloak-admin Admin username
auth.existingSecret keycloak-admin Admin password secret
global.security.allowInsecureImages true Allow unsigned images

Resource Allocation

CPU Memory Ephemeral Storage
Requests 750m 1Gi 50Mi
Limits 2 2Gi 2Gi

Environment Variables

Variable Value Purpose
JAVA_OPTS_APPEND -Djgroups.dns.query=keycloak-headless... JGroups clustering
KC_PROXY_HEADERS xforwarded Reverse proxy support
KC_HOSTNAME_STRICT false Hostname flexibility behind proxy

PostgreSQL Subchart

Setting Value
image.registry ghcr.io/platform-mesh
image.repository upstream-images/postgresql
nameOverride postgresql-keycloak
auth.username keycloak
primary.resourcesPreset none

Image Build

Source: upstream-images/.github/workflows/build-keycloak.yaml

Property Value
Source bitnami/containers
Base Keycloak 26.x on Debian 12
Architectures linux/amd64, linux/arm64
Registry ghcr.io/platform-mesh/upstream-images/keycloak

Gateway Exposure

Source: helm-charts/charts/infra/values.yaml + helm-charts/charts/infra/templates/keycloak/httproute.yaml

Setting Value
Hostname portal.localhost
Path Prefix /keycloak
Service keycloak:80
In-cluster URL http://keycloak.platform-mesh-system.svc.cluster.local/keycloak

Init Container Bootstrap

Source: security-operator/cmd/initContainer.go Config: helm-charts/charts/security-operator/values.yaml

The security-operator Pod runs an init container before the main controller starts. This bootstraps the service account clients needed for Day 2 operations.

Configuration

initContainer:
  enabled: true
  keycloakBaseURL: "http://keycloak.platform-mesh-system.svc.cluster.local/keycloak"
  keycloakClientId: admin-cli
  keycloakUser: keycloak-admin
  clients:
    - name: security-operator
      secretRef:
        namespace: platform-mesh-system
        name: security-operator-client-secret
    - name: iam-service
      secretRef:
        namespace: platform-mesh-system
        name: iam-service-client-secret

Bootstrap Process

  1. Load config from ConfigMap (/config/config.yaml)
  2. Read admin password from Secret (/secrets/keycloak-password)
  3. Authenticate to Keycloak master realm (username/password)
  4. For each client in initContainer.clients:
  5. Create service account client (if missing)
  6. Retrieve client secret
  7. Assign admin realm role to service account
  8. Store credentials in Kubernetes Secret

Clients Created

Client Purpose Secret Location
security-operator Realm/client management, user invites platform-mesh-system/security-operator-client-secret
iam-service User queries platform-mesh-system/iam-service-client-secret

Configuration Reference

Authentication Chain

Component Phase Auth Method Credentials Source
Init Container Day 1 Username/password keycloak-admin 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

Helm Values Quick Reference

Path Phase Description
keycloak.auth.existingSecret Day 1 Secret containing admin credentials
keycloak.httpRelativePath Day 1 URL path prefix (/keycloak/)
security-operator.initContainer.enabled Day 1 Enable bootstrap
security-operator.initContainer.clients Day 1 Service account clients to create
infra.keycloak.gatewayApi.pathPrefix Day 1 Gateway route path
iam-service.keycloak.baseUrl Day 2 Keycloak URL for IAM service

Environment Variables

Variable Phase Component Description
KEYCLOAK_BASE_URL Day 2 iam-service Keycloak server URL
KEYCLOAK_CLIENT_ID Day 2 iam-service OAuth2 client ID
KEYCLOAK_CLIENT_SECRET Day 2 iam-service OAuth2 client secret
INVITE_KEYCLOAK_BASE_URL Day 2 security-operator Keycloak URL for invites
INVITE_KEYCLOAK_CLIENT_SECRET Day 2 security-operator Client secret for invites

Flow Diagrams

Day 1: Deployment & Bootstrap

sequenceDiagram
    participant Helm
    participant KC as Keycloak
    participant PG as PostgreSQL
    participant GW as Gateway
    participant Init as Init Container
    participant K8s as K8s Secrets

    rect rgb(240, 248, 255)
        Note over Helm,GW: Platform Deployment
        Helm->>PG: Deploy PostgreSQL
        Helm->>KC: Deploy Keycloak StatefulSet
        KC->>PG: Connect to database
        Helm->>GW: Create HTTPRoute (/keycloak)
    end

    rect rgb(255, 248, 240)
        Note over Init,K8s: Init Container Bootstrap
        Init->>K8s: Read admin password
        Init->>KC: Authenticate (admin credentials)
        loop For each service account client
            Init->>KC: Create client
            Init->>KC: Get client secret
            Init->>KC: Assign admin role
            Init->>K8s: Store client secret
        end
        Note over Init: Exit success → Controller starts
    end
Hold "Alt" / "Option" to enable pan & zoom

Component Overview

flowchart TB
    subgraph Day1["Day 1: Deployment"]
        direction TB
        H1["helm-charts<br/>Keycloak + PostgreSQL"]
        H2["helm-charts<br/>HTTPRoute"]
        H3["security-operator<br/>Init Container"]

        H1 --> KC
        H2 --> KC
        H3 -->|"Create clients"| KC
    end

    subgraph Runtime["Keycloak Runtime"]
        KC["Keycloak<br/>StatefulSet"]
        PG["PostgreSQL"]
        KC --- PG
    end

    subgraph Day2["Day 2: Operations"]
        direction TB
        S1["security-operator<br/>IDP Subroutine"]
        S2["security-operator<br/>Invite Subroutine"]
        I1["iam-service<br/>User Queries"]
        P1["platform-mesh-operator<br/>Workspace Auth"]

        S1 -->|"Manage realms/clients"| KC
        S2 -->|"Create users"| KC
        I1 -->|"Query users"| KC
        KC -.->|"JWT validation"| P1
    end

    Day1 --> Runtime
    Runtime --> Day2
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