Secrets-Verwaltung
Die Regel: Kein vom Menschen bereitgestelltes Secret steht jemals inline in einer Custom Resource, einem Chart-Wert oder einem Template. Anmeldedaten gelangen über einen von drei Wegen auf die Plattform, ausgewählt und konfiguriert durch die Resource SecretsManagement.
Die drei Quellen für Secrets
- External Secrets (ESO) — bezieht aus einem externen Secret Store (standardmäßig Azure Key Vault, aber jeder ESO-Provider) in namespacebezogene Kubernetes Secrets.
- Sealed Secrets — at-rest verschlüsselte Manifeste, die im Cluster entschlüsselt werden.
- Vom Operator generiert — Anmeldedaten, die der Operator selbst erzeugt (LiteLLM Virtual Keys, Langfuse Callback Keys, Datenspeicher-Passwörter). Gespeichert als owned Kubernetes Secrets mit Owner References für die Garbage Collection; Sie können sie manuell auf ESO/Sealed umstellen.
SecretsManagement ist erforderlich und wählt Backend (1) oder (2). Workloads binden ein SecretsManagement im selben Namespace über secretsRef und referenzieren die materialisierten Secret-Namen.
ESO-Provider
Der Operator stellt einen namespacebezogenen SecretStore bereit (kein ClusterSecretStore) und hält so die Anmeldedaten jedes Namespace isoliert.
Azure Key Vault (der Produktionsstandard)
- Workload Identity (
authType: WorkloadIdentity) — Produktion auf AKS. Der ServiceAccount jeder konsumierenden Workload benötigt das Labelazure.workload.identity/use: "true"und eine Federated Identity Credential in Azure. Der Operator setzt die Pod-/SA-Labels über die von ihm gerenderten Chart-Werte. - Service Principal (
authType: ServicePrincipal) — funktioniert überall, auch in Nicht-AKS-Clustern und Kind (das keine OIDC-Federation für Workload Identity bietet). Geben SietenantID+authSecretRef.{clientID, clientSecret}an.
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata: { name: azure-keyvault, namespace: forge-gateway }
spec:
provider:
azurekv:
authType: WorkloadIdentity
vaultUrl: https://kvforgepltprod.vault.azure.net/
serviceAccountRef: { name: forge-sa }Die Federated Credential ist ein zwingender manueller Schritt
Der Operator richtet die Kubernetes-Seite ein (den gelabelten ServiceAccount, den SecretStore, die ExternalSecrets). Er ruft keine Azure-API auf und kann daher die Federated Identity Credential nicht anlegen, mit der dieser ServiceAccount sein Token gegen die Managed Identity der Plattform tauscht. Du musst pro (Namespace, ServiceAccount) eine anlegen — der AKS-OIDC-Issuer verlangt ein exakt passendes Subject und unterstützt keine Wildcards:
az identity federated-credential create \
--name "eso-<namespace>-<serviceAccount>" \
--identity-name "<managed-identity>" \
--resource-group "<resource-group>" \
--issuer "$(az aks show -g <resource-group> -n <cluster> --query oidcIssuerProfile.issuerUrl -o tsv)" \
--subject "system:serviceaccount:<namespace>:<serviceAccount>" \
--audiences "api://AzureADTokenExchange"Bis sie existiert, schlägt der Token-Tausch von ESO mit dem Entra-Fehler AADSTS70021: No matching federated identity record found … fehl. Der Operator beobachtet den SecretStore-Status von ESO und spiegelt dies auf die SecretsManagement-Bedingung FederatedCredentialReady:
Waiting— ESO hat den Store noch nicht validiert.False/MissingFederatedCredential— derAADSTS70021-Fehler wurde gesehen; die Meldung nennt das exakte Subject, für das eine Credential anzulegen ist.True— ESO hat sich authentifiziert; die Credential ist vorhanden.
Ready zeigt weiterhin an, dass das Backend verdrahtet wurde; FederatedCredentialReady ist das spezifische Signal für den Azure-seitigen Trust. (Mit authType: ServicePrincipal wird keine Federated Credential benötigt und diese Bedingung wird nicht gesetzt.)
HashiCorp Vault
Ermöglicht es, den gesamten Secrets-Pfad im Cluster auszuführen (kein Cloud Key Vault, Service Principal oder Federated Identity). Bei KV-v2 ist jeder keys-Wert der Secret-Pfad und der Kubernetes-Key-Name die Property darin.
Jeder Provider (rohes Passthrough)
provider: raw injiziert den ESO-spec.provider-Block wortwörtlich, sodass jeder ESO-Provider unterstützt wird — AWS, GCP, IBM, Akeyless, 1Password, Kubernetes und jeder Provider, den ESO künftig hinzufügt — ohne Operator-Änderungen. Die Form externalSecrets[].data legt den vollständigen ESO-remoteRef offen (remoteKey / property / version).
Siehe die Referenz SecretsManagement für die genauen Feldformen und Beispiele jedes Providers.
Azure-Key-Vault-Key-Matrix
Bei Verwendung von Azure Key Vault sind dies die Secret-Namen, die der Operator erwartet (übernommen aus den bisherigen Chart-Werten der Plattform). SecretsManagement.eso.externalSecrets[].keys ordnet Kubernetes-Secret-Keys → Key-Vault-Secret-Namen zu.
Gateway (forge-gateway)
| Kubernetes Secret / Key | Key-Vault-Secret | Verwendet für |
|---|---|---|
model-credentials / OPENAI_API_KEY | gateway-foundry-api-key | Upstream-Modell-Authentifizierung |
model-credentials / ANTHROPIC_API_KEY | gateway-foundry-api-key | Upstream-Modell-Authentifizierung |
litellm-db-credentials / DATABASE_URL | (aus PostgresCluster zusammengesetzt) | LiteLLM-DB |
entra-sso-credentials / client-id,client-secret | gateway-entra-sso-client-id / -secret | UI-SSO (wenn enableEntraSSO) |
litellm-license / license-key | gateway-litellm-license-key | LiteLLM Enterprise |
ChatUI (forge-ui)
| Kubernetes Secret / Key | Key-Vault-Secret |
|---|---|
librechat-credentials-env / CREDS_KEY | chatui-creds-key |
librechat-credentials-env / CREDS_IV | chatui-creds-iv |
librechat-credentials-env / JWT_SECRET | chatui-jwt-secret |
librechat-credentials-env / JWT_REFRESH_SECRET | chatui-jwt-refresh-secret |
librechat-credentials-env / LITELLM_API_KEY | chatui-litellm-api-key (oder ein automatisch erzeugter Virtual Key bei vorhandener Lizenz) |
forge-ui-basic-auth / htpasswd | chatui-basic-auth-htpasswd |
MongoDB- und Meilisearch-Anmeldedaten werden für ChatUI nicht aus Key Vault bezogen. Sie gehören zu den Datenspeicher-Resources: der Meilisearch-Master-Key zur MeilisearchInstance und das Mongo-SCRAM-Passwort
- die datenbankspezifische
MONGO_URIzumMongoCluster.
Langfuse (forge-langfuse)
nextauth-secret + salt werden vom langfuse-operator automatisch generiert und in ein <instance>-generated-secrets Secret rotiert — beziehen Sie diese nicht aus Key Vault, es sei denn, Sie überschreiben sie. Datenspeicher-Anmeldedaten stammen aus den materialisierten Secrets der referenzierten Datenspeicher-Resources (plus Key Vault für externe Datenspeicher).
Vom Operator generierte Secrets
- LiteLLM Virtual Keys (ChatUI auto-wiring) und master/salt-Keys (
autoGenerate: true). - CloudNativePG-Rollenpasswörter (als datenbankspezifisches Anmeldedaten-Secret offengelegt).
- Das
MongoClusterSCRAM-Passwort und datenbankspezifischeMONGO_URI-Secrets. - Das
MeilisearchInstanceMaster-Key-Secret.
Alle operator-owned Secrets erhalten Owner References für die Garbage Collection und ein managed-by=navique-ai-core-operator-Label.
Rotation
Mit dem Feature credential-rotation und einem resourcebezogenen rotation-Block (Standardintervall 90 Tage) rotiert der Operator die Anmeldedaten, die er besitzt — LiteLLM Virtual Keys sowie generierte ClickHouse-/Redis-/Mongo-/Meilisearch-Passwörter — und stempelt eine core.navique.com/rotated-at-Annotation neu auf.
Außerhalb des Geltungsbereichs (von ihren eigenen Systemen rotiert): Key-Vault-Secrets (in KV rotieren; ESO synchronisiert neu) und CNPG-verwaltete Rollenpasswörter (über CNPG rotieren). Der Operator rotiert niemals Anmeldedaten, die er nicht besitzt. Ohne das Feature wird der rotation-Block ignoriert.
Umstellung weg von Klartext
Rotieren Sie die zuvor committeten Secrets
Die früheren Helm-Charts der Plattform haben Live-Secrets nach git committet (Modell-API-Keys, Entra-SSO-Client-Secret, LiteLLM-Lizenz, Database-URLs, Langfuse-Secrets). Diese sind per Definition kompromittiert und müssen im Rahmen der Migration rotiert werden — übernehmen Sie keines davon in den Operator. Rotieren Sie jedes einzelne in Key Vault, beziehen Sie sie über ESO und bereinigen Sie nach Möglichkeit die git-Historie.
Was zu vermeiden ist
- Keine Secret-Werte in Samples — verwenden Sie Platzhalter und einen Hinweis, den Vault zu befüllen.
- Kein Secret-Logging. Redigieren Sie Connection Strings in Events und Bedingungen.
- Keine in das Operator-Image eingebackenen Secrets (der öffentliche Lizenz-Key ist in Ordnung; niemals der private Key).