Skip to content

Keycloak Operator

A GitOps-friendly Kubernetes operator for managing Keycloak instances, realms, and OAuth2/OIDC clients declaratively.

Why Use This Operator?

vs. Official Keycloak Operator

  • βœ… True Multi-Tenancy: Cross-namespace realm and client provisioning
  • βœ… GitOps Native: Namespace grant lists instead of manual secret distribution
  • βœ… Declarative Authorization: RBAC + namespace grants, no separate token system
  • βœ… Built for Production: Rate limiting, drift detection, admission webhooks
  • βœ… Comprehensive Status: Rich status fields with observedGeneration tracking

vs. Manual Keycloak Management

  • βœ… No Admin Console Access: Everything through Kubernetes CRDs
  • βœ… Drift Detection: Automatic detection of manual changes
  • βœ… Automated Credentials: Client secrets managed as Kubernetes secrets
  • βœ… Full Observability: Prometheus metrics, structured logging

πŸš€ Quick Start (3 Helm Charts)

Deploy a complete Keycloak setup with database, operator, realm, and client:

# 1. Deploy PostgreSQL (CloudNativePG)
helm install cnpg cloudnative-pg/cloudnative-pg \
  --namespace cnpg-system --create-namespace

# 2. Install operator + Keycloak instance
helm install keycloak-operator keycloak-operator/keycloak-operator \
  --namespace keycloak-system --create-namespace \
  --set keycloak.enabled=true \
  --set keycloak.database.cnpg.enabled=true

# 3. Create realm (in your app namespace)
helm install my-realm keycloak-operator/keycloak-realm \
  --namespace my-app --create-namespace \
  --set realmName=my-app \
  --set instanceRef.name=keycloak \
  --set instanceRef.namespace=keycloak-system \
  --set 'clientAuthorizationGrants={my-app}'

# 4. Create OAuth2 client
helm install my-client keycloak-operator/keycloak-client \
  --namespace my-app \
  --set clientId=my-app \
  --set realmRef.name=my-realm \
  --set 'redirectUris={https://my-app.example.com/callback}'

πŸ“– Complete Quick Start Guide β†’

✨ Key Features

  • πŸ”’ Secure by Default - Kubernetes RBAC controls all access, no separate auth system
  • πŸ“¦ GitOps Ready - Declarative CRDs with full status reporting and drift detection
  • 🎯 Multi-Tenant - Cross-namespace realm and client provisioning with namespace grants
  • ⚑ Production Ready - Rate limiting, admission webhooks, HA support with CloudNativePG
  • πŸ“Š Observable - Prometheus metrics, structured logging, comprehensive status conditions
  • πŸ”„ Drift Detection - Automatic detection and remediation of configuration drift

πŸ—οΈ Architecture

The operator manages three core resources:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Keycloak    │────▢│ KeycloakRealm   │────▢│ KeycloakClient   β”‚
β”‚  (Instance)  β”‚     β”‚ (Identity)      β”‚     β”‚ (OAuth2/OIDC)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Keycloak: Identity server instance with PostgreSQL database
  • KeycloakRealm: Identity domain containing users, roles, and settings
  • KeycloakClient: OAuth2/OIDC applications with automated credentials

πŸ“š Documentation

Getting Started

Configuration

Operations

Development

πŸ”’ Security & Authorization

The operator uses Kubernetes RBAC for all authorization - no separate token system.

Realm Creation

Any user with RBAC permission to create KeycloakRealm resources can create realms. Control this with standard Kubernetes RoleBindings:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: realm-creator
  namespace: my-app
rules:
  - apiGroups: ["vriesdemichael.github.io"]
    resources: ["keycloakrealms"]
    verbs: ["create", "update", "patch"]

Client Creation

Clients require namespace authorization from the realm. Realm owners grant access via clientAuthorizationGrants:

apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-realm
spec:
  clientAuthorizationGrants:
    - dev-team-namespace
    - staging-namespace

Only namespaces in the grant list can create clients in that realm.

πŸ“– Full Security Model Documentation β†’

πŸ“Š Status & Observability

All resources provide comprehensive status information:

status:
  phase: Ready
  conditions:
    - type: Ready
      status: "True"
      reason: ReconciliationSucceeded
      message: "Realm is healthy and synchronized"
  observedGeneration: 5
  realmId: "a1b2c3d4-5678-90ab-cdef-1234567890ab"
  internalUrl: "http://keycloak.keycloak-system.svc:8080/realms/my-app"
  publicUrl: "https://keycloak.example.com/realms/my-app"

πŸ“– Observability Guide β†’

πŸ”„ Drift Detection

The operator continuously monitors for: - Orphaned Resources - Realms/clients in Keycloak not tracked by CRs - Configuration Drift - Manual changes to Keycloak resources - Missing Resources - CRs referencing deleted Keycloak objects

πŸ“– Drift Detection Guide β†’

🚦 Admission Webhooks

Validate resources before they reach etcd: - βœ… Immediate error feedback on kubectl apply - βœ… Enforce resource quotas (max realms per namespace) - βœ… Validate cross-resource references - βœ… Prevent invalid configurations

πŸ“– Admission Webhooks Guide β†’

🀝 Contributing

Contributions welcome! See the Development Guide for: - Setting up your development environment - Running tests - Submitting pull requests - Architecture decision records (ADRs)

πŸ“ License

MIT License - see LICENSE for details.