Skip to content

Commit 218523c

Browse files
committed
PR review for secrets and env vars implement suggestion for langfuse secret
Signed-off-by: sallyom <somalley@redhat.com>
1 parent e7c5a2c commit 218523c

File tree

1 file changed

+113
-14
lines changed

1 file changed

+113
-14
lines changed

components/operator/internal/handlers/sessions.go

Lines changed: 113 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,12 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
180180
// Continue - session cleanup is still successful
181181
}
182182

183+
// Cleanup Langfuse secret when session is stopped
184+
if err := deleteAmbientLangfuseSecret(deleteCtx, sessionNamespace); err != nil {
185+
log.Printf("Warning: Failed to cleanup ambient-admin-langfuse-secret from %s: %v", sessionNamespace, err)
186+
// Continue - session cleanup is still successful
187+
}
188+
183189
return nil
184190
}
185191

@@ -290,6 +296,32 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
290296
log.Printf("Vertex AI disabled (CLAUDE_CODE_USE_VERTEX=0), skipping %s secret copy", types.AmbientVertexSecretName)
291297
}
292298

299+
// Check for Langfuse secret in the operator's namespace and copy it if enabled
300+
ambientLangfuseSecretCopied := false
301+
langfuseEnabled := os.Getenv("LANGFUSE_ENABLED") != "" && os.Getenv("LANGFUSE_ENABLED") != "0" && os.Getenv("LANGFUSE_ENABLED") != "false"
302+
303+
if langfuseEnabled {
304+
if langfuseSecret, err := config.K8sClient.CoreV1().Secrets(operatorNamespace).Get(context.TODO(), "ambient-admin-langfuse-secret", v1.GetOptions{}); err == nil {
305+
// Secret exists in operator namespace, copy it to the session namespace
306+
log.Printf("Found ambient-admin-langfuse-secret in %s, copying to %s", operatorNamespace, sessionNamespace)
307+
// Create context with timeout for secret copy operation
308+
copyCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
309+
defer cancel()
310+
if err := copySecretToNamespace(copyCtx, langfuseSecret, sessionNamespace, currentObj); err != nil {
311+
return fmt.Errorf("failed to copy Langfuse secret from %s to %s: %w", operatorNamespace, sessionNamespace, err)
312+
}
313+
ambientLangfuseSecretCopied = true
314+
log.Printf("Successfully copied Langfuse secret to %s", sessionNamespace)
315+
} else if !errors.IsNotFound(err) {
316+
return fmt.Errorf("failed to check for Langfuse secret in %s: %w", operatorNamespace, err)
317+
} else {
318+
// Langfuse enabled but secret not found - log warning and continue without Langfuse
319+
log.Printf("Warning: LANGFUSE_ENABLED is set but ambient-admin-langfuse-secret not found in namespace %s. Langfuse observability will be disabled for this session.", operatorNamespace)
320+
}
321+
} else {
322+
log.Printf("Langfuse disabled, skipping secret copy")
323+
}
324+
293325
// Create a Kubernetes Job for this AgenticSession
294326
jobName := fmt.Sprintf("%s-job", name)
295327

@@ -503,20 +535,54 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
503535
base = append(base, corev1.EnvVar{Name: "USER_NAME", Value: userName})
504536
}
505537

506-
// Platform-wide Langfuse observability configuration (injected from operator env)
507-
// Uses explicit env vars instead of EnvFrom to prevent automatic exposure of future secret keys
508-
// All LANGFUSE_* vars come from ambient-admin-langfuse-secret Secret (platform-admin managed)
509-
if os.Getenv("LANGFUSE_ENABLED") != "" {
510-
base = append(base, corev1.EnvVar{Name: "LANGFUSE_ENABLED", Value: os.Getenv("LANGFUSE_ENABLED")})
511-
}
512-
if os.Getenv("LANGFUSE_HOST") != "" {
513-
base = append(base, corev1.EnvVar{Name: "LANGFUSE_HOST", Value: os.Getenv("LANGFUSE_HOST")})
514-
}
515-
if os.Getenv("LANGFUSE_PUBLIC_KEY") != "" {
516-
base = append(base, corev1.EnvVar{Name: "LANGFUSE_PUBLIC_KEY", Value: os.Getenv("LANGFUSE_PUBLIC_KEY")})
517-
}
518-
if os.Getenv("LANGFUSE_SECRET_KEY") != "" {
519-
base = append(base, corev1.EnvVar{Name: "LANGFUSE_SECRET_KEY", Value: os.Getenv("LANGFUSE_SECRET_KEY")})
538+
// Platform-wide Langfuse observability configuration
539+
// Uses secretKeyRef to prevent credential exposure in pod specs
540+
// Secret is copied to session namespace from operator namespace
541+
// All keys are optional to prevent pod startup failures if keys are missing
542+
if ambientLangfuseSecretCopied {
543+
base = append(base,
544+
corev1.EnvVar{
545+
Name: "LANGFUSE_ENABLED",
546+
ValueFrom: &corev1.EnvVarSource{
547+
SecretKeyRef: &corev1.SecretKeySelector{
548+
LocalObjectReference: corev1.LocalObjectReference{Name: "ambient-admin-langfuse-secret"},
549+
Key: "LANGFUSE_ENABLED",
550+
Optional: boolPtr(true),
551+
},
552+
},
553+
},
554+
corev1.EnvVar{
555+
Name: "LANGFUSE_HOST",
556+
ValueFrom: &corev1.EnvVarSource{
557+
SecretKeyRef: &corev1.SecretKeySelector{
558+
LocalObjectReference: corev1.LocalObjectReference{Name: "ambient-admin-langfuse-secret"},
559+
Key: "LANGFUSE_HOST",
560+
Optional: boolPtr(true),
561+
},
562+
},
563+
},
564+
corev1.EnvVar{
565+
Name: "LANGFUSE_PUBLIC_KEY",
566+
ValueFrom: &corev1.EnvVarSource{
567+
SecretKeyRef: &corev1.SecretKeySelector{
568+
LocalObjectReference: corev1.LocalObjectReference{Name: "ambient-admin-langfuse-secret"},
569+
Key: "LANGFUSE_PUBLIC_KEY",
570+
Optional: boolPtr(true),
571+
},
572+
},
573+
},
574+
corev1.EnvVar{
575+
Name: "LANGFUSE_SECRET_KEY",
576+
ValueFrom: &corev1.EnvVarSource{
577+
SecretKeyRef: &corev1.SecretKeySelector{
578+
LocalObjectReference: corev1.LocalObjectReference{Name: "ambient-admin-langfuse-secret"},
579+
Key: "LANGFUSE_SECRET_KEY",
580+
Optional: boolPtr(true),
581+
},
582+
},
583+
},
584+
)
585+
log.Printf("Langfuse env vars configured via secretKeyRef for session %s", name)
520586
}
521587

522588
// Add Vertex AI configuration only if enabled
@@ -1127,6 +1193,12 @@ func deleteJobAndPerJobService(namespace, jobName, sessionName string) error {
11271193
// Don't return error - this is a non-critical cleanup step
11281194
}
11291195

1196+
// Delete the Langfuse secret if it was copied by the operator
1197+
if err := deleteAmbientLangfuseSecret(deleteCtx, namespace); err != nil {
1198+
log.Printf("Failed to delete ambient-admin-langfuse-secret from %s: %v", namespace, err)
1199+
// Don't return error - this is a non-critical cleanup step
1200+
}
1201+
11301202
// NOTE: PVC is kept for all sessions and only deleted via garbage collection
11311203
// when the session CR is deleted. This allows sessions to be restarted.
11321204

@@ -1409,6 +1481,33 @@ func deleteAmbientVertexSecret(ctx context.Context, namespace string) error {
14091481
return nil
14101482
}
14111483

1484+
// deleteAmbientLangfuseSecret deletes the ambient-admin-langfuse-secret from a namespace if it was copied
1485+
func deleteAmbientLangfuseSecret(ctx context.Context, namespace string) error {
1486+
const langfuseSecretName = "ambient-admin-langfuse-secret"
1487+
secret, err := config.K8sClient.CoreV1().Secrets(namespace).Get(ctx, langfuseSecretName, v1.GetOptions{})
1488+
if err != nil {
1489+
if errors.IsNotFound(err) {
1490+
// Secret doesn't exist, nothing to do
1491+
return nil
1492+
}
1493+
return fmt.Errorf("error checking for %s secret: %w", langfuseSecretName, err)
1494+
}
1495+
1496+
// Check if this was a copied secret (has the annotation)
1497+
if _, ok := secret.Annotations[types.CopiedFromAnnotation]; !ok {
1498+
log.Printf("%s secret in namespace %s was not copied by operator, not deleting", langfuseSecretName, namespace)
1499+
return nil
1500+
}
1501+
1502+
log.Printf("Deleting copied %s secret from namespace %s", langfuseSecretName, namespace)
1503+
err = config.K8sClient.CoreV1().Secrets(namespace).Delete(ctx, langfuseSecretName, v1.DeleteOptions{})
1504+
if err != nil && !errors.IsNotFound(err) {
1505+
return fmt.Errorf("failed to delete %s secret: %w", langfuseSecretName, err)
1506+
}
1507+
1508+
return nil
1509+
}
1510+
14121511
// Helper functions
14131512
var (
14141513
boolPtr = func(b bool) *bool { return &b }

0 commit comments

Comments
 (0)