Stack
Portée : namespaced · Umbrella optionnel · Sous licence (fonctionnalité managed-deployment + un quota stacks)
Stack est une resource umbrella optionnelle qui crée et possède un lot organisé des resources granulaires, câble automatiquement leurs références et agrège la progression — une expérience de provisionnement en une passe de type déploiement ARM.
Elle ne remplace pas les resources par composant. Les CRDs granulaires demeurent une manière de première classe de composer la plateforme à la main ; Stack se place simplement par-dessus pour les équipes qui souhaitent un objet unique pour gérer tout un environnement.
Quand l'utiliser
- Utilisez
Stacklorsque vous voulez provisionner et suivre un environnement complet (secrets- datastores + gateway + Observability + UI) comme une seule unité, l'opérateur câblant les références croisées pour vous et regroupant le statut en un seul endroit.
- Utilisez les resources granulaires lorsque vous voulez un contrôle fin, que vous composez des resources à travers plusieurs namespaces à la main, ou que vous partagez des datastores entre plusieurs charges de travail gérées indépendamment.
Ce qu'elle fait
- Crée + possède les composants groupés (l'opérateur définit des owner references afin que tout le lot soit collecté par le garbage collector avec le
Stack). - Câble automatiquement les références entre eux (Gateway→Postgres, Gateway→Observability, ChatUI→Gateway, charges de travail→datastores) — cela repose sur la capacité
auto-wiring. - Agrège la progression dans
status.components[]etstatus.endpoints, de sorte qu'un seulkubectl get stackaffiche l'état de préparation et les URLs de tout l'environnement.
Politique de dérive
Par défaut, le Stack applique en continu la spécification organisée à ses enfants : toute modification manuelle apportée à une CR de composant générée (par exemple augmenter la taille de stockage d'un datastore ou le nombre de réplicas d'une charge de travail) est annulée à la prochaine réconciliation. spec.driftPolicy permet d'assouplir ce comportement :
driftPolicy | Comportement |
|---|---|
Enforce (par défaut) | La spécification organisée est réappliquée à chaque réconciliation — les modifications manuelles des enfants sont annulées (correction complète de la dérive). |
Adopt | La spécification organisée est appliquée à la création et chaque fois que la spécification du Stack lui-même change (un « redéploiement » de type ARM). Entre deux modifications du Stack, les modifications manuelles par composant sont préservées. |
Adopt reproduit le comportement d'un déploiement Azure Resource Manager : le Stack initialise et câble les resources, puis vous pouvez ajuster chaque composant directement. Modifier le Stack lui-même réapplique chaque enfant et écrase votre dérive ; considérez donc une modification du Stack comme un redéploiement.
L'owner reference est conservée sous les deux politiques, de sorte que la suppression du Stack entraîne toujours en cascade la suppression (et le démantèlement) de chaque composant qu'il a créé.
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
name: forge
spec:
driftPolicy: Adopt # permettre d'ajuster les composants individuellement après la création
# ...Dimensionnement des datastores
Chaque datastore géré sous spec.datastores accepte un raccourci resources optionnel qui dimensionne le CPU et la mémoire du conteneur sous-jacent. Il est pris en compte pour les datastores Postgres, ClickHouse, Redis et MongoDB (mode managed uniquement) et propagé vers l'enfant PostgresCluster / ClickHouseCluster / RedisInstance / MongoCluster émis, dans son champ managed.resources.
| Champ | Correspond à |
|---|---|
cpu | demande (request) de CPU |
memory | demande (request) de mémoire |
memoryLimit | limite de mémoire |
Le raccourci n'a délibérément pas de limite de CPU (les limites de CPU brident au lieu de protéger). Si vous en avez besoin, utilisez directement la CRD de datastore autonome, qui accepte un managed.resources complet.
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
name: forge
spec:
datastores:
postgres:
storageSize: 20Gi
resources: { cpu: 500m, memory: 1Gi, memoryLimit: 2Gi }
clickhouse:
storageSize: 50Gi
resources: { cpu: 500m, memory: 2Gi, memoryLimit: 3Gi }
redis:
storageSize: 5Gi
resources: { cpu: 100m, memory: 256Mi, memoryLimit: 512Mi }
mongo:
storageSize: 20Gi
resources: { cpu: 250m, memory: 1Gi, memoryLimit: 2Gi }Si resources est omis, les valeurs par défaut du chart en amont s'appliquent (ClickHouse conserve sa limite mémoire de 3Gi réglée par l'opérateur pour éviter les OOM sous la charge de Langfuse).
Choisir l'implémentation de la passerelle
spec.gateway.type choisit le produit de passerelle : litellm (défaut) ou waeg (la passerelle Wäg, via le waeg-operator). Voir Gateway → Passerelle Wäg pour les différences.
Avec type: waeg, le Stack :
- exige
datastores.clickhouse.enableddans le mode de stockagesplitpar défaut — l'admission rejette le Stack sinon, car c'est là que vivent les analyses de Wäg. Posezgateway.waeg.storageMode: singlepour les garder dans le Postgres du Stack, ce qui supprime entièrement cette exigence — voir Stockage analytique de Wäg ; - câble automatiquement le ClickHouse (et le Redis, s'il est activé) du Stack comme second plan de stockage de la passerelle — en mode
splituniquement ; - déclare la base
waegsur ce ClickHouse pour que la passerelle puisse seulement démarrer : Wäg ne crée que ses tables, jamais sa base (ClickHouseCluster→databases[]) ; - nomme la base Postgres logique de la passerelle
waegplutôt quelitellm, pour que les deux implémentations ne partagent jamais un schéma ; - n'attache aucune référence Langfuse — Wäg ne peut pas exporter les traces de façon déclarative, donc le Stack ne câble rien que la passerelle devrait refuser.
spec.gateway.waeg transmet les réglages propres à Wäg : topology, jobWorkers, worker, storageMode, openfga, autoscaling, bootstrapAdmin, dataEncryptionKeySecretRef, modelAccess, scim et jwt. La licence Enterprise se déclare une seule fois, via spec.gateway.licenseSecretRef, et l'organisation de la passerelle via spec.gateway.organization — dont une passerelle Wäg a besoin avant qu'une ChatUI puisse s'y rattacher.
spec:
datastores:
clickhouse: { enabled: true, backup: { enabled: true, provider: s3, s3: { destinationPath: s3://b } } }
redis: { enabled: true }
gateway:
enabled: true
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
waeg:
topology: Split
worker: { enabled: true, replicas: 2 }
scim:
enabled: true
tokenSecretRef: { name: waeg-scim-token, key: scim-token }
defaultRole: viewer
jwt:
appClaim: azp
requireRegisteredApplication: trueLes champs propres à LiteLLM décrits plus bas (rolePermissions, healthCheck, storePromptsInLogs, guardrails, limites par modèle — ainsi que la moitié « correspondances de claims » de jwtAuth) sont signalés sur la condition FeaturesSupported de la passerelle enfant lorsque type: waeg — ils ne sont jamais abandonnés en silence.
Stockage analytique de Wäg
spec.gateway.waeg.storageMode choisit où vivent les analyses de la passerelle (journaux de requêtes, usage, dépenses). C'est la transmission par le Stack de Gateway.spec.waeg.storageMode.
| Mode | Les analyses vivent dans | datastores.clickhouse.enabled |
|---|---|---|
split (défaut) | le ClickHouse du Stack | requis |
single | le Postgres du Stack | inutile — aucun ClickHouse n'est provisionné |
Le défaut de Wäg lui-même est single, et c'est son point de départ recommandé ; cet opérateur conserve split par défaut, par continuité et parce qu'il tient la charge. Avec single, le Stack ne provisionne aucun ClickHouse et la règle d'admission qui en exigeait un ne s'applique plus. Conserver le défaut sans ClickHouse est rejeté avec :
gateway.type=waeg with the default storageMode 'split' requires
datastores.clickhouse.enabled; set gateway.waeg.storageMode: single to keep
analytics in Postgres insteadChanger de mode ne migre pas l'historique analytique
Les deux plans sont des magasins distincts. Modifier storageMode sur un Stack en service pointe la passerelle vers l'autre ; les analyses déjà collectées restent où elles sont, et ni l'opérateur ni Wäg ne les recopie.
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
name: forge
namespace: forge
spec:
datastores:
postgres:
enabled: true
storageSize: 20Gi
backup: { enabled: true, provider: s3, s3: { destinationPath: s3://forge-pg } }
redis: { enabled: true }
# aucun bloc clickhouse — storageMode: single n'en a pas besoin
gateway:
enabled: true
type: waeg
organization: { name: forge }
waeg:
storageMode: singleEn mode split (le défaut), le Stack déclare en plus la base waeg sur son ClickHouse managé, car Wäg ne crée que ses tables et jamais sa base — voir ClickHouseCluster → databases[].
Organisation du gateway
spec.gateway.organization crée l'organisation de premier niveau de la passerelle — l'objet sur lequel remontent les budgets et les plafonds de débit. Le champ est transmis tel quel à spec.organization du Gateway enfant.
| Champ | Description |
|---|---|
name (obligatoire) | Nom de l'organisation |
maxBudget | Plafond de dépenses de l'organisation |
budgetDuration | Période au terme de laquelle le plafond est réinitialisé (p. ex. 30d). LiteLLM uniquement — les politiques de budget de Wäg n'ont pas de champ de période |
rpmLimit | Plafond de requêtes par minute |
tpmLimit | Plafond de tokens par minute |
Sur une passerelle type: litellm, l'organisation reste optionnelle : les équipes, les clés et les modèles fonctionnent sans elle.
Une passerelle Wäg en exige une avant qu'une ChatUI puisse s'y rattacher
Avec type: waeg, ce champ est obligatoire pour câbler automatiquement une ChatUI. Wäg n'a pas de clé virtuelle autonome : une clé appartient à une application, et les applications sont rattachées à une organisation — sans organisation, il n'y a donc rien sous quoi émettre les identifiants de la ChatUI. Avant l'existence de ce champ, un Stack avec gateway.type: waeg et chatUI.enabled: true laissait la ChatUI bloquée sur
Gateway "…" is type=waeg and has no spec.organization: a Wäg virtual key belongs
to an application, and applications are org-rootedsans rien de réglable depuis un Stack pour y remédier : le Gateway granulaire disposait de spec.organization, le Stack n'offrait aucune transmission. Renseignez-le ici et l'opérateur enregistre la ChatUI comme WaegApplication sous cette organisation, puis émet sa WaegVirtualKey à partir d'elle.
C'est également à l'organisation que se rattachent les autorisations de spec.gateway.waeg.modelAccess : l'ACL de modèles est déclarée contre elle et reste sans effet sans elle.
spec:
datastores:
clickhouse: { enabled: true, backup: { enabled: true, provider: s3, s3: { destinationPath: s3://forge-ch } } }
redis: { enabled: true }
gateway:
enabled: true
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
organization:
name: navique-ag
maxBudget: 2000
rpmLimit: 1000
tpmLimit: 500000
waeg:
modelAccess: # rattaché à l'organisation : elle est requise
openByDefault: false
fallbackMode: deny
grants:
- models: [premium, economy]
chatUI:
enabled: true # câblée comme application sous navique-agVoir ChatUI se connecte en tant qu'application pour les objets émis par l'opérateur, et Ce qui n'est pas appliqué pour les champs d'organisation que Wäg ne peut pas honorer.
Licence Enterprise du gateway
spec.gateway.licenseSecretRef fournit la licence Enterprise de la passerelle et est transmis à instance.licenseSecretRef du Gateway. Avec type: litellm, il s'agit de la clé LiteLLM Enterprise ; avec type: waeg, de la licence Wäg Enterprise — et donc de la différence entre une passerelle Enterprise opérationnelle et une passerelle qui répond 402 license_required.
Chaque module Wäg Enterprise en dépend — SSO, SCIM, audit, CMEK, FIPS et l'habillage de la console — et son application est inconditionnelle. Sans ce champ, une passerelle Wäg gérée par un Stack n'a donc aucune fonctionnalité Enterprise accessible.
spec:
gateway:
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }La clé du Secret vaut license par défaut. Laissez le backend SecretsManagement du Stack matérialiser le Secret plutôt que de le créer à la main.
L'habillage suit la licence
Dès qu'une passerelle Wäg est sous licence, l'opérateur applique automatiquement le thème Navique intégré à sa console (une ConfigMap <gateway>-branding qu'il possède). Le Stack n'offre pas de champ de retrait — pour votre propre thème, ou pour conserver la livrée de Wäg, utilisez le Gateway granulaire avec waeg.brandingConfigMapRef / waeg.defaultBranding: false.
Dimensionnement du gateway
spec.gateway.resources dimensionne le conteneur du proxy LiteLLM. Contrairement au raccourci des datastores, il s'agit d'un ResourceRequirements Kubernetes complet (vous pouvez donc définir une limite de CPU) ; il est transmis tel quel à instance.resources du Gateway émis → spec.resources de la LiteLLMInstance. L'omettre laisse la valeur par défaut du litellm-operator.
spec:
gateway:
resources:
requests: { cpu: "500m", memory: 512Mi }
limits: { cpu: "2", memory: 2Gi }Épingler le build du proxy gateway
spec.gateway.image épingle l'image du proxy LiteLLM. La valeur est transmise au Gateway généré (instance.image), puis à la LiteLLMInstance (spec.image).
spec:
gateway:
image:
repository: ghcr.io/berriai/litellm
tag: v1.94.0-dev.2Laissez ce champ vide sauf si vous qualifiez un build précis. Sans épinglage, le litellm-operator applique son propre tag par défaut — celui qui est validé avec son point d'entrée de migration de base de données. Un tag arbitraire peut casser la migration et rendre le gateway indisponible.
Ne corrigez pas le Gateway enfant à la main : avec la politique de dérive par défaut Enforce, la Stack réapplique ses ressources enfants à chaque réconciliation et votre modification est annulée en quelques secondes. Déclarez l'épinglage ici.
Auth JWT & RBAC du gateway
spec.gateway.jwtAuth et spec.gateway.rolePermissions activent l'authentification d'API par JWT et l'accès aux modèles par rôle sur le gateway du Stack — transmis directement à instance.jwtAuth / instance.rolePermissions du gateway. Voir Authentification d'API par JWT & RBAC pour les champs. Nécessite une licence LiteLLM Enterprise.
spec:
gateway:
jwtAuth:
enabled: true
userRolesJWTField: roles
userAllowedRoles: ["basic_user"]
enforceRBAC: true
rolePermissions:
internal_user: { models: ["anthropic-claude"] }Habillage de la console Wäg
spec.gateway.waeg.brandingConfigMapRef et defaultBranding sont transmis à l'habillage de la console de la passerelle : le thème Navique par défaut, votre propre thème avec la fonctionnalité sous licence custom-branding, ou la livrée propre à Wäg avec defaultBranding: false.
Sur une passerelle Wäg
spec.gateway.jwtAuth active aussi l'authentification JWT pour type: waeg — enabled, publicKeyURL (→ le jwksUrl de Wäg), issuer, audience et userIDJWTField (→ subjectClaim) s'appliquent. Les réglages propres à Wäg vivent dans spec.gateway.waeg.jwt ; spec.gateway.rolePermissions et les correspondances de claims (userRolesJWTField, userRoleJWTField, userAllowedRoles, enforceRBAC, userIDUpsert, teamIDsJWTField, adminJWTScope) sont en revanche signalés comme non pris en charge : Wäg autorise via OpenFGA et les applications enregistrées. Voir Authentification JWT du plan de données.
spec:
gateway:
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
jwtAuth:
enabled: true
publicKeyURL: https://login.microsoftonline.com/<tenant>/discovery/v2.0/keys
issuer: https://login.microsoftonline.com/<tenant>/v2.0
audience: <client-id>
userIDJWTField: sub
waeg:
jwt:
appClaim: azp
requireRegisteredApplication: trueLes commutateurs de durcissement peuvent empêcher le démarrage
waeg.jwt.allowMasterKey: false ou allowVirtualKeys: false exigent jwtAuth.enabled: true, une publicKeyURL, une audience et insecureSkipVerify: false — sinon Wäg refuse de démarrer. allowVirtualKeys: false coupe en outre toutes les clés d'application, y compris celle de la ChatUI du Stack.
Approvisionnement SCIM Wäg
spec.gateway.waeg.scim active les points d'accès SCIM v2 de Wäg sur la passerelle du Stack : votre IdP approvisionne et retire directement les utilisateurs de la console. C'est indépendant du SSO — cela fonctionne sans aucune connexion interactive câblée — et cela exige spec.gateway.licenseSecretRef.
spec:
gateway:
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
waeg:
scim:
enabled: true # défaut
tokenSecretRef: { name: waeg-scim-token, key: scim-token } # requis
defaultRole: viewer
orgSource: waeg
roleMap: { "AI Platform Admins": admin }Le jeton porteur est projeté sur les pods de la passerelle sous le nom WAEG_EE_SCIM_TOKEN : faire tourner le Secret constitue donc toute la procédure de rotation. Les points d'accès se trouvent sous /waeg/admin/v1/ee/scim/v2. Voir Approvisionnement SCIM pour tous les champs.
Datastores de la ChatUI : MongoDB et Meilisearch
MongoDB (le stockage des conversations) et Meilisearch (la recherche) alimentent la ChatUI et se configurent sous datastores.mongo / datastores.meilisearch — avec le même sélecteur mode: managed | external que les autres datastores. Ils ne sont provisionnés que lorsque la ChatUI est activée, et sont managed par défaut.
managed(par défaut) : le Stack provisionne et possède uneMongoCluster/MeilisearchInstanceet y raccorde la ChatUI. Dimensionnez viastorageSize(Meilisearch honore aussistorageClass/resources).external: aucune CR de datastore n'est provisionnée ; la ChatUI est raccordée à une instance gérée par l'utilisateur. Mongo nécessiteconnectionSecretRef(clé de SecretMONGO_URI, remplaçable via.key). Meilisearch nécessitehostplus unconnectionSecretRefcontenant la clé maître (clé de SecretMEILI_MASTER_KEY).
spec:
datastores:
mongo:
mode: managed
storageSize: 10Gi
meilisearch:
mode: external
host: https://search.example.com
connectionSecretRef: { name: meili-master-key } # clé MEILI_MASTER_KEYServeurs MCP (recherche web & outils)
chatUI.mcp câble des serveurs MCPServer dans l'interface LibreChat du Stack. Deux approches, combinables :
catalog— serveurs intégrés que le Stack provisionne et possède en tant qu'enfantsMCPServer(un par clé) et câble dans la ChatUI. Première entrée :websearch(recherche web d'entreprise). Nécessite la licencebundled-mcp-catalog; une entrée non autorisée estRefusedet ignorée (l'interface démarre quand même).refs— câble des CRMCPServerpréexistants que vous créez vous-même (catalogue ou externe — p. ex. un serveur MCP interne au cluster auto-hébergé), dans n'importe quel namespace. Le Stack les référence sans posséder leur cycle de vie.
spec:
chatUI:
enabled: true
mcp:
catalog: [ websearch ] # le Stack crée + câble le MCPServer
refs:
- { name: my-internal-mcp } # un MCPServer que vous gérezRéférencer un serveur MCP active automatiquement le point de terminaison Agents de LibreChat. Les enfants MCPServer du Stack apparaissent dans son arbre de progression et sont démantelés avec le Stack. Voir MCPServer pour la définition du serveur et la liste d'autorisation SSRF automatique.
Garde-fous (chemin de données)
gateway.guardrails câble des garde-fous de chemin de données Guardrail dans le Gateway du Stack. Deux méthodes combinables :
catalog— moteurs intégrés que le Stack provisionne et possède en tant qu'enfantsGuardrail(un par clé) et câble dans le Gateway. Première entrée :pseudonymizer(pseudonymisation des PII). Nécessite la licenceguardrail(Enterprise) ; une entrée non autorisée estRefusedet ignorée (le Gateway démarre quand même, sans protection).refs— câblent des CRsGuardrailpréexistants que vous créez vous-même (catalog ou garde-fou HTTP externe), dans n'importe quel namespace. Le Stack les référence sans en posséder le cycle de vie.
spec:
gateway:
enabled: true
guardrails:
catalog: [ pseudonymizer ] # le Stack crée + câble le Guardrail
refs:
- { name: my-guardrail } # un Guardrail que vous gérezLes garde-fous du catalogue comme externes sont sous licence et passent par le proxy de contrôle de licence injecté par l'opérateur (échoue en mode fermé si la licence expire). Les enfants Guardrail du Stack apparaissent dans son arbre de progression et sont démantelés avec le Stack. Voir Guardrail pour la définition complète.
Déboguer un garde-fou au sein d'un Stack
Définissez logLevel (et éventuellement blockedReason) sur le Stack, pas sur l'enfant :
spec:
gateway:
guardrails:
catalog: [ pseudonymizer ]
logLevel: debug # un enregistrement du proxy par requête
blockedReason: "blocked by the Navique license gate"Un Stack réécrit la spec curatée de chacun de ses enfants : avec la valeur par défaut driftPolicy: Enforce, un kubectl patch du logLevel sur le Guardrail enfant est donc annulé — et comme le Stack observe ses enfants Guardrail, le patch déclenche précisément la réconciliation qui le défait. (Avec driftPolicy: Adopt un patch manuel survit, mais seulement jusqu'à la prochaine modification du Stack, et cela désactive la correction de dérive pour tous les enfants.) Ces champs s'appliquent aux enfants catalog que le Stack possède ; les garde-fous câblés via refs vous appartiennent — définissez logLevel directement sur ces CR.
Les compteurs de décision du proxy ne demandent aucune activation — voir Diagnostic d'un appel de garde-fou en échec.
Sauvegardes et protection contre la suppression
Comme un Stack est le chemin emprunté par les utilisateurs non techniques, il traite les données avec état de manière défensive.
Les sauvegardes sont obligatoires pour les datastores avec état managés. Un Stack doit définir un backup activé pour chaque datastores.postgres, datastores.clickhouse et datastores.mongo managé (le même ensemble qui est verrouillé automatiquement) — sinon il est rejeté (Postgres à l'admission via CEL ; ClickHouse/Mongo au reconcile), de sorte que personne ne met en place un datastore sans sauvegardes. Redis (cache) et Meilisearch (index reconstructible) en sont exemptés. Le bloc a partout la même forme neutre (s3/azure/gcs + planification + rétention) et est propagé vers l'enfant managé ; Postgres utilise le PITR natif de CNPG, ClickHouse un CronJob clickhouse-backup, MongoDB un CronJob mongodump+rclone. Un datastore externe n'a besoin d'aucune sauvegarde ici — vous gérez cela vous-même. Définissez datastores.requireBackup: false pour ignorer l'exigence (utilisateurs avancés / CI).
Les datastores managés sont verrouillés automatiquement. Lorsque le Stack provisionne un PostgresCluster, un ClickHouseCluster ou un MongoCluster managé (qui contient l'historique des conversations de la ChatUI), il crée également un Lock dessus, de sorte qu'un kubectl delete accidentel est bloqué. Redis (un cache) et Meilisearch (un index de recherche reconstructible) ne sont jamais verrouillés.
- Il s'agit d'une protection contre la suppression au niveau de la couche de données : la suppression du
Stackreste bloquée tant que vous n'avez pas retiré ces Locks — les datastores (et leurs PVCs) ne sont jamais détruits par accident. Le Stack rapporte le ou les Locks bloquants dans son statut. - Le
Stackcrée chaque Lock une seule fois et n'en recrée jamais un que vous avez retiré — ainsi, pour supprimer unStackprotégé, il vous suffit de fairekubectl delete lock <name>d'abord, puis de supprimer leStack. L'opérateur ne vous fera pas la course en remettant le Lock. - Définissez
datastores.protectData: falsepour ne pas créer les Locks (les Locks existants sont laissés intacts).
spec:
datastores:
postgres:
storageSize: 20Gi
backup:
enabled: true
provider: s3
s3:
destinationPath: s3://forge-backups/pg
credentialsSecretRef: { name: pg-backup }
clickhouse: { storageSize: 20Gi }
redis: { storageSize: 5Gi }
# protectData: false # renoncer aux Locks automatiques (non recommandé)Séparation par namespace
Par défaut, chaque composant se place dans le namespace du Stack. Chaque bloc de composant accepte optionnellement un namespace pour le placer ailleurs :
spec:
gateway: { namespace: forge-gateway }
chatUI: { namespace: forge-ui }
observability: { type: langfuse } # reste dans le namespace du StackLorsqu'un composant déclare un namespace, le Stack :
- crée le namespace s'il n'existe pas (et le laisse en place à la suppression) ;
- place un
SecretsManagementdans chaque namespace hébergeant une charge de travail, afin que lesecretsRefde chaque composant se résolve localement ; - câble automatiquement les références cross-namespace (p. ex. une Gateway dans un namespace vers le Postgres/Langfuse dans un autre) — vous ne définissez toujours aucune référence à la main.
Comme les owner references Kubernetes ne peuvent pas franchir les namespaces, un enfant cross-namespace est suivi via le label core.navique.com/owned-by et retiré par le finalizer du Stack à la suppression (les enfants du même namespace conservent la cascade par owner reference). Les namespaces créés ne sont pas supprimés.
SSO / OIDC login
spec.sso configure l'authentification unique sur tout le Stack à partir d'un seul fournisseur d'identité. L'émetteur/fournisseur/scopes partagés s'appliquent à chaque composant activé, tandis que chaque composant obtient son propre client OAuth (les URLs de callback diffèrent) via une référence de client par composant. Un composant reçoit le SSO uniquement lorsqu'il est activé et que sa référence de client est définie, ce qui vous permet de déployer le SSO de manière sélective.
| Champ | Description |
|---|---|
issuerURL | URL de base partagée de l'émetteur OIDC / de découverte |
providerName | Libellé d'affichage partagé |
scopes | Scopes demandés partagés |
provider / tenantID / authorizationEndpoint / tokenEndpoint / userinfoEndpoint | Variante de fournisseur + endpoints réservés au Gateway (voir les notes SSO du Gateway) |
gateway / chatUI / observability | Références de client OAuth par composant ({ name, clientIDKey?, clientSecretKey? }) |
spec:
sso:
issuerURL: https://idp.example.com
providerName: "Acme SSO"
provider: generic-oidc
authorizationEndpoint: https://idp.example.com/authorize
tokenEndpoint: https://idp.example.com/token
userinfoEndpoint: https://idp.example.com/userinfo
gateway: { name: gateway-oidc }
chatUI: { name: chatui-oidc }
observability: { name: langfuse-oidc }C'est ce qui alimente le SSO en libre-service depuis l'assistant de déploiement de la console de gestion. Les détails par composant (les variables d'environnement que reçoit chaque application, les licences) figurent sur les pages Gateway, ChatUI et Observability.
Mesh
spec.mesh.mode inscrit les namespaces des composants du Stack au ServiceMesh du cluster (mTLS + isolation). Par défaut auto (rejoindre quand un ServiceMesh prêt existe, sinon no-op) ; enabled en exige un ; disabled ne rejoint jamais. Le Stack se contente d'étiqueter ses namespaces — le singleton ServiceMesh réalise l'inscription — de sorte qu'un mesh activé plus tard rejoint les Stacks existants sans redéploiement.
Licences
Stack requiert la fonctionnalité managed-deployment et un quota d'instances stacks dans la License. Sans eux, composez la plateforme avec les resources granulaires, qui sont toujours disponibles (sous réserve de leurs propres quotas dans l'édition Community).
Voir Éditions et licences.