Skip to content

Commit e420f16

Browse files
authored
🔧 Developer doc for keycloak environment and testing with MCP Inspector (containers#413)
Signed-off-by: Matthias Wessendorf <[email protected]>
1 parent 42a0674 commit e420f16

File tree

5 files changed

+218
-0
lines changed

5 files changed

+218
-0
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# Keycloak OIDC Setup for Kubernetes MCP Server
2+
3+
This guide shows you how to set up a local development environment with Keycloak for OIDC authentication testing.
4+
5+
## Overview
6+
7+
The local development environment includes:
8+
- **Kind cluster** with OIDC-enabled API server
9+
- **Keycloak** (deployed in the cluster) for OIDC provider
10+
- **Kubernetes MCP Server** configured for OAuth/OIDC authentication
11+
12+
## Quick Start
13+
14+
Set up the complete environment with one command:
15+
16+
```bash
17+
make local-env-setup
18+
```
19+
20+
This will:
21+
1. Install required tools (kind) to `./_output/bin/`
22+
2. Create a Kind cluster with OIDC configuration
23+
3. Deploy Keycloak in the cluster
24+
4. Configure Keycloak realm and clients
25+
5. Build the MCP server binary
26+
6. Generate a configuration file at `_output/config.toml`
27+
28+
## Running the MCP Server
29+
30+
After setup completes, run the server:
31+
32+
```bash
33+
# Start the server
34+
./kubernetes-mcp-server --port 8008 --config _output/config.toml
35+
```
36+
37+
Or use the MCP Inspector for testing:
38+
39+
```bash
40+
npx @modelcontextprotocol/inspector@latest $(pwd)/kubernetes-mcp-server --config _output/config.toml
41+
```
42+
43+
## Quick Walkthrough
44+
45+
### 1. Start MCP Inspector and Connect
46+
47+
After running the inspector, in the `Authentication`'s **OAuth 2.0 Flow** set the `Client ID` to be `mcp-client` and the `Scope` to `mcp-server`, afterwards click the "Connect" button.
48+
49+
<a href="images/keycloak-mcp-inspector-connect.png">
50+
<img src="images/keycloak-mcp-inspector-connect.png" alt="MCP Inspector Connect Button" width="600" />
51+
</a>
52+
53+
### 2. Login to Keycloak
54+
55+
You'll be redirected to Keycloak. Enter the test credentials:
56+
- Username: `mcp`
57+
- Password: `mcp`
58+
59+
<a href="images/keycloak-login-page.png">
60+
<img src="images/keycloak-login-page.png" alt="Keycloak Login Page" width="600" />
61+
</a>
62+
63+
### 3. Use MCP Tools
64+
65+
After authentication, you can use the **Tools** from the Kubernetes-MCP-Server from the MCP Inspector, like below where we run the `pods_list` tool, to list all pods in the current cluster from all namespaces.
66+
67+
<a href="images/keycloak-mcp-inspector-results.png">
68+
<img src="images/keycloak-mcp-inspector-results.png" alt="MCP Inspector Tool Results" width="600" />
69+
</a>
70+
71+
## Architecture
72+
73+
### Keycloak Deployment
74+
- Runs as a StatefulSet in the `keycloak` namespace
75+
- Exposed via Ingress with TLS at `https://keycloak.127-0-0-1.sslip.io:8443`
76+
- Uses cert-manager for TLS certificates
77+
- Accessible from both host and cluster pods
78+
79+
### Kind Cluster with OIDC
80+
- Kubernetes API server configured with OIDC authentication
81+
- Points to Keycloak's `openshift` realm as the OIDC issuer
82+
- Validates bearer tokens against Keycloak's JWKS endpoint
83+
- API server trusts the cert-manager CA certificate
84+
85+
### Authentication Flow
86+
87+
```
88+
User Browser
89+
|
90+
| 1. OAuth login (https://keycloak.127-0-0-1.sslip.io:8443)
91+
v
92+
Keycloak
93+
|
94+
| 2. ID Token (aud: mcp-server)
95+
v
96+
MCP Server
97+
|
98+
| 3. Token Exchange (aud: openshift)
99+
v
100+
Keycloak
101+
|
102+
| 4. Exchanged Access Token
103+
v
104+
MCP Server
105+
|
106+
| 5. Bearer Token in API request
107+
v
108+
Kubernetes API Server
109+
|
110+
| 6. Validate token via OIDC
111+
v
112+
Keycloak JWKS
113+
|
114+
| 7. Token valid, execute tool
115+
v
116+
MCP Server → User
117+
```
118+
119+
## Keycloak Configuration
120+
121+
The setup automatically configures:
122+
123+
### Realm: `openshift`
124+
- Token lifespan: 30 minutes
125+
- Session idle timeout: 30 minutes
126+
127+
### Clients
128+
129+
1. **mcp-client** (public)
130+
- Public client for browser-based OAuth login
131+
- PKCE required for security
132+
- Valid redirect URIs: `*`
133+
134+
2. **mcp-server** (confidential)
135+
- Confidential client with client secret
136+
- Standard token exchange enabled
137+
- Can exchange tokens with `aud: openshift`
138+
- Default scopes: `openid`, `groups`, `mcp-server`
139+
- Optional scopes: `mcp:openshift`
140+
141+
3. **openshift** (confidential)
142+
- Target client for token exchange
143+
- Accepts exchanged tokens from `mcp-server`
144+
- Used by Kubernetes API server for OIDC validation
145+
146+
### Client Scopes
147+
- **mcp-server**: Default scope with audience mapper
148+
- **mcp:openshift**: Optional scope for token exchange with audience mapper
149+
- **groups**: Group membership mapper (included in tokens)
150+
151+
### Default User
152+
- **Username**: `mcp`
153+
- **Password**: `mcp`
154+
- **Email**: `[email protected]`
155+
- **RBAC**: `cluster-admin` (full cluster access)
156+
157+
## MCP Server Configuration
158+
159+
The generated `_output/config.toml` includes:
160+
161+
```toml
162+
require_oauth = true
163+
oauth_audience = "mcp-server"
164+
oauth_scopes = ["openid", "mcp-server"]
165+
validate_token = false # Validation done by K8s API server
166+
authorization_url = "https://keycloak.127-0-0-1.sslip.io:8443/realms/openshift"
167+
168+
sts_client_id = "mcp-server"
169+
sts_client_secret = "..." # Auto-generated
170+
sts_audience = "openshift" # Triggers token exchange
171+
sts_scopes = ["mcp:openshift"]
172+
173+
certificate_authority = "_output/cert-manager-ca/ca.crt" # For HTTPS validation
174+
```
175+
176+
## Useful Commands
177+
178+
### Check Keycloak Status
179+
180+
```bash
181+
make keycloak-status
182+
```
183+
184+
Shows:
185+
- Keycloak pod status
186+
- Service endpoints
187+
- Access URL
188+
- Admin credentials
189+
190+
### View Keycloak Logs
191+
192+
```bash
193+
make keycloak-logs
194+
```
195+
196+
### Access Keycloak Admin Console
197+
198+
Open your browser to:
199+
```
200+
https://keycloak.127-0-0-1.sslip.io:8443
201+
```
202+
203+
**Admin credentials:**
204+
- Username: `admin`
205+
- Password: `admin`
206+
207+
Navigate to the `openshift` realm to view/modify the configuration.
208+
209+
## Teardown
210+
211+
Remove the local environment:
212+
213+
```bash
214+
make local-env-teardown
215+
```
216+
217+
This deletes the Kind cluster (Keycloak is removed with it).

‎docs/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ Choose the guide that matches your needs:
1818

1919
## Additional Documentation
2020

21+
- **[Keycloak OIDC Setup](KEYCLOAK_OIDC_SETUP.md)** - Developer guide for local Keycloak environment and testing with MCP Inspector
2122
- **[Main README](../README.md)** - Project overview and general information
500 KB
Loading
169 KB
Loading
336 KB
Loading

0 commit comments

Comments
 (0)