Skip to content

Stack ​

Ambito: namespaced · Umbrella facoltativo · Soggetto a licenza (funzionalità managed-deployment + un limite stacks)

Stack è una risorsa umbrella facoltativa che crea e possiede un insieme curato di risorse granulari, collega automaticamente i loro riferimenti e aggrega l'avanzamento — un'esperienza di provisioning in un solo passaggio, nello stile dei deployment ARM.

Non sostituisce le risorse per singolo componente. I CRD granulari restano un modo di prima classe per comporre la piattaforma a mano; Stack si limita a porsi al di sopra per i team che vogliono un unico oggetto con cui gestire un intero ambiente.

Quando usarlo ​

  • Usa Stack quando vuoi eseguire il provisioning e il monitoraggio di un ambiente completo (secret + datastore + gateway + observability + UI) come un'unica unità, lasciando che l'operatore colleghi i riferimenti incrociati e riunisca lo stato in un solo punto.
  • Usa le risorse granulari quando vuoi un controllo dettagliato, componi a mano risorse distribuite su più namespace, oppure condividi datastore tra più workload gestiti in modo indipendente.

Cosa fa ​

  • Crea e possiede i componenti inclusi (l'operatore imposta gli owner reference, così l'intero insieme viene rimosso dal garbage collector insieme allo Stack).
  • Collega automaticamente i riferimenti tra di essi (Gateway→Postgres, Gateway→Observability, ChatUI→Gateway, workload→datastore) — ciò si basa sulla capacità auto-wiring.
  • Aggrega l'avanzamento in status.components[] e status.endpoints, così un singolo kubectl get stack mostra la readiness e gli URL dell'intero ambiente.

Politica di drift ​

Per impostazione predefinita lo Stack impone continuamente la spec curata ai propri figli: qualsiasi modifica manuale a un CR di componente generato (ad esempio aumentare la dimensione dello storage di un datastore o il numero di repliche di un workload) viene annullata alla riconciliazione successiva. spec.driftPolicy consente di allentare questo comportamento:

driftPolicyComportamento
Enforce (predefinito)La spec curata viene riaffermata a ogni riconciliazione — le modifiche manuali ai figli vengono annullate (correzione completa del drift).
AdoptLa spec curata viene applicata alla creazione e ogni volta che cambia la spec dello Stack stesso (un "redeploy" in stile ARM). Tra una modifica dello Stack e l'altra, le modifiche manuali ai singoli componenti vengono preservate.

Adopt rispecchia il comportamento di un deployment Azure Resource Manager: lo Stack crea e collega le risorse, ma in seguito puoi regolare ciascun componente direttamente. Modificare lo Stack stesso riafferma ogni figlio e sovrascrive il tuo drift, quindi considera una modifica dello Stack come un redeploy.

L'owner reference viene mantenuto con entrambe le politiche, quindi eliminare lo Stack si propaga sempre a (e smantella) ogni componente che ha creato.

yaml
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
  name: forge
spec:
  driftPolicy: Adopt   # let users tune individual components after creation
  # ...

Dimensionamento dei datastore ​

Ogni datastore gestito sotto spec.datastores accetta una forma abbreviata resources facoltativa che dimensiona CPU e memoria del container sottostante. È supportata per i datastore Postgres, ClickHouse, Redis e MongoDB (solo in modalità managed) e viene riportata nel figlio emesso PostgresCluster / ClickHouseCluster / RedisInstance / MongoCluster come suo managed.resources.

CampoCorrisponde a
cpurequest di CPU
memoryrequest di memoria
memoryLimitlimit di memoria

La forma abbreviata volutamente non prevede un limit di CPU (i limit di CPU rallentano anziché proteggere). Se ne hai bisogno, usa direttamente il CRD del datastore autonomo, che accetta un managed.resources completo.

yaml
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 }

Quando resources è omesso si applicano i valori predefiniti del chart upstream (ClickHouse mantiene il limit di memoria di 3Gi regolato dall'operatore, per evitare OOM sotto il carico di Langfuse).

Scegliere l'implementazione del gateway ​

spec.gateway.type seleziona il prodotto gateway: litellm (predefinito) oppure waeg (il gateway Wäg, tramite il waeg-operator). Vedi Gateway → Gateway Wäg per le differenze.

Con type: waeg lo Stack:

  • richiede datastores.clickhouse.enabled nella modalità di storage predefinita split — altrimenti l'admission rifiuta lo Stack, perché è lì che risiedono i dati analitici di Wäg. Imposta gateway.waeg.storageMode: single per mantenerli invece nel Postgres dello Stack, eliminando del tutto il requisito — vedi Storage analitico di Wäg;
  • collega automaticamente il ClickHouse dello Stack (e Redis, se abilitato) come secondo piano di storage del gateway — solo in modalità split;
  • dichiara il database waeg su quel ClickHouse, affinché il gateway possa avviarsi: Wäg crea solo le proprie tabelle, mai il proprio database (ClickHouseCluster → databases[]);
  • assegna al database Postgres logico del gateway il nome waeg anziché litellm, così le due implementazioni non condividono mai uno schema;
  • non collega alcun riferimento a Langfuse — Wäg non può esportare le trace in modo dichiarativo, quindi lo Stack non ne collega uno solo per vederlo rifiutato dal Gateway.

spec.gateway.waeg inoltra le opzioni specifiche di Wäg: topology, jobWorkers, worker, storageMode, openfga, autoscaling, bootstrapAdmin, dataEncryptionKeySecretRef, modelAccess, scim e jwt. La licenza Enterprise viene dichiarata una sola volta, in spec.gateway.licenseSecretRef, e l'organization del gateway in spec.gateway.organization — necessaria a un gateway type: waeg prima che una ChatUI possa collegarvisi.

yaml
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: true

I campi seguenti specifici di LiteLLM (rolePermissions, healthCheck, storePromptsInLogs, guardrails, i limiti per modello — e la parte di jwtAuth relativa alle mappature dei claim) vengono segnalati nella condizione FeaturesSupported del Gateway figlio quando type: waeg — non vengono mai scartati silenziosamente.

Storage analitico di Wäg ​

spec.gateway.waeg.storageMode seleziona dove risiedono i dati analitici del gateway (log delle richieste, utilizzo, spesa). È il passthrough a livello di Stack di Gateway.spec.waeg.storageMode.

ModalitàDati analitici indatastores.clickhouse.enabled
split (predefinito)il ClickHouse dello Stackobbligatorio
singleil Postgres dello Stacknon necessario — non viene effettuato il provisioning di alcun ClickHouse

Il valore predefinito di Wäg upstream è single, ed è il punto di partenza consigliato; questo operatore mantiene split come predefinito per continuità e perché regge i volumi elevati. Con single lo Stack non effettua il provisioning di alcun ClickHouse e la regola di admission che ne richiedeva uno non si applica più. Lasciare il valore predefinito senza un ClickHouse viene rifiutato con:

gateway.type=waeg with the default storageMode 'split' requires
datastores.clickhouse.enabled; set gateway.waeg.storageMode: single to keep
analytics in Postgres instead

Cambiare modalità non migra lo storico analitico

I due piani sono store separati. Cambiare storageMode su uno Stack in esecuzione fa puntare il gateway all'altro; i dati analitici già raccolti restano dove erano, e né l'operatore né Wäg li copiano.

yaml
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 }
    # no clickhouse block at all — storageMode: single needs none
  gateway:
    enabled: true
    type: waeg
    organization: { name: forge }
    waeg:
      storageMode: single

Nella modalità predefinita split lo Stack dichiara inoltre il database waeg sul proprio ClickHouse gestito, perché Wäg crea solo le proprie tabelle e mai il proprio database — vedi ClickHouseCluster → databases[].

Organization del gateway ​

spec.gateway.organization crea l'organization di primo livello del gateway — l'oggetto a cui fanno capo budget e limiti di frequenza. Viene passata direttamente al campo spec.organization del Gateway figlio.

CampoDescrizione
name (obbligatorio)Il nome dell'organization
maxBudgetTetto di spesa per l'organization
budgetDurationPeriodo dopo il quale il tetto si azzera (ad es. 30d). Solo LiteLLM — le policy di budget di Wäg non hanno un campo per il periodo
rpmLimitLimite di richieste al minuto
tpmLimitLimite di token al minuto

Su un gateway type: litellm un'organization resta facoltativa — team, chiavi e modelli funzionano tutti anche senza.

Un gateway Wäg ne richiede una prima che una ChatUI possa collegarsi

Con type: waeg questo campo è obbligatorio per collegare automaticamente una ChatUI. Wäg non ha virtual key autonome: una chiave appartiene a un'applicazione, e le applicazioni hanno radice nell'organization — quindi senza organization non c'è nulla sotto cui generare la credenziale della ChatUI. Prima che esistesse questo campo, uno Stack con gateway.type: waeg e chatUI.enabled: true lasciava la ChatUI bloccata su

Gateway "…" is type=waeg and has no spec.organization: a Wäg virtual key belongs
to an application, and applications are org-rooted

senza nulla di impostabile da uno Stack per soddisfarla — il Gateway granulare aveva spec.organization, lo Stack non prevedeva alcun passthrough. Impostalo qui e la ChatUI viene registrata come WaegApplication sotto quella organization, con il suo WaegVirtualKey generato di conseguenza.

L'organization è anche ciò a cui si agganciano i grant di spec.gateway.waeg.modelAccess: l'ACL dei modelli è dichiarata rispetto ad essa, quindi senza organization i grant vengono ignorati.

yaml
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:                  # org-rooted: needs the organization above
        openByDefault: false
        fallbackMode: deny
        grants:
          - models: [premium, economy]
  chatUI:
    enabled: true                   # auto-wired as an application under navique-ag

Vedi La ChatUI si connette come applicazione per gli oggetti emessi dall'operatore, e Cosa non viene applicato per i campi dell'organization che Wäg non può rispettare.

Licenza Enterprise del gateway ​

spec.gateway.licenseSecretRef fornisce la licenza Enterprise del gateway stesso, passata all'instance.licenseSecretRef del Gateway. Per type: litellm è la chiave LiteLLM Enterprise; per type: waeg è la licenza Wäg Enterprise, ed è ciò che distingue un gateway Enterprise funzionante da uno che risponde 402 license_required.

Ogni modulo Wäg Enterprise dipende da essa — SSO, SCIM, audit, CMEK, FIPS e branding della console — e l'applicazione è incondizionata, quindi senza questo campo un gateway Wäg gestito da uno Stack non ha alcuna funzionalità Enterprise raggiungibile.

yaml
spec:
  gateway:
    type: waeg
    licenseSecretRef: { name: waeg-enterprise-license, key: license }

La chiave del Secret è per impostazione predefinita license. Lascia che il backend SecretsManagement dello Stack materializzi il Secret invece di crearlo a mano.

Il branding segue la licenza

Una volta che un gateway Wäg dispone di licenza, l'operatore applica automaticamente alla sua console il theme pack Navique integrato (una ConfigMap <gateway>-branding di sua proprietà). Lo Stack non prevede un campo di opt-out — per impostare un pack tuo, o per mantenere l'aspetto di Wäg, usa il Gateway granulare con waeg.brandingConfigMapRef / waeg.defaultBranding: false.

Dimensionamento del gateway ​

spec.gateway.resources dimensiona il container del proxy LiteLLM. A differenza della forma abbreviata dei datastore, è un ResourceRequirements Kubernetes completo (quindi puoi impostare un limit di CPU), passato direttamente all'instance.resources del Gateway emesso → allo spec.resources del LiteLLMInstance. Omettilo per lasciare il valore predefinito del litellm-operator.

yaml
spec:
  gateway:
    resources:
      requests: { cpu: "500m", memory: 512Mi }
      limits:   { cpu: "2", memory: 2Gi }

Fissare la build del proxy del gateway ​

spec.gateway.image fissa l'immagine del proxy LiteLLM, passata all'instance.image del Gateway emesso → allo spec.image del LiteLLMInstance.

yaml
spec:
  gateway:
    image:
      repository: ghcr.io/berriai/litellm
      tag: v1.94.0-dev.2

Lascialo non impostato, a meno che tu non stia qualificando una build specifica. Senza un valore fissato il litellm-operator applica il proprio tag predefinito — quello convalidato con il suo entrypoint di migrazione del database — quindi un tag arbitrario può compromettere la migrazione e lasciare il gateway fuori servizio.

Non provare invece a modificare a mano il Gateway figlio: con la politica di drift predefinita Enforce lo Stack riapplica i propri figli a ogni riconciliazione e la tua modifica viene annullata in pochi secondi. Dichiara qui il valore fissato.

Autenticazione JWT e RBAC del gateway ​

spec.gateway.jwtAuth e spec.gateway.rolePermissions abilitano l'autenticazione API basata su JWT e l'accesso ai modelli per ruolo sul Gateway dello Stack — passati direttamente a instance.jwtAuth / instance.rolePermissions del Gateway. Vedi Autenticazione API tramite JWT e RBAC per i campi. Richiede una licenza LiteLLM Enterprise.

yaml
spec:
  gateway:
    jwtAuth:
      enabled: true
      userRolesJWTField: roles
      userAllowedRoles: ["basic_user"]
      enforceRBAC: true
    rolePermissions:
      internal_user: { models: ["anthropic-claude"] }

Branding della console Wäg ​

spec.gateway.waeg.brandingConfigMapRef e defaultBranding vengono inoltrati al branding della console del Gateway: il tema Navique per impostazione predefinita, un tuo theme pack con la funzionalità soggetta a licenza custom-branding, oppure l'aspetto di Wäg con defaultBranding: false.

Su un gateway Wäg ​

spec.gateway.jwtAuth attiva l'autenticazione JWT anche per type: waeg — enabled, publicKeyURL (→ jwksUrl di Wäg), issuer, audience e userIDJWTField (→ subjectClaim) si applicano tutti. Le opzioni specifiche di Wäg si trovano in spec.gateway.waeg.jwt, mentre spec.gateway.rolePermissions e le mappature dei claim (userRolesJWTField, userRoleJWTField, userAllowedRoles, enforceRBAC, userIDUpsert, teamIDsJWTField, adminJWTScope) vengono invece segnalati come non supportati: Wäg autorizza tramite OpenFGA e le applicazioni registrate. Vedi Autenticazione JWT del data plane.

yaml
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: true

Gli interruttori di hardening possono impedire l'avvio del gateway

waeg.jwt.allowMasterKey: false o allowVirtualKeys: false richiedono jwtAuth.enabled: true, un publicKeyURL, un'audience e insecureSkipVerify: false — altrimenti Wäg si rifiuta di avviarsi. allowVirtualKeys: false blocca inoltre ogni chiave di applicazione, inclusa quella della ChatUI dello Stack.

Provisioning SCIM di Wäg ​

spec.gateway.waeg.scim attiva gli endpoint SCIM v2 di Wäg sul gateway dello Stack, così il tuo IdP crea e disattiva direttamente gli utenti della console. È indipendente dall'SSO — funziona anche senza alcun login interattivo collegato — e richiede spec.gateway.licenseSecretRef.

yaml
spec:
  gateway:
    type: waeg
    licenseSecretRef: { name: waeg-enterprise-license, key: license }
    waeg:
      scim:
        enabled: true                                              # default
        tokenSecretRef: { name: waeg-scim-token, key: scim-token }  # required
        defaultRole: viewer
        orgSource: waeg
        roleMap: { "AI Platform Admins": admin }

Il bearer token viene proiettato sui pod del gateway come WAEG_EE_SCIM_TOKEN, quindi ruotare il Secret è l'intera procedura di rotazione. Gli endpoint si trovano sotto /waeg/admin/v1/ee/scim/v2. Vedi Provisioning SCIM per tutti i campi.

Datastore della ChatUI: MongoDB e Meilisearch ​

MongoDB (lo store delle conversazioni) e Meilisearch (la ricerca) supportano la ChatUI e si configurano sotto datastores.mongo / datastores.meilisearch — con lo stesso selettore mode: managed | external degli altri datastore. Il loro provisioning avviene solo quando la ChatUI è abilitata, e per impostazione predefinita sono managed.

  • managed (predefinito): lo Stack effettua il provisioning di un MongoCluster / MeilisearchInstance, ne è proprietario e vi collega la ChatUI. Dimensionali con storageSize (Meilisearch supporta anche storageClass / resources).
  • external: non viene creato alcun CR di datastore; la ChatUI viene collegata a un'istanza gestita dall'utente. Mongo richiede connectionSecretRef (chiave del Secret MONGO_URI, sovrascrivibile con .key). Meilisearch richiede host più un connectionSecretRef che contenga la master key (chiave del Secret MEILI_MASTER_KEY).
yaml
spec:
  datastores:
    mongo:
      mode: managed
      storageSize: 10Gi
    meilisearch:
      mode: external
      host: https://search.example.com
      connectionSecretRef: { name: meili-master-key }   # key MEILI_MASTER_KEY

Server MCP (ricerca web e strumenti) ​

chatUI.mcp collega server MCPServer alla UI LibreChat dello Stack. Due modalità, combinabili:

  • catalog — server inclusi di cui lo Stack effettua il provisioning e che possiede come figli MCPServer (uno per chiave), collegandoli alla ChatUI. Prima voce: websearch (ricerca web enterprise). Richiede la licenza bundled-mcp-catalog; una voce senza licenza è Refused e viene saltata (la UI si avvia comunque).
  • refs — collega CR MCPServer preesistenti creati da te (da catalogo o esterni — ad es. un server MCP self-hosted nel cluster), in qualsiasi namespace. Lo Stack vi fa riferimento senza possederne il ciclo di vita.
yaml
spec:
  chatUI:
    enabled: true
    mcp:
      catalog: [ websearch ]                 # Stack creates + wires the MCPServer
      refs:
        - { name: my-internal-mcp }          # an MCPServer you manage

Fare riferimento a un qualsiasi server MCP abilita automaticamente l'endpoint Agents di LibreChat. I figli MCPServer dello Stack compaiono nel suo albero di avanzamento e vengono smantellati insieme allo Stack. Vedi MCPServer per la definizione del server e la allowlist SSRF automatica.

Guardrail (percorso dei dati) ​

gateway.guardrails collega guardrail del percorso dei dati Guardrail al Gateway dello Stack. Due modalità, combinabili:

  • catalog — motori inclusi di cui lo Stack effettua il provisioning e che possiede come figli Guardrail (uno per chiave), collegandoli al Gateway. Prima voce: pseudonymizer (pseudonimizzazione dei dati personali). Richiede la licenza guardrail (Enterprise); una voce senza licenza è Refused e viene saltata (il Gateway si avvia comunque, senza protezione).
  • refs — collega CR Guardrail preesistenti creati da te (da catalogo o guardrail HTTP esterno), in qualsiasi namespace. Lo Stack vi fa riferimento senza possederne il ciclo di vita.
yaml
spec:
  gateway:
    enabled: true
    guardrails:
      catalog: [ pseudonymizer ]             # Stack creates + wires the Guardrail
      refs:
        - { name: my-guardrail }             # a Guardrail you manage

Sia i guardrail da catalogo sia quelli esterni sono soggetti a licenza e passano attraverso il proxy license-gate iniettato dall'operatore (che fallisce in modo chiuso se la licenza decade). I figli Guardrail dello Stack compaiono nel suo albero di avanzamento e vengono smantellati insieme allo Stack. Vedi Guardrail per la definizione completa.

Eseguire il debug di un guardrail all'interno di uno Stack ​

Imposta logLevel (e facoltativamente blockedReason) sullo Stack, non sul figlio:

yaml
spec:
  gateway:
    guardrails:
      catalog: [ pseudonymizer ]
      logLevel: debug                        # one proxy log record per request
      blockedReason: "blocked by the Navique license gate"

Uno Stack riscrive la spec curata di ogni figlio, quindi con la driftPolicy: Enforce predefinita un kubectl patch del logLevel del Guardrail figlio viene annullato — e poiché lo Stack osserva i propri figli Guardrail, la patch innesca proprio la riconciliazione che la annulla. (Con driftPolicy: Adopt una patch manuale sopravvive, ma solo fino alla modifica successiva dello Stack, e disattiva la correzione del drift per ogni figlio.) Questi campi si applicano ai figli catalog posseduti dallo Stack; i guardrail collegati tramite refs sono tuoi, quindi imposta logLevel direttamente su quei CR.

I contatori delle decisioni del proxy non richiedono alcun opt-in — vedi Risoluzione dei problemi di una chiamata guardrail non riuscita.

Backup e protezione dall'eliminazione ​

Poiché uno Stack è il percorso scelto dagli utenti non tecnici, tratta i dati con stato in modo difensivo.

I backup sono obbligatori per i datastore con stato gestiti. Uno Stackdeve impostare un backup abilitato su ogni datastores.postgres, datastores.clickhouse e datastores.mongo gestito (lo stesso insieme a cui viene applicato automaticamente un Lock) — applicarne uno senza backup viene rifiutato (Postgres in fase di admission tramite CEL; ClickHouse/Mongo in fase di riconciliazione), così nessuno avvia un datastore privo di backup. Redis (cache) e Meilisearch (un indice ricostruibile) sono esenti. Il blocco ha ovunque la stessa forma indipendente dal provider (s3/azure/gcs + pianificazione + retention) e viene riportato nel figlio gestito; Postgres esegue il PITR nativo di CNPG, ClickHouse un CronJob clickhouse-backup, MongoDB un CronJob mongodump+rclone. I datastore esterni non richiedono qui alcun backup — lo gestisci tu. Imposta datastores.requireBackup: false per saltare il requisito (utenti avanzati / CI).

Ai datastore gestiti viene applicato automaticamente un Lock. Quando lo Stack effettua il provisioning di un PostgresCluster, ClickHouseCluster o MongoCluster gestito (quest'ultimo contiene la cronologia delle conversazioni della ChatUI), crea anche un Lock su di esso, così un kubectl delete accidentale viene bloccato. Redis (una cache) e Meilisearch (un indice di ricerca ricostruibile) non vengono mai bloccati.

  • Si tratta di una protezione dall'eliminazione a livello di dati: l'eliminazione dello Stack resta bloccata finché non rimuovi quei Lock — i datastore (e i loro PVC) non vengono mai distrutti per errore. Lo Stack riporta nel proprio status i Lock che lo bloccano.
  • Lo Stack crea ciascun Lock una sola volta e non ricrea mai un Lock che hai rimosso — quindi per eliminare uno Stack protetto basta eseguire prima kubectl delete lock <name> e poi eliminare lo Stack. L'operatore non ti ostacolerà rimettendo il Lock al suo posto.
  • Imposta datastores.protectData: false per non creare i Lock (i Lock esistenti restano invariati).
yaml
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   # opt out of the auto-Locks (not recommended)

Separazione per namespace ​

Per impostazione predefinita ogni componente finisce nel namespace dello Stack stesso. Ogni blocco di componente accetta facoltativamente un namespace per collocarlo altrove:

yaml
spec:
  gateway:       { namespace: forge-gateway }
  chatUI:        { namespace: forge-ui }
  observability: { type: langfuse }   # stays in the Stack's namespace

Quando un componente dichiara un namespace, lo Stack:

  • crea il namespace se non esiste (e lo lascia al suo posto in caso di eliminazione);
  • colloca un SecretsManagement in ogni namespace che ospita un workload, così il secretsRef nello stesso namespace di ciascun componente viene risolto localmente;
  • collega automaticamente i riferimenti tra namespace (ad es. un Gateway in un namespace verso il Postgres/Langfuse in un altro) — non devi comunque impostare alcun riferimento a mano.

Poiché gli owner reference di Kubernetes non possono attraversare i namespace, un figlio in un altro namespace viene tracciato tramite l'etichetta core.navique.com/owned-by e rimosso dal finalizer dello Stack all'eliminazione (i figli nello stesso namespace mantengono la propagazione tramite owner reference). I namespace creati automaticamente non vengono eliminati.

Login SSO / OIDC ​

spec.sso configura il single sign-on per l'intero Stack a partire da un solo identity provider. Issuer/provider/scope condivisi si applicano a ogni componente abilitato, mentre ogni componente riceve il proprio client OAuth (gli URL di callback differiscono) tramite un riferimento al client per componente. Un componente riceve l'SSO solo se è abilitato e il suo riferimento al client è impostato, così puoi introdurre l'SSO in modo selettivo.

CampoDescrizione
issuerURLIssuer OIDC / URL base di discovery condiviso
providerNameEtichetta visualizzata condivisa
scopesScope richiesti condivisi
provider / tenantID / authorizationEndpoint / tokenEndpoint / userinfoEndpointTipo di provider + endpoint, solo per il Gateway (vedi le note SSO del Gateway)
gateway / chatUI / observabilityRiferimenti al client OAuth per componente ({ name, clientIDKey?, clientSecretKey? })
yaml
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 }

È ciò che rende possibile l'SSO self-service dalla procedura guidata di deployment della console di gestione. I dettagli per componente (quali variabili d'ambiente riceve ciascuna app, licenze) si trovano nelle pagine Gateway, ChatUI e Observability.

Mesh ​

spec.mesh.mode fa aderire i namespace dei componenti dello Stack alla ServiceMesh del cluster (mTLS + isolamento). Il valore predefinito è auto (adesione quando esiste una ServiceMesh Ready, nessun effetto altrimenti); enabled ne richiede una; disabled non aderisce mai. Lo Stack si limita ad applicare etichette ai propri namespace — l'iscrizione è compito del singleton ServiceMesh — quindi una mesh abilitata in seguito include gli Stack esistenti senza redeploy.

Licenze ​

Stack richiede la funzionalità managed-deployment e un limite di istanze stacks nella License. In loro assenza, componi la piattaforma con le risorse granulari, sempre disponibili (nel rispetto dei rispettivi limiti nell'edizione Community).

Vedi Edizioni e licenze.

Nucleo open source sotto AGPL-3.0. I componenti Enterprise sono proprietari e soggetti a licenza.