Observability
Geltungsbereich: namespaced · Kind: Observability (Kurzname obs, Plural observabilities) · Gruppe: core.navique.com/v1alpha1
LLM-Observability — Traces, Evals, Prompt-Management. Observability ist der generische Observability-Workload: spec.type wählt die Backend-Implementierung aus. Heute ist nur langfuse implementiert (Langfuse v3 via langfuse-operator); weitere Typen sind als Gerüst für die Zukunft angelegt.
Spec
| Feld | Typ | Beschreibung |
|---|---|---|
type | enum (erforderlich) | Backend-Implementierung. Heute ist nur langfuse implementiert |
secretsRef | LocalRef (optional) | SecretsManagement im selben Namespace, auf die gewartet wird. Weglassen, um selbst verwaltete, gewöhnliche Kubernetes-Secrets zu verwenden — siehe secretsRef |
mesh | object | Den Namespace in das Cluster-ServiceMesh aufnehmen (auto / enabled / disabled) |
image | object | Image-Override für das gewählte Backend |
ingress | object | Host + TLS (TLS ⇒ stellt cert-manager sicher) |
sso | object | OIDC/SSO-Login (siehe SSO) |
langfuse | object | Langfuse-spezifische Konfiguration — vorhanden bei type: langfuse (siehe langfuse-Block) |
Diese Felder der obersten Ebene sind allen Backend-Typen gemeinsam. Die backend-spezifische Konfiguration liegt unter einem Block, der nach dem Typ benannt ist (spec.langfuse für das Langfuse-Backend).
type
type | Status | Emittiert |
|---|---|---|
langfuse | Implementiert | Eine LangfuseInstance (langfuse.palena.ai/v1alpha1) via langfuse-operator |
Weitere Backend-Typen sind reserviert und noch nicht implementiert; das Setzen eines solchen ergibt eine klare „noch nicht implementiert“-Status-Condition.
langfuse-Block
Bei type: langfuse enthält spec.langfuse die Verkabelung für Langfuse v3. Langfuse v3 benötigt Postgres, ClickHouse, Redis und Object-(Blob-)Storage; jeder Datenspeicher kann eine Datenspeicher-Ressource referenzieren oder auf einen externen Host verweisen.
| Feld | Typ | Beschreibung |
|---|---|---|
postgres | DatastoreRef (erforderlich) | Verweis auf ein PostgresCluster oder extern |
clickhouse | DatastoreRef (erforderlich) | Verweis auf ein ClickHouseCluster oder extern |
redis | DatastoreRef (erforderlich) | Verweis auf eine RedisInstance oder extern |
blob | object (erforderlich) | Object-Storage (von Langfuse v3 erforderlich): S3 / Azure / GCS |
auth | object | nextAuthUrl; Secret/Salt werden vom Operator automatisch generiert |
bootstrap | object | Headless-Seeding einer Org / eines Projekts / eines API-Keys + Admin-Benutzers (siehe Bootstrap) |
licenseSecretRef | SecretKeyRef | Langfuse-Enterprise-Lizenz — Zugang pro Person (siehe Personen Zugang geben) |
defaultAccess | object | Automatischer Zugang für alle, die sich anmelden (siehe Personen Zugang geben) |
DatastoreRef
| Feld | Beschreibung |
|---|---|
mode | ref (eine Datenspeicher-Ressource) oder external |
ref | Die zu verwendende Datenspeicher-Ressource (Modus ref) |
databaseName | Datenbank im gemeinsam genutzten Datenspeicher. Postgres: erforderlich für einen verwalteten/übernommenen PostgresCluster. ClickHouse: optional (Standard default); muss in spec.databases des ClickHouseCluster stehen (ein Stack erledigt das) — Langfuse wartet darauf. Nur Buchstaben, Ziffern und _ |
connectionSecretRef | Verbindungs-Secret (Modus external) |
blob (diskriminierte Union)
provider wählt das Backend aus; geben Sie den passenden Block an. Anmeldedaten werden aus einem Secret im Namespace unter kanonischen Schlüsseln gelesen; lässt man das Anmeldedaten-Secret weg, werden Umgebungs-Cloud-Anmeldedaten ausgewählt (IRSA / Workload Identity).
| Provider | Block | Anmeldedaten-Schlüssel |
|---|---|---|
s3 (Standard) | s3 (bucket, region, endpoint, forcePathStyle) | access-key-id, secret-access-key |
azure | azure (storageAccountName, containerName, endpoint) | account-key |
gcs | gcs (bucket, projectId) | credentials (SA JSON) |
Was es emittiert
Für type: langfuse löst der Controller die Datenspeicher auf, stellt cert-manager sicher, falls TLS/Ingress aktiviert ist, stellt den langfuse-operator sicher und emittiert eine LangfuseInstance (langfuse.palena.ai/v1alpha1), die auf die aufgelösten Datenspeicher und Secrets verweist. Die managed-/adopt-/external-Provenance liegt in den referenzierten Datenspeicher-Ressourcen — Observability verweist lediglich auf sie.
Standardmäßig operator-verwaltete Datenspeicher
Für ClickHouse und Redis kann der langfuse-operator diese intern verwalten. Sofern Sie keinen external-Datenspeicher referenzieren, verwendet der Controller standardmäßig operator-verwaltetes ClickHouse/Redis — Sie benötigen also nicht zwingend ein dediziertes ClickHouseCluster / eine dedizierte RedisInstance. Postgres wird typischerweise gemeinsam mit dem Gateway genutzt.
Beispiel
apiVersion: core.navique.com/v1alpha1
kind: Observability
metadata:
name: observability
namespace: forge-langfuse
spec:
type: langfuse
secretsRef: { name: langfuse-secrets }
ingress: { enabled: true, host: langfuse.forge.example.com, tls: true }
langfuse:
postgres: { mode: ref, ref: { name: forge-pg, namespace: forge-data }, databaseName: langfuse }
clickhouse: { mode: ref, ref: { name: forge-ch, namespace: forge-data } }
redis: { mode: ref, ref: { name: forge-redis, namespace: forge-data } }
blob:
provider: azure
azure:
storageAccountName: forgelangfuse
containerName: langfuse-eventsSSO / OIDC login
spec.sso aktiviert Single Sign-On. Für das Langfuse-Backend verwendet es den generischen Custom-OIDC-Provider von Langfuse v3: Der Operator setzt den nativen spec.auth.oidc-Block der LangfuseInstance, den der langfuse-operator in die AUTH_CUSTOM_*-Konfiguration von Langfuse übersetzt. Die OAuth-Client-Anmeldedaten stammen aus einem Secret im selben Namespace (über SecretsManagement).
| Feld | Beschreibung |
|---|---|
issuerURL | OIDC-Issuer-/Discovery-Basis-URL |
clientSecretRef.name | Secret mit dem OAuth-Client (Schlüssel standardmäßig client-id / client-secret) |
scopes | Angeforderte Scopes (Standard openid, email, profile) |
providerName | Beschriftung der Login-Schaltfläche (AUTH_CUSTOM_NAME) |
Die Felder provider, tenantID und die Felder für explizite Endpunkte des gemeinsamen SSO-Typs sind ausschließlich für das Gateway und werden hier ignoriert.
Der IdP muss den Custom-OIDC-Callback <publicURL>/api/auth/callback/custom zulassen; aktivieren Sie daher spec.ingress (oder setzen Sie langfuse.auth.nextAuthUrl) auf eine öffentliche URL.
spec:
type: langfuse
sso:
issuerURL: https://idp.example.com
providerName: "Acme SSO"
clientSecretRef: { name: langfuse-oidc }TIP
Statische OIDC-Provider sind Teil der quelloffenen Self-Hosted-Variante von Langfuse. Nur die SSO-Einrichtung in der UI, die SSO-Durchsetzung pro Organisation sowie RBAC/SCIM sind Langfuse-Enterprise-Features.
Bootstrap
spec.langfuse.bootstrap seedet headless eine Organisation, ein Projekt, einen initialen API-Key sowie einen Admin-Benutzer in ein frisches Community-Langfuse über die LANGFUSE_INIT_*-Umgebung. So kommt die Plattform vollständig verkabelt hoch, ohne dass sich zuvor jemand in die Langfuse-UI einloggen muss — etwa damit ein Gateway Traces gegen einen bekannten Projektschlüssel auf einem Community-Langfuse exportieren kann, das andernfalls keine Projektschlüssel ausstellen könnte.
| Feld | Beschreibung |
|---|---|
organization | Name der initialen Organisation |
project | Name des initialen Projekts |
apiKeySecretRef | Secret, das mit dem Public-/Secret-Key des geseedeten Projekts befüllt wird |
admin | Admin-Benutzer (E-Mail + Passwort aus einem Secret), beim ersten Start geseedet |
Die geseedeten Anmeldedaten werden in eigene Secrets durchgeschrieben, sodass Konsumenten (Gateway-Trace-Export, die Management-Konsole) sie ohne UI-Schritte lesen können.
Personen Zugang geben
Es gibt zwei Wege zu Langfuse, und sie brauchen Verschiedenes:
- Einzeln — eine
Identitymittype: observability(mitobservabilityRefund einerrole:viewer,member,adminoderowner) macht die Person zum Mitglied der Organisation dieses Langfuse: der Bootstrap-Organisation, wennbootstrapaktiv ist, die Projekte und Traces enthält. Die Mitgliederverwaltung von Langfuse ist eine Enterprise-Funktion, daher braucht dieslicenseSecretRef(den Langfuse-Enterprise-Lizenzschlüssel). Ohne sie meldet eine solche Identity, dass die Lizenz fehlt. - Alle, die sich anmelden —
defaultAccessfügt jeden neuen Langfuse-Benutzer (etwa bei der ersten Firmenanmeldung) automatisch der Bootstrap-Organisation und dem Bootstrap-Projekt hinzu. Keine Lizenz nötig. Ohne Lizenz zähltorgRolefür alle Projekte: Rollen auf Projektebene (projectRole) sind ebenfalls eine Enterprise-Funktion.
status.peopleAccess meldet, ob der Einzelzugang Available ist oder warum nicht (NeedsLicense, NeedsNewerLangfuseOperator), und status.signInAccessRole die Rolle, die der automatische Zugang tatsächlich vergibt. Die Management-Konsole liest beides, um die passende Option anzubieten.
| Feld | Beschreibung |
|---|---|
licenseSecretRef | Secret mit der Langfuse-Enterprise-Lizenz (Standard-Key license) |
defaultAccess.orgRole | OWNER / ADMIN / MEMBER / VIEWER (Standard) / NONE |
defaultAccess.projectRole | OWNER / ADMIN / MEMBER / VIEWER (Standard) — nur Enterprise |
defaultAccess erfordert bootstrap (sonst bei der Admission abgelehnt).
Secrets
nextauth-secret und salt werden vom langfuse-operator automatisch generiert und rotiert und in ein <instance>-generated-secrets-Secret geschrieben — Sie beziehen diese nicht aus Key Vault, es sei denn, Sie möchten sie überschreiben. Die Datenspeicher-Anmeldedaten stammen aus den materialisierten Secrets der referenzierten Datenspeicher-Ressourcen (plus Key Vault für externe Datenspeicher). Siehe Secrets Management.
Status
Bereitschaft je Datenspeicher, Bereitschaft der Instanz und der Ingress-Host, zusätzlich zu den standardmäßigen conditions und observedGeneration. Ein nicht implementierter type legt eine klare „noch nicht implementiert“-Condition offen.