From 3e0f280676009f1fbc141ade960ca0a6932b9119 Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Thu, 27 Nov 2025 20:58:08 +0100 Subject: [PATCH 1/8] chore: Refactor authentication and secret management in environment templates --- .env.template | 9 +-- Tiltfile | 7 +- .../rag/templates/backend/secrets.yaml | 25 ++++--- .../rag/templates/frontend/secrets.yaml | 5 +- infrastructure/rag/templates/secrets.yaml | 6 +- infrastructure/rag/values.yaml | 67 +++++++++++++++---- 6 files changed, 81 insertions(+), 38 deletions(-) diff --git a/.env.template b/.env.template index 4c837066..a85d8baf 100644 --- a/.env.template +++ b/.env.template @@ -10,7 +10,8 @@ S3_SECRET_ACCESS_KEY=your_s3_secret_key_here # ============================================================================= # Basic Authentication (Required) # ============================================================================= -BASIC_AUTH="foo:$apr1$ryE0iE7H$F2SlPDNoFdGoaHrcla2HL/" +BASIC_AUTH_USER=foo +BASIC_AUTH_PASSWORD=bar # ============================================================================= # Langfuse Configuration (Required for observability) @@ -27,12 +28,6 @@ LANGFUSE_INIT_USER_EMAIL="user@stackit.cloud" LANGFUSE_INIT_USER_NAME="stackiteer" LANGFUSE_INIT_USER_PASSWORD="stackit123" -# ============================================================================= -# Frontend Authentication (Required) -# ============================================================================= -VITE_AUTH_USERNAME=foo -VITE_AUTH_PASSWORD=bar - # ============================================================================= # LLM Provider API Keys (Choose one or more) # ============================================================================= diff --git a/Tiltfile b/Tiltfile index cecbc2ac..b1c7c2b6 100644 --- a/Tiltfile +++ b/Tiltfile @@ -471,12 +471,13 @@ value_override = [ # secrets env "shared.secrets.s3.accessKey=%s" % os.environ["S3_ACCESS_KEY_ID"], "shared.secrets.s3.secretKey=%s" % os.environ["S3_SECRET_ACCESS_KEY"], - "backend.secrets.basicAuth=%s" % os.environ["BASIC_AUTH"], + "shared.secrets.basicAuthUser=%s" % os.environ["BASIC_AUTH_USER"], + "shared.secrets.basicAuthPassword=%s" % os.environ["BASIC_AUTH_PASSWORD"], "backend.secrets.langfuse.publicKey=%s" % os.environ["LANGFUSE_PUBLIC_KEY"], "backend.secrets.langfuse.secretKey=%s" % os.environ["LANGFUSE_SECRET_KEY"], "backend.secrets.ragas.openaiApikey=%s" % os.environ["RAGAS_OPENAI_API_KEY"], - "frontend.secrets.viteAuth.VITE_AUTH_USERNAME=%s" % os.environ["VITE_AUTH_USERNAME"], - "frontend.secrets.viteAuth.VITE_AUTH_PASSWORD=%s" % os.environ["VITE_AUTH_PASSWORD"], + "frontend.secrets.viteAuth.VITE_AUTH_USERNAME=%s" % os.environ["BASIC_AUTH_USER"],#TODO + "frontend.secrets.viteAuth.VITE_AUTH_PASSWORD=%s" % os.environ["BASIC_AUTH_PASSWORD"], # variables "shared.debug.backend.enabled=%s" % backend_debug, "features.frontend.enabled=true", diff --git a/infrastructure/rag/templates/backend/secrets.yaml b/infrastructure/rag/templates/backend/secrets.yaml index c4828b67..2bf4b4a9 100644 --- a/infrastructure/rag/templates/backend/secrets.yaml +++ b/infrastructure/rag/templates/backend/secrets.yaml @@ -1,43 +1,50 @@ +{{- if and $.Values.shared.secrets.basicAuthUser.value $.Values.shared.secrets.basicAuthPassword.value }} apiVersion: v1 data: - auth: {{ .Values.backend.secrets.basicAuth | b64enc }} - {{- range $key, $value := .Values.backend.secrets.auth }} - {{ $key }}: {{ $value | b64enc }} - {{- end }} + auth: {{ htpasswd .Values.shared.secrets.basicAuthUser.value .Values.shared.secrets.basicAuthPassword.value | b64enc }} kind: Secret metadata: name: basic-auth type: Opaque +{{- end }} --- +{{- if and .Values.backend.secrets.langfuse.publicKey.value .Values.backend.secrets.langfuse.secretKey.value }} apiVersion: v1 kind: Secret metadata: name: {{ template "secret.langfuseName" . }} type: Opaque data: - LANGFUSE_PUBLIC_KEY: {{ .Values.backend.secrets.langfuse.publicKey | b64enc }} - LANGFUSE_SECRET_KEY: {{ .Values.backend.secrets.langfuse.secretKey | b64enc }} + LANGFUSE_PUBLIC_KEY: {{ .Values.backend.secrets.langfuse.publicKey.value | b64enc }} + LANGFUSE_SECRET_KEY: {{ .Values.backend.secrets.langfuse.secretKey.value | b64enc }} +{{- end }} --- +{{- if .Values.backend.secrets.stackitVllm.apiKey.value }} apiVersion: v1 kind: Secret metadata: name: {{ template "secret.stackitVllmName" . }} type: Opaque data: - STACKIT_VLLM_API_KEY: {{ .Values.backend.secrets.stackitVllm.apiKey | b64enc }} + STACKIT_VLLM_API_KEY: {{ .Values.backend.secrets.stackitVllm.apiKey.value | b64enc }} +{{- end }} --- +{{- if .Values.backend.secrets.stackitEmbedder.apiKey.value }} apiVersion: v1 kind: Secret metadata: name: {{ template "secret.stackitEmbedderName" . }} type: Opaque data: - STACKIT_EMBEDDER_API_KEY: {{ .Values.backend.secrets.stackitEmbedder.apiKey | b64enc }} + STACKIT_EMBEDDER_API_KEY: {{ .Values.backend.secrets.stackitEmbedder.apiKey.value | b64enc }} +{{- end }} --- +{{- if .Values.backend.secrets.ragas.openaiApikey.value }} apiVersion: v1 kind: Secret metadata: name: {{ template "secret.ragasName" . }} type: Opaque data: - RAGAS_OPENAI_API_KEY: {{ .Values.backend.secrets.ragas.openaiApikey | b64enc }} + RAGAS_OPENAI_API_KEY: {{ .Values.backend.secrets.ragas.openaiApikey.value | b64enc }} +{{- end }} diff --git a/infrastructure/rag/templates/frontend/secrets.yaml b/infrastructure/rag/templates/frontend/secrets.yaml index 416614a9..7d5a156f 100644 --- a/infrastructure/rag/templates/frontend/secrets.yaml +++ b/infrastructure/rag/templates/frontend/secrets.yaml @@ -1,9 +1,8 @@ {{- if $.Values.features.frontend.enabled }} apiVersion: v1 data: - {{- range $key, $value := .Values.frontend.secrets.viteAuth }} - {{ $key }}: {{ $value | b64enc }} - {{- end }} + VITE_AUTH_USERNAME: {{ .Values.shared.secrets.basicAuthUser.value | b64enc }} + VITE_AUTH_PASSWORD: {{ .Values.shared.secrets.basicAuthPassword.value | b64enc }} kind: Secret metadata: name: vite-auth diff --git a/infrastructure/rag/templates/secrets.yaml b/infrastructure/rag/templates/secrets.yaml index e85957fd..8c4410a7 100644 --- a/infrastructure/rag/templates/secrets.yaml +++ b/infrastructure/rag/templates/secrets.yaml @@ -1,11 +1,13 @@ +{{- if and .Values.shared.secrets.s3.accessKey.value .Values.shared.secrets.s3.secretKey.value }} apiVersion: v1 kind: Secret metadata: name: {{ template "secret.s3Name" . }} type: Opaque data: - S3_ACCESS_KEY_ID: {{ .Values.shared.secrets.s3.accessKey | b64enc }} - S3_SECRET_ACCESS_KEY: {{ .Values.shared.secrets.s3.secretKey | b64enc }} + S3_ACCESS_KEY_ID: {{ .Values.shared.secrets.s3.accessKey.value | b64enc }} + S3_SECRET_ACCESS_KEY: {{ .Values.shared.secrets.s3.secretKey.value | b64enc }} +{{- end }} --- apiVersion: v1 kind: Secret diff --git a/infrastructure/rag/values.yaml b/infrastructure/rag/values.yaml index c8d95a29..77362c3e 100644 --- a/infrastructure/rag/values.yaml +++ b/infrastructure/rag/values.yaml @@ -145,16 +145,35 @@ backend: port: 8080 secrets: - basicAuth: "" langfuse: - publicKey: "pk-lf" - secretKey: "sk-lf" + publicKey: + value: "pk-lf" + secretKeyRef: + name: "" + key: "LANGFUSE_PUBLIC_KEY" + secretKey: + value: "sk-lf" + secretKeyRef: + name: "" + key: "LANGFUSE_SECRET_KEY" stackitEmbedder: - apiKey: "" + apiKey: + value: "" + secretKeyRef: + name: "" + key: "STACKIT_EMBEDDER_API_KEY" stackitVllm: - apiKey: "sk-123" + apiKey: + value: "sk-123" + secretKeyRef: + name: "" + key: "STACKIT_VLLM_API_KEY" ragas: - openaiApikey: "" + openaiApikey: + value: "" + secretKeyRef: + name: "" + key: "RAGAS_OPENAI_API_KEY" envs: stackitVllm: @@ -244,11 +263,6 @@ frontend: pathType: ImplementationSpecific port: 8080 - secrets: - viteAuth: - VITE_AUTH_USERNAME: "" - VITE_AUTH_PASSWORD: "" - envs: vite: VITE_CHAT_AUTH_ENABLED: true @@ -461,10 +475,29 @@ shared: issuerKind: ClusterIssuer secrets: + basicAuthUser: + value: "" + secretKeyRef: + name: "" + key: "BASIC_AUTH_USER" + basicAuthPassword: + value: "" + secretKeyRef: + name: "" + key: "BASIC_AUTH_PASSWORD" + s3: - accessKey: "admin" - secretKey: "adminpassword" - usecase: + accessKey: + value: "admin" + secretKeyRef: + name: "" + key: "S3_ACCESS_KEY_ID" + secretKey: + value: "adminpassword" + secretKeyRef: + name: "" + key: "S3_SECRET_ACCESS_KEY" + usecase: {} envs: @@ -488,6 +521,9 @@ langfuse: # Used to hash API keys salt: value: "changeme" + secretKeyRef: + name: "" + key: "" # Authentication settings features: @@ -514,6 +550,9 @@ langfuse: url: http://localhost:3000 secret: value: "changeme" + secretKeyRef: + name: "" + key: "" # Additional environment variables (only for init values) additionalEnv: From ce8f1523ce95e5246987935f779c4fcb7d30a3ed Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Thu, 27 Nov 2025 21:47:31 +0100 Subject: [PATCH 2/8] chore: Enhance basic authentication setup and secret management in deployment templates --- .env.template | 1 + README.md | 26 +++++---- Tiltfile | 20 +++---- infrastructure/README.md | 58 ++++++++++++++----- .../_admin_backend_and_extractor_helpers.tpl | 36 ++++++++++++ .../rag/templates/_backend_helpers.tpl | 46 ++++++++++++++- .../templates/admin-backend/deployment.yaml | 8 +-- .../rag/templates/backend/deployment.yaml | 8 +-- .../rag/templates/backend/secrets.yaml | 2 +- infrastructure/rag/values.yaml | 35 ++++++++--- 10 files changed, 186 insertions(+), 54 deletions(-) diff --git a/.env.template b/.env.template index a85d8baf..95be1696 100644 --- a/.env.template +++ b/.env.template @@ -10,6 +10,7 @@ S3_SECRET_ACCESS_KEY=your_s3_secret_key_here # ============================================================================= # Basic Authentication (Required) # ============================================================================= +# Used for backend/admin endpoints and reused by the frontend's auth prompt. BASIC_AUTH_USER=foo BASIC_AUTH_PASSWORD=bar diff --git a/README.md b/README.md index 6171103e..2ecfd87f 100644 --- a/README.md +++ b/README.md @@ -208,28 +208,33 @@ For local deployment, a few env variables need to be provided by an `.env` file The `.env` needs to contain the following values: ```dotenv -BASIC_AUTH=Zm9vOiRhcHIxJGh1VDVpL0ZKJG10elZQUm1IM29JQlBVMlZ4YkpUQy8K +# Basic auth (used by backend/admin ingress and the frontend prompt) +BASIC_AUTH_USER=... +BASIC_AUTH_PASSWORD=... S3_ACCESS_KEY_ID=... S3_SECRET_ACCESS_KEY=... -VITE_AUTH_USERNAME=... -VITE_AUTH_PASSWORD=... +LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +# Optional keys RAGAS_OPENAI_API_KEY=... - STACKIT_VLLM_API_KEY=... STACKIT_EMBEDDER_API_KEY=... -# ONLY necessary, if no init values are set. if init values are set, -# the following two values should match the init values or be commented out -# or be created via the langfuse UI. -LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +# Optional Langfuse init values (omit if you already created a project/user) +LANGFUSE_INIT_ORG_ID=... +LANGFUSE_INIT_PROJECT_ID=... +LANGFUSE_INIT_PROJECT_PUBLIC_KEY=... +LANGFUSE_INIT_PROJECT_SECRET_KEY=... +LANGFUSE_INIT_USER_EMAIL=... +LANGFUSE_INIT_USER_NAME=... +LANGFUSE_INIT_USER_PASSWORD=... ``` -This results in a basic auth with username=`foo` and password=`bar`. +Using the defaults in `.env.template` results in a basic auth with username=`foo` and password=`bar`. > 📝 NOTE: All values containing `...` are placeholders and have to be replaced with real values. > This deployment comes with multiple options. You change the `global.config.envs.rag_class_types.RAG_CLASS_TYPE_LLM_TYPE` in the helm-deployment to on of the following values: @@ -483,4 +488,3 @@ The linting-settings can be changed in the `services/rag-backend/pyproject.toml` ## 4. Contribution Guidelines In order to contribute please consult the [CONTRIBUTING.md](./CONTRIBUTING.md). - diff --git a/Tiltfile b/Tiltfile index b1c7c2b6..02e37bc2 100644 --- a/Tiltfile +++ b/Tiltfile @@ -469,15 +469,13 @@ docker_build( ######################################################################################################################## value_override = [ # secrets env - "shared.secrets.s3.accessKey=%s" % os.environ["S3_ACCESS_KEY_ID"], - "shared.secrets.s3.secretKey=%s" % os.environ["S3_SECRET_ACCESS_KEY"], - "shared.secrets.basicAuthUser=%s" % os.environ["BASIC_AUTH_USER"], - "shared.secrets.basicAuthPassword=%s" % os.environ["BASIC_AUTH_PASSWORD"], - "backend.secrets.langfuse.publicKey=%s" % os.environ["LANGFUSE_PUBLIC_KEY"], - "backend.secrets.langfuse.secretKey=%s" % os.environ["LANGFUSE_SECRET_KEY"], - "backend.secrets.ragas.openaiApikey=%s" % os.environ["RAGAS_OPENAI_API_KEY"], - "frontend.secrets.viteAuth.VITE_AUTH_USERNAME=%s" % os.environ["BASIC_AUTH_USER"],#TODO - "frontend.secrets.viteAuth.VITE_AUTH_PASSWORD=%s" % os.environ["BASIC_AUTH_PASSWORD"], + "shared.secrets.s3.accessKey.value=%s" % os.environ["S3_ACCESS_KEY_ID"], + "shared.secrets.s3.secretKey.value=%s" % os.environ["S3_SECRET_ACCESS_KEY"], + "shared.secrets.basicAuthUser.value=%s" % os.environ["BASIC_AUTH_USER"], + "shared.secrets.basicAuthPassword.value=%s" % os.environ["BASIC_AUTH_PASSWORD"], + "backend.secrets.langfuse.publicKey.value=%s" % os.environ["LANGFUSE_PUBLIC_KEY"], + "backend.secrets.langfuse.secretKey.value=%s" % os.environ["LANGFUSE_SECRET_KEY"], + "backend.secrets.ragas.openaiApikey.value=%s" % os.environ["RAGAS_OPENAI_API_KEY"], # variables "shared.debug.backend.enabled=%s" % backend_debug, "features.frontend.enabled=true", @@ -533,13 +531,13 @@ if has_confluence_config(): if os.environ.get("STACKIT_VLLM_API_KEY", False): stackit_vllm_settings = [ - "backend.secrets.stackitVllm.apiKey=%s" % os.environ["STACKIT_VLLM_API_KEY"], + "backend.secrets.stackitVllm.apiKey.value=%s" % os.environ["STACKIT_VLLM_API_KEY"], ] value_override.extend(stackit_vllm_settings) if os.environ.get("STACKIT_EMBEDDER_API_KEY", False): stackit_embedder_settings = [ - "backend.secrets.stackitEmbedder.apiKey=%s" % os.environ["STACKIT_EMBEDDER_API_KEY"], + "backend.secrets.stackitEmbedder.apiKey.value=%s" % os.environ["STACKIT_EMBEDDER_API_KEY"], ] value_override.extend(stackit_embedder_settings) diff --git a/infrastructure/README.md b/infrastructure/README.md index 887e7ea5..f7449e3a 100644 --- a/infrastructure/README.md +++ b/infrastructure/README.md @@ -233,6 +233,20 @@ langfuse: The following values should be adjusted for the deployment: ```yaml +shared: + secrets: + # Required: Basic authentication used by backend/admin ingress and frontend auth modal + basicAuthUser: + value: ... # Username for basic auth + secretKeyRef: + name: "" # Optionally reference an existing secret instead of an inline value + key: "BASIC_AUTH_USER" + basicAuthPassword: + value: ... # Password for basic auth + secretKeyRef: + name: "" + key: "BASIC_AUTH_PASSWORD" + frontend: envs: vite: @@ -245,12 +259,6 @@ frontend: ingress: host: name: ... # Your domain name (e.g., rag.yourdomain.com) - - secrets: - viteAuth: - # Required: Credentials for backend authentication - VITE_AUTH_USERNAME: ... # Username for basic auth - VITE_AUTH_PASSWORD: ... # Password for basic auth ``` ### 1.5 Backend @@ -260,24 +268,42 @@ The following values should be adjusted for the deployment: ```yaml backend: secrets: - # Required: Basic authentication for the backend API - basicAuth: ... # Set your basic auth credentials - + # Basic auth is configured under shared.secrets (see frontend section) # Required: Langfuse API keys for observability langfuse: - publicKey: ... # Your Langfuse public key - secretKey: ... # Your Langfuse secret key + publicKey: + value: ... # Your Langfuse public key + secretKeyRef: + name: "" # Optionally reference an existing secret instead of an inline value + key: "LANGFUSE_PUBLIC_KEY" + secretKey: + value: ... # Your Langfuse secret key + secretKeyRef: + name: "" + key: "LANGFUSE_SECRET_KEY" # Required: API keys for your chosen LLM provider # STACKIT LLM provider stackitEmbedder: - apiKey: ... # Your STACKIT embedder API key + apiKey: + value: ... # Your STACKIT embedder API key + secretKeyRef: + name: "" + key: "STACKIT_EMBEDDER_API_KEY" stackitVllm: - apiKey: ... # Your STACKIT vLLM API key + apiKey: + value: ... # Your STACKIT vLLM API key + secretKeyRef: + name: "" + key: "STACKIT_VLLM_API_KEY" # Optional: Only needed if using RAGAS evaluation with OpenAI ragas: - openaiApikey: ... # Your OpenAI API key for RAGAS evaluation + openaiApikey: + value: ... # Your OpenAI API key for RAGAS evaluation + secretKeyRef: + name: "" + key: "RAGAS_OPENAI_API_KEY" envs: # Required: Choose your LLM and embedder providers @@ -310,13 +336,15 @@ backend: ERROR_MESSAGES_NO_ANSWER_FOUND: "I'm sorry, I couldn't find an answer with the context provided." # Settings for the evaluation. You can specify the datasetname, as well as the path (in the container) where the dataset is located. langfuse: - LANGFUSE_DATASET_NAME: "test_ds" + LANGFUSE_DATASET_NAME: "rag_test_ds" LANGFUSE_DATASET_FILENAME: "/app/test_data.json" ragas: RAGAS_IS_DEBUG: false RAGAS_MODEL: "gpt-4o-mini" RAGAS_USE_OPENAI: true + RAGAS_TIMEOUT: 60 + RAGAS_EVALUATION_DATASET_NAME: "eval-data" RAGAS_MAX_CONCURRENCY: "5" ingress: diff --git a/infrastructure/rag/templates/_admin_backend_and_extractor_helpers.tpl b/infrastructure/rag/templates/_admin_backend_and_extractor_helpers.tpl index 5f851477..92fd1bfe 100644 --- a/infrastructure/rag/templates/_admin_backend_and_extractor_helpers.tpl +++ b/infrastructure/rag/templates/_admin_backend_and_extractor_helpers.tpl @@ -15,6 +15,42 @@ {{- printf "%s-stackit-vllm-secret" .Release.Name | trunc 63 | trimSuffix "-" -}} {{- end -}} +{{- define "secret.langfuseRefName" -}} +{{- if .Values.backend.secrets.langfuse.publicKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.langfuse.publicKey.secretKeyRef.name -}} +{{- else if .Values.backend.secrets.langfuse.secretKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.langfuse.secretKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.langfuseName" . }} +{{- end -}} +{{- end -}} + +{{- define "secret.stackitVllmRefName" -}} +{{- if .Values.backend.secrets.stackitVllm.apiKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.stackitVllm.apiKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.stackitVllmName" . }} +{{- end -}} +{{- end -}} + +{{- define "secret.stackitEmbedderRefName" -}} +{{- if .Values.backend.secrets.stackitEmbedder.apiKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.stackitEmbedder.apiKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.stackitEmbedderName" . }} +{{- end -}} +{{- end -}} + +{{- define "secret.s3RefName" -}} +{{- if .Values.shared.secrets.s3.accessKey.secretKeyRef.name -}} +{{- .Values.shared.secrets.s3.accessKey.secretKeyRef.name -}} +{{- else if .Values.shared.secrets.s3.secretKey.secretKeyRef.name -}} +{{- .Values.shared.secrets.s3.secretKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.s3Name" . }} +{{- end -}} +{{- end -}} + # configmaps {{- define "configmap.s3Name" -}} {{- printf "%s-s3-configmap" .Release.Name | trunc 63 | trimSuffix "-" -}} diff --git a/infrastructure/rag/templates/_backend_helpers.tpl b/infrastructure/rag/templates/_backend_helpers.tpl index f1bdb14e..404e34b5 100644 --- a/infrastructure/rag/templates/_backend_helpers.tpl +++ b/infrastructure/rag/templates/_backend_helpers.tpl @@ -19,6 +19,50 @@ {{- printf "%s-stackit-ragas-secret" .Release.Name | trunc 63 | trimSuffix "-" -}} {{- end -}} +{{- define "secret.basicAuthName" -}} +{{- if .Values.shared.secrets.basicAuthUser.secretKeyRef.name -}} +{{- .Values.shared.secrets.basicAuthUser.secretKeyRef.name -}} +{{- else if .Values.shared.secrets.basicAuthPassword.secretKeyRef.name -}} +{{- .Values.shared.secrets.basicAuthPassword.secretKeyRef.name -}} +{{- else -}} +basic-auth +{{- end -}} +{{- end -}} + +{{- define "secret.langfuseRefName" -}} +{{- if .Values.backend.secrets.langfuse.publicKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.langfuse.publicKey.secretKeyRef.name -}} +{{- else if .Values.backend.secrets.langfuse.secretKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.langfuse.secretKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.langfuseName" . }} +{{- end -}} +{{- end -}} + +{{- define "secret.stackitEmbedderRefName" -}} +{{- if .Values.backend.secrets.stackitEmbedder.apiKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.stackitEmbedder.apiKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.stackitEmbedderName" . }} +{{- end -}} +{{- end -}} + +{{- define "secret.stackitVllmRefName" -}} +{{- if .Values.backend.secrets.stackitVllm.apiKey.secretKeyRef.name -}} +{{- .Values.backend.secrets.stackitVllm.apiKey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.stackitVllmName" . }} +{{- end -}} +{{- end -}} + +{{- define "secret.ragasRefName" -}} +{{- if .Values.backend.secrets.ragas.openaiApikey.secretKeyRef.name -}} +{{- .Values.backend.secrets.ragas.openaiApikey.secretKeyRef.name -}} +{{- else -}} +{{ template "secret.ragasName" . }} +{{- end -}} +{{- end -}} + # configmaps {{- define "configmap.publicName" -}} @@ -109,7 +153,7 @@ {{- define "backend.ingress.commonAnnotations" -}} {{- if .Values.shared.config.basicAuth.enabled }} nginx.ingress.kubernetes.io/auth-type: basic -nginx.ingress.kubernetes.io/auth-secret: basic-auth +nginx.ingress.kubernetes.io/auth-secret: {{ template "secret.basicAuthName" . }} {{- end }} nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-read-timeout: "6000" diff --git a/infrastructure/rag/templates/admin-backend/deployment.yaml b/infrastructure/rag/templates/admin-backend/deployment.yaml index d86baffd..d2c2012e 100644 --- a/infrastructure/rag/templates/admin-backend/deployment.yaml +++ b/infrastructure/rag/templates/admin-backend/deployment.yaml @@ -122,15 +122,15 @@ spec: - configMapRef: name: {{ template "configmap.chunkerName" . }} - secretRef: - name: {{ template "secret.langfuseName" . }} + name: {{ template "secret.langfuseRefName" . }} - secretRef: name: {{ template "secret.usecaseName" . }} - secretRef: - name: {{ template "secret.s3Name" . }} + name: {{ template "secret.s3RefName" . }} - secretRef: - name: {{ template "secret.stackitVllmName" . }} + name: {{ template "secret.stackitVllmRefName" . }} - secretRef: - name: {{ template "secret.stackitEmbedderName" . }} + name: {{ template "secret.stackitEmbedderRefName" . }} env: - name: PYTHONPATH value: {{ .Values.adminBackend.pythonPathEnv.PYTHONPATH }} diff --git a/infrastructure/rag/templates/backend/deployment.yaml b/infrastructure/rag/templates/backend/deployment.yaml index c3dfbf44..5a89b19a 100644 --- a/infrastructure/rag/templates/backend/deployment.yaml +++ b/infrastructure/rag/templates/backend/deployment.yaml @@ -134,15 +134,15 @@ spec: - configMapRef: name: {{ template "configmap.retryDecoratorName" . }} - secretRef: - name: {{ template "secret.langfuseName" . }} + name: {{ template "secret.langfuseRefName" . }} - secretRef: - name: {{ template "secret.stackitVllmName" . }} + name: {{ template "secret.stackitVllmRefName" . }} - secretRef: name: {{ template "secret.usecaseName" . }} - secretRef: - name: {{ template "secret.stackitEmbedderName" . }} + name: {{ template "secret.stackitEmbedderRefName" . }} - secretRef: - name: {{ template "secret.ragasName" . }} + name: {{ template "secret.ragasRefName" . }} env: - name: PYTHONPATH value: {{ .Values.backend.pythonPathEnv.PYTHONPATH }} diff --git a/infrastructure/rag/templates/backend/secrets.yaml b/infrastructure/rag/templates/backend/secrets.yaml index 2bf4b4a9..08d873cc 100644 --- a/infrastructure/rag/templates/backend/secrets.yaml +++ b/infrastructure/rag/templates/backend/secrets.yaml @@ -4,7 +4,7 @@ data: auth: {{ htpasswd .Values.shared.secrets.basicAuthUser.value .Values.shared.secrets.basicAuthPassword.value | b64enc }} kind: Secret metadata: - name: basic-auth + name: {{ template "secret.basicAuthName" . }} type: Opaque {{- end }} --- diff --git a/infrastructure/rag/values.yaml b/infrastructure/rag/values.yaml index 77362c3e..1939136a 100644 --- a/infrastructure/rag/values.yaml +++ b/infrastructure/rag/values.yaml @@ -557,19 +557,40 @@ langfuse: # Additional environment variables (only for init values) additionalEnv: - name: LANGFUSE_INIT_ORG_ID - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_ORG_ID" - name: LANGFUSE_INIT_PROJECT_ID - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_PROJECT_ID" - name: LANGFUSE_INIT_PROJECT_PUBLIC_KEY - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_PROJECT_PUBLIC_KEY" - name: LANGFUSE_INIT_PROJECT_SECRET_KEY - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_PROJECT_SECRET_KEY" - name: LANGFUSE_INIT_USER_EMAIL - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_USER_EMAIL" - name: LANGFUSE_INIT_USER_NAME - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_USER_NAME" - name: LANGFUSE_INIT_USER_PASSWORD - value: "" + valueFrom: + secretKeyRef: + name: "langfuse-init-secrets" + key: "LANGFUSE_INIT_USER_PASSWORD" # Additional init containers extraInitContainers: From 17f88ce0b30e194c986b88bc31e7ba86d047432c Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Thu, 27 Nov 2025 22:00:45 +0100 Subject: [PATCH 3/8] chore: Add Langfuse init secrets management for local development with Kustomize and Tilt --- .gitignore | 1 + README.md | 6 +++++ Tiltfile | 23 +++++++------------ infrastructure/README.md | 6 +++++ .../kustomize/langfuse/.env.langfuse.template | 8 +++++++ .../kustomize/langfuse/kustomization.yaml | 12 ++++++++++ 6 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 infrastructure/kustomize/langfuse/.env.langfuse.template create mode 100644 infrastructure/kustomize/langfuse/kustomization.yaml diff --git a/.gitignore b/.gitignore index 4becb20d..e168b724 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +**/.env.langfuse **/.nx/* *.tgz */Chart.lock diff --git a/README.md b/README.md index 2ecfd87f..9cc2a253 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,12 @@ Using the defaults in `.env.template` results in a basic auth with username=`foo > - `ollama`: Uses ollama as an LLM provider. > +##### Langfuse init secret (dev-only, Tilt + Kustomize) + +- Copy `infrastructure/kustomize/langfuse/.env.langfuse.template` to `infrastructure/kustomize/langfuse/.env.langfuse` and fill in your Langfuse init values (org/project/user and API keys) before starting Tilt. +- Tilt runs Kustomize automatically to create a stable `langfuse-init-secrets` secret before Helm applies manifests. +- Use this helper only for local/dev. For production, manage secrets via your usual mechanism and point `secretKeyRef.name` in `values.yaml` to your precreated secrets. + #### 1.4.1 Environment Variables Setup Before running the application, you need to configure environment variables. Copy the provided example file and fill in your values: diff --git a/Tiltfile b/Tiltfile index 02e37bc2..6e1c73cf 100644 --- a/Tiltfile +++ b/Tiltfile @@ -320,6 +320,14 @@ local_resource( allow_parallel=True, ) +# Dev-only Langfuse init secrets via Kustomize (stable name, no hash suffix) +langfuse_kustomize_dir = "./infrastructure/kustomize/langfuse" +langfuse_env_file = "%s/.env.langfuse" % langfuse_kustomize_dir +if os.path.exists(langfuse_env_file): + watch_file(langfuse_env_file) + watch_file("%s/kustomization.yaml" % langfuse_kustomize_dir) + k8s_yaml(kustomize(langfuse_kustomize_dir)) + ######################################################################################################################## ################################## build document extractor image and do live update ############################################## ######################################################################################################################## @@ -486,21 +494,6 @@ value_override = [ "features.mcp.enabled=true", # ingress host names "backend.ingress.host.name=rag.localhost", - # langfuse - "langfuse.langfuse.additionalEnv[0].name=LANGFUSE_INIT_ORG_ID", - "langfuse.langfuse.additionalEnv[0].value=\"%s\"" % os.environ["LANGFUSE_INIT_ORG_ID"], - "langfuse.langfuse.additionalEnv[1].name=LANGFUSE_INIT_PROJECT_ID", - "langfuse.langfuse.additionalEnv[1].value=\"%s\"" % os.environ["LANGFUSE_INIT_PROJECT_ID"], - "langfuse.langfuse.additionalEnv[2].name=LANGFUSE_INIT_PROJECT_PUBLIC_KEY", - "langfuse.langfuse.additionalEnv[2].value=%s" % os.environ["LANGFUSE_INIT_PROJECT_PUBLIC_KEY"], - "langfuse.langfuse.additionalEnv[3].name=LANGFUSE_INIT_PROJECT_SECRET_KEY", - "langfuse.langfuse.additionalEnv[3].value=%s" % os.environ["LANGFUSE_INIT_PROJECT_SECRET_KEY"], - "langfuse.langfuse.additionalEnv[4].name=LANGFUSE_INIT_USER_EMAIL", - "langfuse.langfuse.additionalEnv[4].value=%s" % os.environ["LANGFUSE_INIT_USER_EMAIL"], - "langfuse.langfuse.additionalEnv[5].name=LANGFUSE_INIT_USER_PASSWORD", - "langfuse.langfuse.additionalEnv[5].value=%s" % os.environ["LANGFUSE_INIT_USER_PASSWORD"], - "langfuse.langfuse.additionalEnv[6].name=LANGFUSE_INIT_USER_NAME", - "langfuse.langfuse.additionalEnv[6].value=%s" % os.environ["LANGFUSE_INIT_USER_NAME"], ] def has_confluence_config(): diff --git a/infrastructure/README.md b/infrastructure/README.md index f7449e3a..c18a9793 100644 --- a/infrastructure/README.md +++ b/infrastructure/README.md @@ -182,6 +182,12 @@ Default values for the deployment are provided in the `rag/values.yaml` file und > >All values containing `...` are placeholders and have to be replaced with real values. +**Dev helper via Kustomize/Tilt** +For local development you can let Tilt generate Langfuse init secrets automatically: +- Fill `infrastructure/kustomize/langfuse/.env.langfuse` with the Langfuse init env values. +- Tilt runs Kustomize on `infrastructure/kustomize/langfuse` and applies the resulting `langfuse-init-secrets` (hash disabled) before Helm resources. +- This is dev-only. For production, create/manage secrets with your secret manager and set `secretKeyRef.name` in `values.yaml` to your managed secret. + ### 1.2 Qdrant The deployment of the Qdrant can be disabled by setting the following value in the helm-chart: diff --git a/infrastructure/kustomize/langfuse/.env.langfuse.template b/infrastructure/kustomize/langfuse/.env.langfuse.template new file mode 100644 index 00000000..6aad45a8 --- /dev/null +++ b/infrastructure/kustomize/langfuse/.env.langfuse.template @@ -0,0 +1,8 @@ +# Copy to .env.langfuse and replace with your real Langfuse init values. +LANGFUSE_INIT_ORG_ID=your-org-id +LANGFUSE_INIT_PROJECT_ID=your-project-id +LANGFUSE_INIT_PROJECT_PUBLIC_KEY=your-project-public-key +LANGFUSE_INIT_PROJECT_SECRET_KEY=your-project-secret-key +LANGFUSE_INIT_USER_EMAIL=admin@example.com +LANGFUSE_INIT_USER_NAME=Admin +LANGFUSE_INIT_USER_PASSWORD=changeme diff --git a/infrastructure/kustomize/langfuse/kustomization.yaml b/infrastructure/kustomize/langfuse/kustomization.yaml new file mode 100644 index 00000000..bbed09bf --- /dev/null +++ b/infrastructure/kustomize/langfuse/kustomization.yaml @@ -0,0 +1,12 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: rag + +secretGenerator: + - name: langfuse-init-secrets + envs: + - .env.langfuse + type: Opaque + options: + # Keep a stable name so Helm/Tilt can reference the secret directly. + disableNameSuffixHash: true From e7d174c00c42db6bff35e0175c02ecb4c3cd163d Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Thu, 27 Nov 2025 22:07:11 +0100 Subject: [PATCH 4/8] chore: Add existingSecret fields for Langfuse configuration to support production secret management --- infrastructure/rag/values.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/infrastructure/rag/values.yaml b/infrastructure/rag/values.yaml index 1939136a..ee1a5126 100644 --- a/infrastructure/rag/values.yaml +++ b/infrastructure/rag/values.yaml @@ -616,6 +616,7 @@ langfuse: username: postgres password: postgres database: langfuse + existingSecret: "" # NOTE: for production use existing secret to fetch password # Redis Configuration (external KeyDB) redis: @@ -625,6 +626,7 @@ langfuse: auth: username: "default" password: "" + existingSecret: "" # NOTE: for production use existing secret to fetch password # ClickHouse Configuration (external ClickHouse) clickhouse: @@ -635,6 +637,7 @@ langfuse: auth: username: "default" password: "changeme" + existingSecret: "" # NOTE: for production use existing secret to fetch password migration: url: "clickhouse://rag-clickhouse:9000" ssl: false @@ -665,8 +668,14 @@ langfuse: forcePathStyle: true accessKeyId: value: "admin" + secretKeyRef: + name: "" + key: "" secretAccessKey: value: "adminpassword" + secretKeyRef: + name: "" + key: "" eventUpload: enabled: true bucket: "langfuse" @@ -675,8 +684,14 @@ langfuse: forcePathStyle: true accessKeyId: value: "admin" + secretKeyRef: + name: "" + key: "" secretAccessKey: value: "adminpassword" + secretKeyRef: + name: "" + key: "" minio: image: From 9825cffb7f9dd2d61d152d44a5822bb45c0da450 Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Thu, 27 Nov 2025 22:09:35 +0100 Subject: [PATCH 5/8] chore: Disable Minio feature in adminBackend configuration --- infrastructure/rag/values.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/infrastructure/rag/values.yaml b/infrastructure/rag/values.yaml index ee1a5126..1196ae72 100644 --- a/infrastructure/rag/values.yaml +++ b/infrastructure/rag/values.yaml @@ -335,9 +335,6 @@ adminBackend: pathType: ImplementationSpecific port: 8080 - minio: - enabled: true - envs: summarizer: SUMMARIZER_MAXIMUM_INPUT_SIZE: "8000" From a53e3a8df93924052dcc11c8fd6f73fe2e48a57c Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Thu, 27 Nov 2025 22:22:47 +0100 Subject: [PATCH 6/8] chore: Update README and secrets template for Langfuse init secrets management --- infrastructure/README.md | 6 +++++- infrastructure/rag/templates/frontend/secrets.yaml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/infrastructure/README.md b/infrastructure/README.md index c18a9793..72f6a528 100644 --- a/infrastructure/README.md +++ b/infrastructure/README.md @@ -184,7 +184,7 @@ Default values for the deployment are provided in the `rag/values.yaml` file und **Dev helper via Kustomize/Tilt** For local development you can let Tilt generate Langfuse init secrets automatically: -- Fill `infrastructure/kustomize/langfuse/.env.langfuse` with the Langfuse init env values. +- Copy `infrastructure/kustomize/langfuse/.env.langfuse.template` to `.env.langfuse` and fill it with the Langfuse init env values. - Tilt runs Kustomize on `infrastructure/kustomize/langfuse` and applies the resulting `langfuse-init-secrets` (hash disabled) before Helm resources. - This is dev-only. For production, create/manage secrets with your secret manager and set `secretKeyRef.name` in `values.yaml` to your managed secret. @@ -265,6 +265,10 @@ frontend: ingress: host: name: ... # Your domain name (e.g., rag.yourdomain.com) + +# In production, ensure a secret named "vite-auth" exists with keys +# VITE_AUTH_USERNAME and VITE_AUTH_PASSWORD set to your basic auth creds. +# (For local/dev, the chart can generate it from shared.secrets.) ``` ### 1.5 Backend diff --git a/infrastructure/rag/templates/frontend/secrets.yaml b/infrastructure/rag/templates/frontend/secrets.yaml index 7d5a156f..4fb55ab5 100644 --- a/infrastructure/rag/templates/frontend/secrets.yaml +++ b/infrastructure/rag/templates/frontend/secrets.yaml @@ -1,4 +1,4 @@ -{{- if $.Values.features.frontend.enabled }} +{{- if and $.Values.features.frontend.enabled $.Values.shared.secrets.basicAuthUser.value $.Values.shared.secrets.basicAuthPassword.value }} apiVersion: v1 data: VITE_AUTH_USERNAME: {{ .Values.shared.secrets.basicAuthUser.value | b64enc }} From 03e80d3d97e141c97648cfcbd3fdb451a8dd6611 Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Fri, 28 Nov 2025 09:49:03 +0100 Subject: [PATCH 7/8] chore: Remove unnecessary blank line before S3 accessKey in values.yaml --- infrastructure/rag/values.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/infrastructure/rag/values.yaml b/infrastructure/rag/values.yaml index 1196ae72..bd822b8a 100644 --- a/infrastructure/rag/values.yaml +++ b/infrastructure/rag/values.yaml @@ -482,7 +482,6 @@ shared: secretKeyRef: name: "" key: "BASIC_AUTH_PASSWORD" - s3: accessKey: value: "admin" From fa88ed4287e3ef3106586ef57e504c1fd5baaf9e Mon Sep 17 00:00:00 2001 From: Andreas Klos Date: Tue, 2 Dec 2025 13:11:45 +0100 Subject: [PATCH 8/8] chore: Add secret key fields for Langfuse configuration to enhance production secret management --- infrastructure/rag/values.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infrastructure/rag/values.yaml b/infrastructure/rag/values.yaml index bd822b8a..dece1dba 100644 --- a/infrastructure/rag/values.yaml +++ b/infrastructure/rag/values.yaml @@ -613,6 +613,8 @@ langfuse: password: postgres database: langfuse existingSecret: "" # NOTE: for production use existing secret to fetch password + secretKeys: + userPasswordKey: password # Redis Configuration (external KeyDB) redis: @@ -623,6 +625,7 @@ langfuse: username: "default" password: "" existingSecret: "" # NOTE: for production use existing secret to fetch password + existingSecretPasswordKey: "" # ClickHouse Configuration (external ClickHouse) clickhouse: @@ -634,6 +637,7 @@ langfuse: username: "default" password: "changeme" existingSecret: "" # NOTE: for production use existing secret to fetch password + existingSecretKey: "" migration: url: "clickhouse://rag-clickhouse:9000" ssl: false