Skip to content

Commit d912d76

Browse files
Collin Walkerclaude
andcommitted
feat: add SSL/TLS configuration support to ModelConfig CRD
Add comprehensive SSL/TLS configuration capabilities to Kagent's ModelConfig custom resource, enabling agents to securely connect to internal LiteLLM gateways and model providers that use self-signed certificates or custom certificate authorities. This is a production-ready, Kubernetes-native implementation that follows security best practices and maintains full backward compatibility with existing ModelConfig resources. Changes by Component: Go Backend (Kubernetes CRD & Controller): - Added TLSConfig struct to v1alpha1 and v1alpha2 CRD schemas - Implemented controller logic to mount CA certificates as volumes - Extended HTTP API to include TLS configuration in responses - Added comprehensive validation tests and controller mounting tests Python Runtime (kagent-adk): - Created SSL utilities module with create_ssl_context() supporting 3 modes - Extended OpenAI and AzureOpenAI clients with TLS configuration support - Added type-safe TLS fields to model configuration classes - Comprehensive test coverage with 33 test functions and test fixtures Key Features: 1. Kubernetes-native design using Secrets and volume mounts 2. Three TLS modes: disabled, custom CA only, system + custom CA 3. Security-focused with validation, warnings, and RBAC docs 4. Production-ready with error handling and extensive testing 5. Fully backward compatible (no breaking changes) Documentation: - User guide: docs/user-guide/modelconfig-tls.md - RBAC guide: docs/user-guide/tls-rbac.md - Troubleshooting: docs/troubleshooting/ssl-errors.md - Examples: examples/modelconfig-with-tls.yaml All tests pass (14 Go tests, 33 Python tests with ~62 test cases). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> Signed-off-by: Collin Walker <[email protected]>
1 parent 658b41a commit d912d76

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+5397
-2878
lines changed

docs/troubleshooting/ssl-errors.md

Lines changed: 595 additions & 0 deletions
Large diffs are not rendered by default.

docs/user-guide/modelconfig-tls.md

Lines changed: 482 additions & 0 deletions
Large diffs are not rendered by default.

docs/user-guide/tls-rbac.md

Lines changed: 676 additions & 0 deletions
Large diffs are not rendered by default.

examples/modelconfig-with-tls.yaml

Lines changed: 388 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,388 @@
1+
# ModelConfig TLS Configuration Examples
2+
#
3+
# This file demonstrates various TLS configuration scenarios for ModelConfig resources
4+
# to enable agents to connect to LLM providers with custom certificates.
5+
#
6+
# See docs/user-guide/modelconfig-tls.md for complete documentation.
7+
8+
---
9+
# Example 1: Internal LiteLLM with Custom CA Certificate (Recommended)
10+
#
11+
# Use Case: LiteLLM gateway running at https://litellm.internal.corp:8080 with
12+
# self-signed certificate. This configuration trusts both system CAs (for public
13+
# services) and your custom CA (for internal services).
14+
#
15+
# This is the recommended configuration for most use cases.
16+
17+
apiVersion: v1
18+
kind: Secret
19+
metadata:
20+
name: litellm-ca-cert
21+
namespace: kagent
22+
type: Opaque
23+
stringData:
24+
# CA certificate in PEM format
25+
# Replace with your actual CA certificate
26+
ca.crt: |
27+
-----BEGIN CERTIFICATE-----
28+
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRkmgMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
29+
BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG
30+
A1UECgwETXlPcmcxDzANBgNVBAsMBlByaXZhdGUxDDAKBgNVBAMMA0NBMDAeFw0y
31+
NTAxMDEwMDAwMDBaFw0yNjAxMDEwMDAwMDBaMEUxCzAJBgNVBAYTAlVTMQswCQYD
32+
VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETXlPcmcx
33+
DzANBgNVBAsMBlByaXZhdGUxDDAKBgNVBAMMA0NBMDCCASIwDQYJKoZIhvcNAQEB
34+
BQADggEPADCCAQoCggEBAMkN...
35+
(your certificate content here)
36+
...
37+
-----END CERTIFICATE-----
38+
39+
---
40+
apiVersion: v1
41+
kind: Secret
42+
metadata:
43+
name: litellm-api-key
44+
namespace: kagent
45+
type: Opaque
46+
stringData:
47+
key: sk-litellm-1234567890abcdef # Replace with your actual API key
48+
49+
---
50+
apiVersion: kagent.dev/v1alpha1
51+
kind: ModelConfig
52+
metadata:
53+
name: litellm-internal
54+
namespace: kagent
55+
spec:
56+
# Provider must be set to OpenAI since LiteLLM presents an OpenAI-compatible API
57+
provider: OpenAI
58+
model: gpt-4
59+
60+
# API key for authentication
61+
apiKeySecretRef: litellm-api-key
62+
apiKeySecretKey: key
63+
64+
# OpenAI configuration with custom base URL pointing to LiteLLM
65+
openAI:
66+
baseUrl: https://litellm.internal.corp:8080
67+
68+
# TLS configuration for custom certificate
69+
tls:
70+
# Reference to Secret containing CA certificate
71+
caCertSecretRef: litellm-ca-cert
72+
caCertSecretKey: ca.crt
73+
74+
# Trust both system CAs and custom CA (recommended)
75+
# This allows connecting to both public services and internal services
76+
useSystemCAs: true
77+
78+
# Verification is enabled (secure)
79+
verifyDisabled: false
80+
81+
---
82+
# Example 2: Multiple CA Certificates (Certificate Bundle)
83+
#
84+
# Use Case: Your certificate chain includes both root and intermediate CAs,
85+
# or you need to trust multiple certificate authorities.
86+
87+
apiVersion: v1
88+
kind: Secret
89+
metadata:
90+
name: corporate-ca-bundle
91+
namespace: kagent
92+
type: Opaque
93+
stringData:
94+
# Certificate bundle with multiple CA certificates
95+
# Certificates should be concatenated in PEM format
96+
# Order: intermediate CA(s) first, then root CA
97+
ca-bundle.crt: |
98+
-----BEGIN CERTIFICATE-----
99+
(Intermediate CA certificate)
100+
-----END CERTIFICATE-----
101+
-----BEGIN CERTIFICATE-----
102+
(Root CA certificate)
103+
-----END CERTIFICATE-----
104+
-----BEGIN CERTIFICATE-----
105+
(Optional: additional CA certificates)
106+
-----END CERTIFICATE-----
107+
108+
---
109+
apiVersion: kagent.dev/v1alpha1
110+
kind: ModelConfig
111+
metadata:
112+
name: corporate-llm
113+
namespace: kagent
114+
spec:
115+
provider: OpenAI
116+
model: gpt-4-corporate
117+
apiKeySecretRef: corporate-api-key
118+
apiKeySecretKey: key
119+
openAI:
120+
baseUrl: https://ai-platform.corp.internal:443
121+
tls:
122+
caCertSecretRef: corporate-ca-bundle
123+
caCertSecretKey: ca-bundle.crt # Reference the bundle key
124+
useSystemCAs: true
125+
verifyDisabled: false
126+
127+
---
128+
# Example 3: Custom CA Only (No System CAs)
129+
#
130+
# Use Case: Strict security policy where only corporate/internal CAs should be trusted.
131+
# Public CA certificates are not trusted, improving security posture but limiting
132+
# connectivity to only internal services.
133+
134+
apiVersion: v1
135+
kind: Secret
136+
metadata:
137+
name: strict-ca-cert
138+
namespace: kagent
139+
type: Opaque
140+
stringData:
141+
ca.crt: |
142+
-----BEGIN CERTIFICATE-----
143+
(Corporate CA certificate only)
144+
-----END CERTIFICATE-----
145+
146+
---
147+
apiVersion: kagent.dev/v1alpha1
148+
kind: ModelConfig
149+
metadata:
150+
name: strict-internal-llm
151+
namespace: kagent
152+
spec:
153+
provider: OpenAI
154+
model: gpt-4
155+
apiKeySecretRef: internal-api-key
156+
apiKeySecretKey: key
157+
openAI:
158+
baseUrl: https://secure-llm.corp.internal:443
159+
tls:
160+
caCertSecretRef: strict-ca-cert
161+
caCertSecretKey: ca.crt
162+
163+
# Only trust custom CA, not system CAs
164+
# This prevents connections to public services
165+
useSystemCAs: false
166+
167+
verifyDisabled: false
168+
169+
---
170+
# Example 4: Verification Disabled (Development/Testing Only)
171+
#
172+
# ⚠️ WARNING: This configuration disables ALL SSL verification.
173+
# Use ONLY in development or testing environments. NEVER in production.
174+
#
175+
# Use Case: Local development where you want to quickly test without
176+
# managing certificates, or testing against a server with invalid certificates.
177+
178+
apiVersion: kagent.dev/v1alpha1
179+
kind: ModelConfig
180+
metadata:
181+
name: litellm-dev
182+
namespace: kagent-dev
183+
spec:
184+
provider: OpenAI
185+
model: gpt-4
186+
apiKeySecretRef: dev-api-key
187+
apiKeySecretKey: key
188+
openAI:
189+
baseUrl: https://localhost:8080
190+
tls:
191+
# Disable all SSL verification (insecure!)
192+
verifyDisabled: true
193+
194+
# When verifyDisabled is true, other TLS fields are ignored
195+
# No Secret is required in this mode
196+
197+
# When this configuration is used, agents will log prominent warnings:
198+
#
199+
# ============================================================
200+
# ⚠️ SSL VERIFICATION DISABLED ⚠️
201+
# ============================================================
202+
# SSL certificate verification is disabled.
203+
# This should ONLY be used in development/testing.
204+
# Production deployments MUST use proper certificates.
205+
# ============================================================
206+
207+
---
208+
# Example 5: Azure OpenAI with Custom Certificate
209+
#
210+
# Use Case: Azure OpenAI service accessed through internal proxy with custom certificate
211+
212+
apiVersion: v1
213+
kind: Secret
214+
metadata:
215+
name: azure-proxy-ca
216+
namespace: kagent
217+
type: Opaque
218+
stringData:
219+
ca.crt: |
220+
-----BEGIN CERTIFICATE-----
221+
(Proxy CA certificate)
222+
-----END CERTIFICATE-----
223+
224+
---
225+
apiVersion: v1
226+
kind: Secret
227+
metadata:
228+
name: azure-api-key
229+
namespace: kagent
230+
type: Opaque
231+
stringData:
232+
key: your-azure-api-key-here
233+
234+
---
235+
apiVersion: kagent.dev/v1alpha1
236+
kind: ModelConfig
237+
metadata:
238+
name: azure-through-proxy
239+
namespace: kagent
240+
spec:
241+
provider: AzureOpenAI
242+
model: gpt-4
243+
apiKeySecretRef: azure-api-key
244+
apiKeySecretKey: key
245+
azureOpenAI:
246+
endpoint: https://your-resource.openai.azure.com/ # Through internal proxy
247+
deploymentId: gpt-4-deployment
248+
apiVersion: "2024-02-15-preview"
249+
tls:
250+
caCertSecretRef: azure-proxy-ca
251+
caCertSecretKey: ca.crt
252+
useSystemCAs: true
253+
verifyDisabled: false
254+
255+
---
256+
# Example 6: Default Configuration (No TLS)
257+
#
258+
# Use Case: Connecting to public LLM providers (OpenAI, Anthropic, etc.) with
259+
# standard publicly-trusted certificates. This is the default behavior.
260+
261+
apiVersion: v1
262+
kind: Secret
263+
metadata:
264+
name: openai-api-key
265+
namespace: kagent
266+
type: Opaque
267+
stringData:
268+
key: sk-openai-1234567890abcdef
269+
270+
---
271+
apiVersion: kagent.dev/v1alpha1
272+
kind: ModelConfig
273+
metadata:
274+
name: openai-public
275+
namespace: kagent
276+
spec:
277+
provider: OpenAI
278+
model: gpt-4
279+
apiKeySecretRef: openai-api-key
280+
apiKeySecretKey: key
281+
282+
# No openAI.baseUrl specified - uses default https://api.openai.com
283+
# No tls configuration - uses system CAs with verification enabled
284+
# This is the simplest and most common configuration
285+
286+
---
287+
# Example 7: Agent Using ModelConfig with TLS
288+
#
289+
# Complete example showing how to create an Agent that uses a ModelConfig
290+
# with TLS configuration.
291+
292+
apiVersion: kagent.dev/v1alpha1
293+
kind: Agent
294+
metadata:
295+
name: internal-assistant
296+
namespace: kagent
297+
spec:
298+
# Framework selection (ADK, LangGraph, or CrewAI)
299+
framework: ADK
300+
301+
# Reference to ModelConfig with TLS configuration
302+
modelConfigName: litellm-internal
303+
304+
# Agent card for A2A protocol
305+
card:
306+
name: internal-assistant
307+
description: AI assistant using internal LiteLLM gateway
308+
309+
# Optional: Agent configuration
310+
config:
311+
systemMessage: "You are a helpful AI assistant."
312+
temperature: 0.7
313+
314+
---
315+
# Example 8: RBAC Configuration for Secret Access
316+
#
317+
# Agents need read access to Secrets containing CA certificates.
318+
# This example shows how to grant appropriate permissions.
319+
320+
apiVersion: rbac.authorization.k8s.io/v1
321+
kind: Role
322+
metadata:
323+
name: agent-tls-secret-reader
324+
namespace: kagent
325+
rules:
326+
# Grant read access to specific Secrets only
327+
- apiGroups: [""]
328+
resources: ["secrets"]
329+
verbs: ["get"]
330+
resourceNames:
331+
- litellm-ca-cert
332+
- corporate-ca-bundle
333+
- strict-ca-cert
334+
# Add other certificate Secrets as needed
335+
336+
---
337+
apiVersion: rbac.authorization.k8s.io/v1
338+
kind: RoleBinding
339+
metadata:
340+
name: agent-tls-secret-reader-binding
341+
namespace: kagent
342+
subjects:
343+
# Bind to default ServiceAccount (or specify custom ServiceAccount)
344+
- kind: ServiceAccount
345+
name: default
346+
namespace: kagent
347+
roleRef:
348+
kind: Role
349+
name: agent-tls-secret-reader
350+
apiGroup: rbac.authorization.k8s.io
351+
352+
---
353+
# Notes and Best Practices
354+
#
355+
# 1. Certificate Format:
356+
# - Must be in PEM format (text-based, base64-encoded)
357+
# - Starts with -----BEGIN CERTIFICATE-----
358+
# - Ends with -----END CERTIFICATE-----
359+
# - No extra whitespace or characters
360+
#
361+
# 2. Secret Management:
362+
# - Store Secrets in the same namespace as ModelConfig
363+
# - Use descriptive names (e.g., "litellm-ca-cert" not "secret1")
364+
# - Rotate certificates before expiration
365+
# - Never commit Secrets to Git (use sealed secrets or external secret management)
366+
#
367+
# 3. Security:
368+
# - Always enable verification (verifyDisabled: false) in production
369+
# - Use RBAC to limit Secret access to specific service accounts
370+
# - Use namespace isolation for different environments
371+
# - Monitor certificate expiry dates
372+
#
373+
# 4. Testing:
374+
# - Test connectivity after configuration changes
375+
# - Check agent logs for TLS warnings or errors
376+
# - Verify certificate chain with openssl commands
377+
# - Use verification disabled mode only for development/testing
378+
#
379+
# 5. Certificate Updates:
380+
# - Update Secret with new certificate
381+
# - Restart agent pods to pick up changes: kubectl rollout restart deployment/agent-<name>
382+
# - Secrets are mounted as volumes and not automatically reloaded
383+
#
384+
# 6. Troubleshooting:
385+
# - See docs/troubleshooting/ssl-errors.md for detailed debugging steps
386+
# - Check agent logs: kubectl logs deployment/agent-<name>
387+
# - Verify Secret is mounted: kubectl exec deployment/agent-<name> -- ls /etc/ssl/certs/custom/
388+
# - Test certificate: kubectl exec deployment/agent-<name> -- openssl x509 -in /etc/ssl/certs/custom/ca.crt -text -noout

0 commit comments

Comments
 (0)