ManagementPlane
Ambito: namespaced · Opzionale (la console viene distribuita di default)
Il Navique AI Core Management Plane è la console di amministrazione dell'intera piattaforma — un'unica UI web per vedere tutto ciò che l'operatore gestisce, attivare una licenza e (se licenziato) esportare il modo in cui gli utenti hanno usato il gateway AI. L'operatore la distribuisce di default, anche quando non esiste alcuna risorsa ManagementPlane; questa risorsa si limita a sovrascrivere i valori predefiniti (host, ingress, SSO, immagine, discovery).
Che cos'è il management plane
È una console di amministrazione proprietaria — la controparte closed-source dell'operatore open-source. Mentre l'operatore esegue la piattaforma, il management plane offre a una persona un unico punto di controllo su di essa:
- Vedere in un unico posto ogni risorsa gestita dall'operatore e il suo stato in tempo reale, invece di eseguire
kubectlsu una dozzina di custom resource in diversi namespace. - Visualizzare e attivare la licenza della piattaforma da un browser.
- Per i clienti soggetti a regolamentazione, esportare la cronologia di utilizzo / conversazione del gateway di un utente su una finestra temporale come JSON o CSV (una funzionalità con licenza).
Viene distribuita solo come immagine container precompilata ed è riservata agli admin in v1. Essendo proprietaria, non effettua deliberatamente il link del codice AGPL dell'operatore — legge le risorse dell'operatore tramite l'API Kubernetes come qualsiasi altro client. (Un controllo in fase di build fallisce se viene linkato un qualsiasi pacchetto dell'operatore.)
Perché è utile
| Capacità | Disponibilità |
|---|---|
| Visualizzare le risorse gestite dall'operatore + stato in tempo reale su tutti i namespace | Baseline gratuita (qualsiasi licenza o nessuna) |
| Individuare le istanze LiteLLM / Langfuse in esecuzione e la loro raggiungibilità | Baseline gratuita |
Visualizzare e attivare una licenza (crea/aggiorna la risorsa License) | Baseline gratuita — l'unica azione di scrittura |
| Esportare la cronologia di utilizzo / conversazione del gateway di un utente (audit, JSON/CSV) | Con licenza: management-plane-audit-export |
Le funzionalità soggette a licenza falliscono in modo chiuso (fail closed) senza l'entitlement; la baseline gratuita è sempre disponibile, anche senza alcuna licenza.
Come funziona
La console è un BFF di aggregazione di API (backend-for-frontend), non una pipeline di osservabilità né un database. Un backend Go serve una single-page app Nuxt + Vue (incorporata nel binario, quindi senza Node a runtime — ideale per installazioni air-gapped) e un'API JSON. Legge da tre sorgenti e non memorizza alcun dato proprio della piattaforma:
Admin browser ──▶ Nuxt SPA (served by Go via embed)
│ JSON BFF API
▼
Go backend (auth · discovery · license · audit · api)
│ Kubernetes API │ LiteLLM API │ Langfuse API
▼ operator CRs + status ▼ usage / spend ▼ conversation traces
License CR (read+write) (audit primary) (audit supplement)- API Kubernetes (tramite il dynamic client + il ServiceAccount della console) — le risorse dell'operatore e il loro
.status, più la lettura e la scrittura dellaLicense. - API LiteLLM — utilizzo, spesa e attività per utente finale (la sorgente di audit primaria).
- API Langfuse — trace delle conversazioni (contenuto di audit supplementare).
Le credenziali per LiteLLM/Langfuse vengono lette dai Secret Kubernetes tramite il ServiceAccount della console e non raggiungono mai il browser. Il backend mette in cache l'elenco delle risorse e le istanze individuate, così la dashboard è istantanea (vedi Ottimizzazione della cache).
Accesso e autorizzazioni
Due metodi di login, entrambi integrati:
Admin locale — un amministratore di bootstrap, per cluster senza SSO o air-gapped. Abilitalo in
auth.localAdmin. Se non fornisci uncredentialsSecretRef, l'operatore genera automaticamente le credenziali: crea un Secretnavique-management-plane-consoledi sua proprietà contenente lousername(dalocalAdmin.username, predefinitoadmin) e unapasswordcasuale, e registra il nome del Secret instatus.localAdminSecret. Leggi la password generata con:bashkubectl get secret navique-management-plane-console -n navique-system \ -o jsonpath='{.data.password}' | base64 -dFornisci un
credentialsSecretRef(un Secret con le chiaviusernameepassword) solo se vuoi gestire le credenziali in autonomia.Microsoft Entra OIDC — configura issuer, client ID e client secret; il pulsante SSO compare quindi automaticamente.
Configura entrambi tramite il blocco auth di questa risorsa. L'operatore genera inoltre una SESSION_KEY stabile nello stesso Secret della console di sua proprietà, così i login sopravvivono ai riavvii e allo scale-out della console.
Attivare una licenza dalla console
L'attivazione della licenza è l'unica scrittura eseguita dalla console. Dalla pagina License un admin incolla o carica un token di licenza firmato; il backend verifica la firma e mostra un'anteprima degli entitlements decodificati (funzionalità + limiti di istanze) prima di modificare qualsiasi cosa; alla conferma crea o aggiorna la risorsa License e il Secret di supporto. L'operatore acquisisce quindi i nuovi entitlements al reconcile successivo.
È lo stesso token firmato usato ovunque — la console incorpora la stessa chiave pubblica Ed25519 dell'operatore, quindi un token viene interpretato in modo identico da entrambe le parti. Vedi Gestire una licenza per il percorso via CLI e Edizioni e licenze per il significato di funzionalità e limiti.
Audit ed export di utilizzo (con licenza)
La prima funzionalità con licenza (management-plane-audit-export) consente a un admin di esportare come un utente finale ha usato il gateway su una finestra temporale. È pensata per le organizzazioni regolamentate che devono rispondere alla domanda "che cosa ha inviato questo utente attraverso la piattaforma AI, e quando?"
- L'identità dell'utente finale è l'email dell'utente (
x-litellm-end-user-id), propagata LibreChat → LiteLLM → Langfuse. - LiteLLM è la sorgente primaria (timestamp, modello, token, spesa, stato e contenuto della richiesta dove memorizzato); Langfuse la integra con un contenuto delle conversazioni più ricco, dove disponibile. Se Langfuse è assente, l'export funziona comunque solo con LiteLLM e lo segnala.
- L'output è JSON o CSV normalizzato, in streaming (non bufferizzato), con un blocco
metache registra chi lo ha eseguito, l'utente di destinazione, la finestra temporale, l'istanza e le sorgenti usate. - Gli export sono a loro volta sottoposti ad audit. Ogni export scrive un record di meta-audit (identità dell'operatore, utente di destinazione, finestra, formato, numero di righe, sorgenti) nel log dell'applicazione e in una destinazione persistente nel cluster — rispondendo a "chi ha esportato i dati di chi, e quando".
Il contenuto delle conversazioni è sensibile: la funzionalità è riservata agli admin, il contenuto non viene mai registrato nei log in chiaro e l'export è sottoposto a meta-audit. La console rispetta la retention degli strumenti upstream — legge ciò che LiteLLM/Langfuse conservano ancora e non memorizza nulla in proprio.
Sicurezza e confini
- RBAC con privilegio minimo. L'operatore fornisce alla console un ServiceAccount la cui unica scrittura è l'attivazione della licenza; tutto il resto è in sola lettura (vedi Cosa riconcilia il controller).
- Sicuro rispetto all'AGPL. La console proprietaria legge le risorse dell'operatore tramite il dynamic client Kubernetes e non importa i pacchetti AGPL dell'operatore, quindi il confine open-core resta intatto. L'operatore si limita a referenziare e distribuire l'immagine.
- Non sostituisce Langfuse. Langfuse resta lo strumento di tracing LLM; la console è la superficie di amministrazione trasversale ai componenti che vi rimanda e ne attinge i dati.
- Fuori dagli obiettivi di v1: RBAC multi-tenant, gestione in scrittura di istanze/modelli/team e uno store di osservabilità integrato — possibili in futuro, oggi fuori ambito.
Spec
| Campo | Tipo | Descrizione |
|---|---|---|
image | string | Sovrascrive immagine/tag (predefinito: fissato dall'operatore) |
ingress | object | Route pubblica per la console — host, TLS (cert-manager), className e api (Ingress / Gateway). Vedi Routing |
auth | object | OIDC (Entra) e/o un admin locale di bootstrap |
discovery | object | Override espliciti degli endpoint, uniti alla auto-discovery dei CR. Vedi Discovery |
resources | object | Request e limit di CPU/memoria applicati al container della console |
replicas | int | Numero di repliche della console (predefinito 1) |
Routing
La console è costruita dall'operatore (non è un Helm chart), quindi l'operatore emette direttamente la sua route pubblica. Entrambe le API di routing sono supportate e selezionate in base al valore predefinito a livello di cluster PlatformConfig.spec.routing, sovrascrivibile per singola console con ingress.api:
- Ingress classico (
api: Ingress, oppure il predefinito quando nessuna mesh è attiva) — l'operatore crea un Ingressnetworking.k8s.io/v1(con il nome del CR) che instradahost→ il Service della console. Vengono rispettaticlassName, il TLS di cert-manager (tls+clusterIssuer), ilbasicAuthSecretdi nginx e leannotationspersonalizzate. - Gateway API (
api: Gateway, oppure il predefinito quando una mesh è attiva) — l'operatore emette unaHTTPRoutecollegata al Gateway gestito condiviso. Richiede i CRD della Gateway API; finché non sono presenti la console riporta una conditionWaiting.
Discovery
Di default la console individua automaticamente le istanze LiteLLM/Langfuse in esecuzione dai relativi CR Gateway/Observability. discovery.litellmEndpoints / discovery.langfuseEndpoints aggiungono URL di endpoint espliciti che vengono uniti a tale auto-discovery — utili per istanze esterne o di altri cluster che non sono CR dell'operatore. Questi endpoint manuali compaiono nella dashboard e vengono sondati per la raggiungibilità; poiché non hanno un Secret di credenziali associato, le funzionalità che richiedono credenziali (export di utilizzo/audit) restano disponibili solo per le istanze individuate tramite CR.
auth
| Campo | Descrizione |
|---|---|
oidc | Entra: issuerURL, clientID, clientSecretRef |
localAdmin | Admin di bootstrap per configurazioni senza SSO / air-gapped |
auth.localAdmin
| Campo | Descrizione |
|---|---|
enabled | Attiva il login dell'admin locale |
username | Username di login (predefinito admin) |
credentialsSecretRef | Opzionale. Un Secret con le chiavi username e password. Omettilo perché l'operatore generi automaticamente le credenziali nel Secret navique-management-plane-console di sua proprietà |
Cosa riconcilia il controller
- Un Deployment + Service + Ingress opzionale per l'immagine del management plane — una console per cluster (vedi Singleton di cluster e rilocazione). Senza alcuna risorsa
ManagementPlanerisiede nel namespace di sistema (ad es.navique-system); con una risorsa risiede nel namespace di quella risorsa. - Un ServiceAccount con RBAC a privilegio minimo:
get/list/watcha livello di cluster su tutte le risorse*.core.navique.come su/status;getsui Secret delle credenziali di LiteLLM/Langfuse;create/update/getsulicenses.core.navique.come sul Secret della licenza (l'unica scrittura della console — l'attivazione della licenza);create/patchsuevents(una destinazione di meta-audit).
- La configurazione dalla risorsa
ManagementPlane, se presente; altrimenti valori predefiniti sensati.
Singleton di cluster e rilocazione
La console dispone di RBAC a livello di cluster, quindi eseguirne più di una non è mai utile. L'operatore impone esattamente una console per cluster:
- Predefinito (nessuna risorsa): la console viene eseguita nel namespace di sistema (
navique-system). - Rilocazione: applica un
ManagementPlanein un altro namespace e l'operatore vi sposta l'unica console — crea la console nel tuo namespace ed elimina quella predefinita innavique-system. Non esiste mai una seconda console. Elimina la risorsa e la console torna innavique-system. - Più di una risorsa: vince il
ManagementPlanepiù vecchio, che governa la console; ogni risorsa più recente riportastatus.phase: Superseded(Ready=False, reasonSuperseded) e non distribuisce nulla. Elimina quella attiva e la successiva in ordine di anzianità viene promossa automaticamente.
Si tratta esclusivamente di un comportamento del controller — non esiste alcuna admission policy che imponga un nome particolare, e qualsiasi nome è accettato.
Esempio
apiVersion: core.navique.com/v1alpha1
kind: ManagementPlane
metadata:
name: management-plane
namespace: navique-system
spec:
ingress:
enabled: true
host: console.forge.example.com
className: nginx # classic Ingress; use api: Gateway for an HTTPRoute
tls: true
clusterIssuer: letsencrypt-prod
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { memory: 256Mi }
discovery:
# External / cross-cluster instances merged with CR auto-discovery.
litellmEndpoints: [ "https://litellm.other-cluster.example.com" ]
auth:
oidc:
enabled: true
issuerURL: https://login.microsoftonline.com/<tenant>/v2.0
clientID: <app-id>
clientSecretRef: { name: mp-oidc, key: client-secret }
localAdmin:
enabled: true
username: admin
# credentialsSecretRef omitted → the operator auto-generates the
# username + a random password into navique-management-plane-console.Ottimizzazione della cache
La console mette in cache l'elenco delle risorse e le istanze individuate, così la dashboard è istantanea. Questi valori sono regolabili tramite l'ambiente del deployment (ciascuno è una duration Go; sono mostrati i valori predefiniti):
| Variabile d'ambiente | Predefinito | Controlla |
|---|---|---|
RESOURCE_RESYNC_INTERVAL | 10s | Risincronizzazione in background della cache dell'elenco delle risorse |
INSTANCES_CACHE_TTL | 15s | TTL per la discovery delle istanze + le sonde di raggiungibilità |
LICENSE_REFRESH_INTERVAL | 60s | Frequenza con cui la License viene riletta e verificata |
Stato
Disponibilità del Deployment, l'URL risolto della console, il localAdminSecret che contiene le credenziali dell'admin locale (quando l'admin locale è abilitato), e i consueti conditions e observedGeneration. Una risorsa non attiva (vedi Singleton di cluster e rilocazione) riporta phase: Superseded.