Skip to content

Commit 48cbe47

Browse files
committed
adding auth based authentication instead of kubeconfigs
1 parent 74fd934 commit 48cbe47

File tree

10 files changed

+733
-5
lines changed

10 files changed

+733
-5
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ python/build/
2727
python/dist/
2828
python/kubernetes_mcp_server.egg-info/
2929
!python/kubernetes-mcp-server
30+
31+
config-dev.toml

docs/AUTH_HEADERS_PROVIDER.md

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
# Auth-Headers Provider
2+
3+
The `auth-headers` cluster provider strategy enables multi-tenant Kubernetes MCP server deployments where each user authenticates with their own Kubernetes token via HTTP request headers.
4+
5+
## Overview
6+
7+
This provider:
8+
- **Requires authentication via request headers** (`Authorization` or `kubernetes-authorization`)
9+
- **Extracts cluster connection details** from kubeconfig (server URL, CA certificates)
10+
- **Strips all authentication credentials** from the kubeconfig
11+
- **Creates dynamic Kubernetes clients** per request using the provided bearer tokens
12+
13+
## Use Cases
14+
15+
- **Multi-tenant SaaS deployments** - Single MCP server instance serving multiple users
16+
- **Zero-trust architectures** - No stored credentials, authentication per request
17+
- **OIDC/OAuth integration** - Users authenticate via identity provider, tokens forwarded to Kubernetes
18+
- **Auditing & compliance** - Each request uses the user's actual identity for Kubernetes RBAC
19+
20+
## Configuration
21+
22+
### Basic Setup
23+
24+
```bash
25+
kubernetes-mcp-server \
26+
--port 8080 \
27+
--kubeconfig /path/to/kubeconfig \
28+
--cluster-provider-strategy auth-headers
29+
```
30+
31+
The server will:
32+
1. Read cluster connection details from the kubeconfig
33+
2. Automatically enable `--require-oauth`
34+
3. Reject any requests without valid bearer tokens
35+
36+
### TOML Configuration
37+
38+
```toml
39+
cluster_provider_strategy = "auth-headers"
40+
kubeconfig = "/path/to/kubeconfig"
41+
require_oauth = true
42+
validate_token = true # Optional: validate tokens against Kubernetes API
43+
```
44+
45+
### With Token Validation
46+
47+
```bash
48+
kubernetes-mcp-server \
49+
--port 8080 \
50+
--kubeconfig /path/to/kubeconfig \
51+
--cluster-provider-strategy auth-headers \
52+
--validate-token
53+
```
54+
55+
This validates each token using Kubernetes TokenReview API before allowing operations.
56+
57+
## How It Works
58+
59+
### 1. Initialization
60+
61+
When the server starts:
62+
```
63+
Kubeconfig → Extract cluster info (server URL, CA cert) → Create base manager
64+
65+
Strip all auth credentials
66+
67+
Ready to accept requests
68+
```
69+
70+
### 2. Request Processing
71+
72+
For each MCP request:
73+
```
74+
HTTP Request → Extract Authorization header → Create derived Kubernetes client
75+
↓ ↓
76+
"Bearer <token>" Uses token for authentication
77+
78+
Execute Kubernetes operation
79+
```
80+
81+
### 3. Security Model
82+
83+
```
84+
┌──────────────────┐
85+
│ MCP Client │ (User's application)
86+
│ (Claude, etc) │
87+
└────────┬─────────┘
88+
│ Bearer <user-token>
89+
90+
┌──────────────────┐
91+
│ MCP Server │
92+
│ (auth-headers) │
93+
└────────┬─────────┘
94+
│ Uses user's token
95+
96+
┌──────────────────┐
97+
│ Kubernetes API │
98+
│ Server │
99+
└──────────────────┘
100+
101+
RBAC enforced with
102+
user's actual identity
103+
```
104+
105+
## Client Usage
106+
107+
### Using the Go MCP Client
108+
109+
```go
110+
import "github.com/mark3labs/mcp-go/client/transport"
111+
112+
// Get user's Kubernetes token (from OIDC, service account, etc.)
113+
userToken := getUserKubernetesToken()
114+
115+
client := NewMCPClient(
116+
transport.WithHTTPHeaders(map[string]string{
117+
"Authorization": "Bearer " + userToken
118+
})
119+
)
120+
```
121+
122+
### Using Claude Desktop
123+
124+
```json
125+
{
126+
"mcpServers": {
127+
"kubernetes": {
128+
"url": "https://mcp-server.example.com/sse",
129+
"headers": {
130+
"Authorization": "Bearer YOUR_KUBERNETES_TOKEN"
131+
}
132+
}
133+
}
134+
}
135+
```
136+
137+
### Using cURL
138+
139+
```bash
140+
curl -X POST https://mcp-server.example.com/mcp \
141+
-H "Content-Type: application/json" \
142+
-H "Authorization: Bearer eyJhbGci..." \
143+
-d '{
144+
"jsonrpc": "2.0",
145+
"method": "tools/call",
146+
"params": {
147+
"name": "pods_list",
148+
"arguments": {"namespace": "default"}
149+
},
150+
"id": 1
151+
}'
152+
```
153+
154+
## Comparison with Other Providers
155+
156+
| Feature | auth-headers | kubeconfig | in-cluster | disabled |
157+
|---------|--------------|------------|------------|----------|
158+
| **Multi-tenant** | ✅ Yes | ❌ No | ❌ No | ❌ No |
159+
| **Multi-cluster** | ❌ No | ✅ Yes | ❌ No | ❌ No |
160+
| **Per-request auth** | ✅ Yes | ❌ No | ❌ No | ❌ No |
161+
| **Requires headers** | ✅ Required | ❌ Optional | ❌ Optional | ❌ Optional |
162+
| **Stored credentials** | ❌ None | ✅ Kubeconfig | ✅ SA token | ✅ Kubeconfig |
163+
| **Use case** | SaaS/Multi-user | Local dev | In-cluster | Single cluster |
164+
165+
## Security Considerations
166+
167+
### ✅ Advantages
168+
169+
- **No stored credentials** - Server doesn't store any Kubernetes authentication
170+
- **Per-request authentication** - Each request uses fresh, user-specific token
171+
- **RBAC enforcement** - Kubernetes enforces permissions using actual user identity
172+
- **Token expiration** - Short-lived tokens automatically expire
173+
- **Audit trails** - Kubernetes audit logs show actual user, not service account
174+
175+
### ⚠️ Important Notes
176+
177+
1. **Tokens in transit** - Use HTTPS to protect tokens in HTTP headers
178+
2. **Token validation** - Enable `--validate-token` for additional security
179+
3. **Rate limiting** - Consider implementing rate limiting per token/user
180+
4. **Token rotation** - Clients must handle token refresh/expiration
181+
5. **Network security** - Ensure MCP server can reach Kubernetes API
182+
183+
## Example Deployment
184+
185+
### Docker Compose
186+
187+
```yaml
188+
version: '3.8'
189+
services:
190+
kubernetes-mcp-server:
191+
image: quay.io/containers/kubernetes_mcp_server:latest
192+
ports:
193+
- "8080:8080"
194+
command:
195+
- --port=8080
196+
- --kubeconfig=/kubeconfig/config
197+
- --cluster-provider-strategy=auth-headers
198+
- --validate-token
199+
volumes:
200+
- ./kubeconfig:/kubeconfig:ro
201+
environment:
202+
- LOG_LEVEL=1
203+
```
204+
205+
### Kubernetes Deployment
206+
207+
```yaml
208+
apiVersion: apps/v1
209+
kind: Deployment
210+
metadata:
211+
name: kubernetes-mcp-server
212+
spec:
213+
replicas: 3
214+
selector:
215+
matchLabels:
216+
app: kubernetes-mcp-server
217+
template:
218+
metadata:
219+
labels:
220+
app: kubernetes-mcp-server
221+
spec:
222+
containers:
223+
- name: server
224+
image: quay.io/containers/kubernetes_mcp_server:latest
225+
args:
226+
- --port=8080
227+
- --kubeconfig=/kubeconfig/config
228+
- --cluster-provider-strategy=auth-headers
229+
- --validate-token
230+
ports:
231+
- containerPort: 8080
232+
volumeMounts:
233+
- name: kubeconfig
234+
mountPath: /kubeconfig
235+
readOnly: true
236+
volumes:
237+
- name: kubeconfig
238+
configMap:
239+
name: cluster-kubeconfig
240+
---
241+
apiVersion: v1
242+
kind: Service
243+
metadata:
244+
name: kubernetes-mcp-server
245+
spec:
246+
selector:
247+
app: kubernetes-mcp-server
248+
ports:
249+
- port: 80
250+
targetPort: 8080
251+
```
252+
253+
## Troubleshooting
254+
255+
### Error: "bearer token required in Authorization header"
256+
257+
**Cause**: Request missing authentication header
258+
259+
**Solution**: Include `Authorization: Bearer <token>` header in all requests
260+
261+
### Error: "auth-headers ClusterProviderStrategy cannot be used in in-cluster deployments"
262+
263+
**Cause**: Trying to use auth-headers provider from within a Kubernetes cluster
264+
265+
**Solution**: Use `in-cluster` or `disabled` strategy for in-cluster deployments, or explicitly set a kubeconfig path
266+
267+
### Error: "token-based authentication required"
268+
269+
**Cause**: `RequireOAuth` is enabled but no token provided
270+
271+
**Solution**: Ensure client sends bearer token in Authorization header
272+
273+
### Warning: "auth-headers ClusterProviderStrategy requires OAuth authentication, enabling RequireOAuth"
274+
275+
**Info**: This is expected - auth-headers provider automatically enables OAuth requirement
276+
277+
## Related Documentation
278+
279+
- [OIDC/OAuth Setup Guide](./KEYCLOAK_OIDC_SETUP.md)
280+
- [Getting Started](./GETTING_STARTED_KUBERNETES.md)
281+
- [Claude Integration](./GETTING_STARTED_CLAUDE_CODE.md)
282+

pkg/config/config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import (
1111
)
1212

1313
const (
14-
ClusterProviderKubeConfig = "kubeconfig"
15-
ClusterProviderInCluster = "in-cluster"
16-
ClusterProviderDisabled = "disabled"
14+
ClusterProviderKubeConfig = "kubeconfig"
15+
ClusterProviderInCluster = "in-cluster"
16+
ClusterProviderDisabled = "disabled"
17+
ClusterProviderAuthHeaders = "auth-headers"
1718
)
1819

1920
// StaticConfig is the configuration for the server.

0 commit comments

Comments
 (0)