Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
3e0f280
chore: Refactor authentication and secret management in environment t…
a-klos Nov 27, 2025
ce8f152
chore: Enhance basic authentication setup and secret management in de…
a-klos Nov 27, 2025
17f88ce
chore: Add Langfuse init secrets management for local development wit…
a-klos Nov 27, 2025
e7d174c
chore: Add existingSecret fields for Langfuse configuration to suppor…
a-klos Nov 27, 2025
9825cff
chore: Disable Minio feature in adminBackend configuration
a-klos Nov 27, 2025
a53e3a8
chore: Update README and secrets template for Langfuse init secrets m…
a-klos Nov 27, 2025
03e80d3
chore: Remove unnecessary blank line before S3 accessKey in values.yaml
a-klos Nov 28, 2025
fa88ed4
chore: Add secret key fields for Langfuse configuration to enhance pr…
a-klos Dec 2, 2025
0821925
chore: Update langfuse version to 1.5.13 in Chart.lock and Chart.yaml
a-klos Dec 3, 2025
5c9e086
chore: Update digest and generated timestamp in Chart.lock
a-klos Dec 3, 2025
50830f6
chore: Update secret reference name in deployment.yaml for S3 configu…
a-klos Dec 3, 2025
74896c7
chore: Add key value store credentials support in admin backend and u…
a-klos Dec 4, 2025
bcb1334
chore: Refactor basic auth credential handling in secrets templates f…
a-klos Dec 4, 2025
26261e8
chore: Simplify secret lookup for basic auth credentials in helpers t…
a-klos Dec 4, 2025
d2832e3
chore: Refactor basic auth secret handling for improved structure and…
a-klos Dec 4, 2025
775352c
chore: Update PostgreSQL readiness check with specific host and timeo…
a-klos Dec 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ S3_SECRET_ACCESS_KEY=your_s3_secret_key_here
# =============================================================================
# Basic Authentication (Required)
# =============================================================================
BASIC_AUTH="foo:$apr1$ryE0iE7H$F2SlPDNoFdGoaHrcla2HL/"
# Used for backend/admin endpoints and reused by the frontend's auth prompt.
BASIC_AUTH_USER=foo
BASIC_AUTH_PASSWORD=bar

# =============================================================================
# Langfuse Configuration (Required for observability)
Expand All @@ -27,12 +29,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)
# =============================================================================
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/.env.langfuse
**/.nx/*
*.tgz
*/Chart.lock
Expand Down
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -238,6 +243,12 @@ This results in a basic auth with username=`foo` and password=`bar`.
> - `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:
Expand Down Expand Up @@ -483,4 +494,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).

42 changes: 17 additions & 25 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 ##############################################
########################################################################################################################
Expand Down Expand Up @@ -469,14 +477,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"],
"backend.secrets.basicAuth=%s" % os.environ["BASIC_AUTH"],
"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"],
"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",
Expand All @@ -487,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():
Expand Down Expand Up @@ -532,13 +524,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)

Expand Down
84 changes: 70 additions & 14 deletions infrastructure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
- 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.

### 1.2 Qdrant

The deployment of the Qdrant can be disabled by setting the following value in the helm-chart:
Expand Down Expand Up @@ -214,10 +220,28 @@ adminBackend:
keyValueStore:
USECASE_KEYVALUE_HOST: ... # Your Redis host (e.g., redis.yourdomain.com)
USECASE_KEYVALUE_PORT: 6379
secrets:
keyValueStore:
username:
value: "" # Optional inline username; prefer secretKeyRef in production
secretKeyRef:
name: "" # Existing secret containing the username
key: "USECASE_KEYVALUE_USERNAME"
password:
value: "" # Optional inline password; prefer secretKeyRef in production
secretKeyRef:
name: "" # Existing secret containing the password
key: "USECASE_KEYVALUE_PASSWORD"

features:
keydb:
enabled: false # Disable KeyDB for production
keydb:
password: "" # Optional inline password for the bundled KeyDB chart
existingSecret: "" # Name of an existing secret that stores the KeyDB password
existingSecretPasswordKey: "password" # Key within the existing secret
auth:
username: "default" # Username that the admin backend uses when auth is enabled

langfuse:
valkey:
Expand All @@ -233,6 +257,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:
Expand All @@ -246,11 +284,9 @@ frontend:
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
# 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
Expand All @@ -260,24 +296,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
Expand Down Expand Up @@ -310,13 +364,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:
Expand Down
8 changes: 8 additions & 0 deletions infrastructure/kustomize/langfuse/.env.langfuse.template
Original file line number Diff line number Diff line change
@@ -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
12 changes: 12 additions & 0 deletions infrastructure/kustomize/langfuse/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions infrastructure/rag/Chart.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
dependencies:
- name: langfuse
repository: https://langfuse.github.io/langfuse-k8s
version: 1.5.4
version: 1.5.13
- name: qdrant
repository: https://qdrant.github.io/qdrant-helm
version: 1.15.5
Expand All @@ -14,5 +14,5 @@ dependencies:
- name: ollama
repository: https://otwld.github.io/ollama-helm/
version: 1.30.0
digest: sha256:bdcbd61348805d9135cabd97c80cd08e774f479eedcbc686dc851ca55fb4dc4c
generated: "2025-10-10T08:41:01.890585511Z"
digest: sha256:398f4f0791092b57a2c0d33a715f8680fb45663499a9ad410ca4bee7eda201bb
generated: "2025-12-03T18:35:42.061121+01:00"
2 changes: 1 addition & 1 deletion infrastructure/rag/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ appVersion: "v3.4.0"
dependencies:
- name: langfuse
repository: https://langfuse.github.io/langfuse-k8s
version: "1.5.4"
version: "1.5.13"
condition: features.langfuse.enabled
- name: qdrant
version: 1.15.5
Expand Down
Loading