Skip to content

vriesdemichael/keycloak-operator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Keycloak Operator

CI/CD Pipeline (Unified) codecov OpenSSF Scorecard Snyk Security Docker Image License Python 3.13

A Kubernetes operator for managing Keycloak instances, realms, and OAuth2/OIDC clients declaratively with full GitOps compatibility.

πŸš€ Quick Start

Get a complete Keycloak setup running in under 10 minutes:

# 1. Install the operator (OCI registry)
# Note: The chart creates the namespace by default, don't use --create-namespace
helm install keycloak-operator \
  oci://ghcr.io/vriesdemichael/charts/keycloak-operator \
  --namespace keycloak-system

# Or install from local charts:
# helm install keycloak-operator ./charts/keycloak-operator \
#   --namespace keycloak-system

# 2. Deploy Keycloak with database
kubectl apply -f examples/01-keycloak-instance.yaml

# 3. Create an identity realm
kubectl apply -f examples/02-realm-example.yaml

# 4. Create an OAuth2 client
kubectl apply -f examples/03-client-example.yaml

πŸ“– Full Quick Start Guide β†’

✨ Features

  • Declarative Configuration - Manage Keycloak entirely through Kubernetes resources
  • Admission Webhooks - Immediate validation feedback with clear error messages (docs)
  • GitOps Ready - Full observability with status conditions and observedGeneration tracking
  • Drift Detection - Automatic detection of orphaned resources and configuration drift (docs)
  • Cross-Namespace Support - Secure delegation model for multi-tenant environments
  • Production Ready - Rate limiting, exponential backoff, and comprehensive monitoring
  • Comprehensive Test Coverage - Unit and integration tests with coverage tracking
  • Resource Quotas - Namespace-level limits on realms and clients via admission webhooks
  • Rate Limiting - Two-level throttling (global + per-namespace) protects Keycloak from overload
  • High Availability - Multi-replica Keycloak with PostgreSQL clustering via CloudNativePG
  • OAuth2/OIDC Clients - Automated client provisioning with credential management
  • Service Accounts - Declarative role assignment for machine-to-machine authentication
  • OIDC Endpoint Discovery - Automatic population of all OIDC/OAuth2 endpoints in realm status

πŸ“š Documentation

🌐 Full Documentation - Versioned documentation with version selector

Quick Links

Note: Version-Specific Documentation Use the version selector in the documentation to view docs for your installed version. See the Versioning Guide for details.

πŸ—οΈ Architecture

The operator manages three custom resources:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Keycloak     β”‚    β”‚  KeycloakRealm   β”‚    β”‚ KeycloakClient  β”‚
β”‚   (Instance)    │◄────   (Identity)     │◄────   (OAuth2/OIDC) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Keycloak: The identity server instance with database and networking
  • KeycloakRealm: Identity domain with users, roles, and authentication settings
  • KeycloakClient: OAuth2/OIDC applications with automated credential management

πŸ“Š Example

Create a complete OAuth2 setup:

# yaml-language-server: $schema=https://vriesdemichael.github.io/keycloak-operator/schemas/v1/Keycloak.json
# Keycloak instance with PostgreSQL database
apiVersion: vriesdemichael.github.io/v1
kind: Keycloak
metadata:
  name: keycloak
  namespace: keycloak-system
spec:
  replicas: 3
  image: quay.io/keycloak/keycloak:26.0.0
  database:
    type: postgresql
    host: keycloak-postgres-rw
    port: 5432
    database: app
    username: app
    passwordSecret:
      name: keycloak-postgres-app
      key: password
---
# yaml-language-server: $schema=https://vriesdemichael.github.io/keycloak-operator/schemas/v1/KeycloakRealm.json
# Identity realm with client authorization grants
apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
  name: my-app-realm
  namespace: my-app
spec:
  realmName: my-app
  operatorRef:
    namespace: keycloak-system
  # Namespaces authorized to create clients in this realm
  clientAuthorizationGrants:
    - my-app
---
# yaml-language-server: $schema=https://vriesdemichael.github.io/keycloak-operator/schemas/v1/KeycloakClient.json
# OAuth2 client (namespace must be in realm's clientAuthorizationGrants)
apiVersion: vriesdemichael.github.io/v1
kind: KeycloakClient
metadata:
  name: my-app-client
  namespace: my-app
spec:
  clientId: my-app
  realmRef:
    name: my-app-realm
    namespace: my-app
  publicClient: false
  redirectUris:
    - "https://my-app.example.com/callback"

See examples/ for complete manifests with detailed configuration options.

🎯 IDE Integration

Get autocompletion, validation, and inline documentation in your IDE using published JSON schemas:

# yaml-language-server: $schema=https://vriesdemichael.github.io/keycloak-operator/schemas/v1/KeycloakRealm.json
apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
# ... IDE will autocomplete fields with descriptions!

Features:

  • βœ… Autocomplete for all CRD fields
  • βœ… Inline validation with error messages
  • βœ… Field descriptions from CRD schema
  • βœ… Enum value suggestions

Supported IDEs:

  • VS Code (with YAML extension)
  • IntelliJ IDEA / PyCharm (built-in)
  • Neovim (with yaml-language-server)

Available schemas:

  • https://vriesdemichael.github.io/keycloak-operator/schemas/v1/Keycloak.json
  • https://vriesdemichael.github.io/keycloak-operator/schemas/v1/KeycloakRealm.json
  • https://vriesdemichael.github.io/keycloak-operator/schemas/v1/KeycloakClient.json

Add the schema annotation as the first line of your YAML files to enable IDE features.

πŸ” Security

The operator uses a namespace grant authorization model combining Kubernetes RBAC with declarative access control:

  • Realm Creation: Controlled by standard Kubernetes RBAC (who can create KeycloakRealm resources)
  • Client Creation: Controlled by realm's clientAuthorizationGrants list (which namespaces can create clients)
  • Self-service: Teams can create realms and clients without platform team intervention
  • GitOps Native: All authorization is declarative and stored in Git
  • Auditability: All access changes tracked in Git history and Kubernetes audit logs

Read the Security Model documentation for detailed authorization architecture.

πŸ“ˆ Monitoring

The operator exposes Prometheus metrics and includes a Grafana dashboard:

# Enable monitoring in Helm chart
helm install keycloak-operator ./charts/keycloak-operator \
  --set monitoring.enabled=true \
  --set monitoring.prometheusRules.enabled=true \
  --set monitoring.grafanaDashboard.enabled=true

Key metrics:

  • Reconciliation success/failure rates
  • Rate limiting wait times and timeouts
  • Reconciliation duration (p50/p95/p99)
  • Resource counts by phase

See Observability for full details.

🚦 Rate Limiting

The operator implements two-level rate limiting to protect Keycloak from API overload:

Configuration

env:
  # Global rate limit (all namespaces combined)
  - name: KEYCLOAK_API_GLOBAL_RATE_LIMIT_TPS
    value: "50"  # requests per second
  - name: KEYCLOAK_API_GLOBAL_BURST
    value: "100"  # burst capacity

  # Per-namespace rate limit (fair sharing)
  - name: KEYCLOAK_API_NAMESPACE_RATE_LIMIT_TPS
    value: "5"  # requests per second
  - name: KEYCLOAK_API_NAMESPACE_BURST
    value: "10"  # burst capacity

  # Jitter to prevent thundering herd
  - name: RECONCILE_JITTER_MAX_SECONDS
    value: "5.0"  # 0-5 second random delay

Protection Scenarios

Scenario Protection
Spam 1000 realms in one namespace Limited to 5 req/s = 200s minimum
Multiple teams overwhelming Keycloak Global 50 req/s enforced
Operator restart (50+ resources) Jitter + rate limiting prevents flood

Monitoring

Prometheus metrics available at :8081/metrics:

  • keycloak_api_rate_limit_wait_seconds - Time waiting for tokens
  • keycloak_api_rate_limit_acquired_total - Successful token acquisitions
  • keycloak_api_rate_limit_timeouts_total - Rate limit timeout errors
  • keycloak_api_tokens_available - Current available tokens per namespace

🀝 Contributing

Contributions welcome!

To set up a development environment:

# Clone the repository
git clone https://github.com/vriesdemichael/keycloak-operator.git
cd keycloak-operator

# Install dependencies
make install

# Run quality checks
make quality

# Run unit tests
make test-unit

See Development Guide and CLAUDE.md for more details.

πŸ“ License

MIT License - see LICENSE for details.

πŸ”— Links

Packages

 
 
 

Contributors 6

Languages