Sitemap

Kubernetes + LDAP + Keycloak: Enterprise-Grade Authentication

4 min readJul 10, 2025

--

Kubernetes doesn’t handle user authentication directly — instead, it relies on external identity providers. If your organization uses LDAP, integrating it with Kubernetes through Keycloak gives you centralized authentication, fine-grained access control, and an audit-friendly system.

Press enter or click to view image in full size

In this post, we’ll walk through how to integrate Kubernetes with LDAP via Keycloak using OpenID Connect (OIDC) and Kubernetes RBAC.

Why Keycloak?

Keycloak is an open-source Identity and Access Management (IAM) solution that supports:

✅ LDAP integration
✅ OpenID Connect (OIDC)
✅ SSO across multiple apps
✅ MFA and user federation
✅ Fine-grained access policies

Using Keycloak, you can authenticate users from LDAP and allow them access to Kubernetes with OIDC tokens.

Architecture Overview

Here’s how the components fit together:

+--------+       +-----------+       +---------+       +-----------+
| User | <---> | Keycloak | <---> | LDAP | | Kubernetes|
+--------+ +-----------+ +---------+ +-----------+
^ ↘ Uses OIDC token

Auth source Authorizes via RBAC

Step-by-Step: Keycloak + LDAP + Kubernetes

Set Up Keycloak

You can run Keycloak using Docker, Podman, or deploy it on Kubernetes via the official Helm chart.

(Optional) Quick Keycloak Setup with Docker Compose (Standalone VM)

Before we integrate with Kubernetes, let’s get Keycloak running on a standalone virtual machine (Linux) using Docker Compose. This is ideal for dev/test environments.

📦 Requirements

  • Linux VM (e.g., Ubuntu or Rocky Linux)
  • Docker + Docker Compose installed
  • Port 8080 open (or 8443 for TLS)
  1. Create a docker-compose.yml File
version: "3.8"

services:
keycloak:
image: quay.io/keycloak/keycloak:24.0.4
container_name: keycloak
command: start-dev
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_DB: h2
ports:
- "8080:8080"
restart: unless-stopped

This will:

  • Run Keycloak in development mode using the in-memory H2 database
  • Expose the Keycloak admin console at http://<your-vm-ip>:8080
  • Create default admin user: admin / admin

Note: This is not for production — use PostgreSQL and TLS in secure environments.

2. Start Keycloak

Run the following commands in your VM:

mkdir keycloak-standalone && cd keycloak-standalone
nano docker-compose.yml # Paste the content above
docker compose up -d

You should now be able to access Keycloak at:

http://<your-vm-ip>:8080

Login using:

  • Username: admin
  • Password: admin

3. (Optional) Run with PostgreSQL for Persistent Storage

Here’s a minimal Docker Compose setup with PostgreSQL:

version: "3.8"

services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data

keycloak:
image: quay.io/keycloak/keycloak:24.0.4
command: start-dev
depends_on:
- postgres
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_DB: postgres
KC_DB_URL_HOST: postgres
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: secret
ports:
- "8080:8080"

volumes:
pgdata:

Create LDAP User Federation

In the Keycloak admin console:

  • Navigate to: User Federation → Add provider → ldap

Fill in details like:

  • Connection URL: ldap://ldap.example.com:389
  • Bind DN: cn=admin,dc=example,dc=com
  • Bind Credential: Your LDAP admin password
  • Users DN: ou=Users,dc=example,dc=com
  • Username LDAP attribute: uid

Enable Import Users (optional) and Sync Registrations.

Create a Realm and Client

  1. Create a Realm (e.g., kubernetes)
  2. Create a Client:
  • Client ID: kubernetes
  • Client Protocol: openid-connect
  • Access Type: confidential
  • Valid Redirect URIs: https://<your-k8s-dashboard-or-client>/*
  • Add a Client Secret

Configure Kubernetes API Server with OIDC

Add the following flags to your Kubernetes API server:

--oidc-issuer-url=https://keycloak.example.com/realms/kubernetes
--oidc-client-id=kubernetes
--oidc-username-claim=preferred_username
--oidc-groups-claim=groups
--oidc-username-prefix=oidc:

You can configure these with kubeadm, kops, or your managed Kubernetes provider (like EKS, AKS, or GKE).

Create RBAC Rules in Kubernetes

Now that authentication is handled by Keycloak, define what users can do using Kubernetes RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: view-pods
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-view-pods
subjects:
- kind: User
name: "jane.doe" # should match the Keycloak username
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view-pods
apiGroup: rbac.authorization.k8s.io

You can also use Group in subjects if your LDAP/Keycloak is configured to return groups.

Testing

  • Use an OIDC helper like kubelogin to authenticate and get a token.
  • Configure your kubeconfig file to use OIDC:
users:
- name: oidc-user
user:
auth-provider:
name: oidc
config:
idp-issuer-url: https://keycloak.example.com/realms/kubernetes
client-id: kubernetes
client-secret: <client-secret>
  • Run kubectl get pods and validate access.

Pro Tips:

  • Enable TLS for both Keycloak and LDAP connections.
  • Regularly sync LDAP users in Keycloak for up-to-date access.
  • Use Keycloak mappers to map LDAP attributes to OIDC claims.
  • Monitor and audit authentication events using Keycloak’s admin events log.

Using Keycloak as an OIDC provider for Kubernetes backed by LDAP gives you a powerful and secure authentication model. It’s a production-ready solution ideal for enterprise environments that already rely on LDAP for identity management.

This setup not only brings SSO to your Kubernetes environment but also simplifies access control, audits, and compliance.

--

--

Gerardo Ocampos
Gerardo Ocampos

Written by Gerardo Ocampos

Red Hat Certified Engineer — Red Hat Certified System Administrator — Red Hat Certified Specialist in Containers and Kubernetes. Asunción, Paraguay