Skip to content

ManagementPlane ​

Scope: namespaced · Optional (the console is deployed by default)

The Navique AI Core Management Plane is the admin console for the whole platform — a single web UI to see everything the operator manages, activate a license, and (when licensed) export how users used the AI gateway. The operator deploys it by default, even when no ManagementPlane resource exists; this resource only overrides defaults (host, ingress, SSO, image, discovery).

What the management plane is ​

It is a proprietary admin console — the closed-source counterpart to the open-source operator. Where the operator runs the platform, the management plane gives a human a single pane of glass over it:

  • See every operator-managed resource and its live status in one place, instead of running kubectl against a dozen custom resources across namespaces.
  • See and activate the platform license from a browser.
  • For regulated buyers, export a user's gateway usage / conversation history over a time window as JSON or CSV (a licensed feature).

It is shipped only as a prebuilt container image and is admin-only in v1. Because it is proprietary, it deliberately does not link the operator's AGPL code — it reads the operator's resources through the Kubernetes API like any other client. (A build-time check fails if any operator package is linked.)

Why it is useful ​

CapabilityAvailability
View operator-managed resources + live status across namespacesFree baseline (any / no license)
Discover the running LiteLLM / Langfuse instances and their reachabilityFree baseline
View & activate a license (creates/updates the License resource)Free baseline — the only write action
Export a user's gateway usage / conversation history (audit, JSON/CSV)Licensed: management-plane-audit-export

License-gated features fail closed without the entitlement; the free baseline is always available, even with no license at all.

How it works ​

The console is an API-aggregation BFF (backend-for-frontend), not an observability pipeline or a database. A Go backend serves a Nuxt + Vue single-page app (embedded in the binary, so there is no Node at runtime — good for air-gapped installs) and a JSON API. It reads from three sources and stores no platform data of its own:

text
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)
  • Kubernetes API (via the dynamic client + the console's ServiceAccount) — the operator's resources and their .status, plus reading and writing the License.
  • LiteLLM API — usage, spend, and per-end-user activity (the primary audit source).
  • Langfuse API — conversation traces (supplementary audit content).

Credentials for LiteLLM/Langfuse are read from Kubernetes Secrets via the console's ServiceAccount and never reach the browser. The backend caches the resource list and discovered instances so the dashboard is instant (see Cache tuning).

Login & access ​

Two login methods, both built in:

  • Local admin — a bootstrap administrator, for SSO-less or air-gapped clusters. Enable it under auth.localAdmin. If you do not supply a credentialsSecretRef, the operator auto-generates the credentials for you: it creates an owned navique-management-plane-console Secret containing the username (from localAdmin.username, default admin) and a random password, and records the Secret name in status.localAdminSecret. Read the generated password with:

    bash
    kubectl get secret navique-management-plane-console -n navique-system \
      -o jsonpath='{.data.password}' | base64 -d

    Supply a credentialsSecretRef (a Secret with username and password keys) only when you want to manage the credentials yourself.

  • Microsoft Entra OIDC — configure the issuer, client ID, and client secret; the SSO button then appears automatically.

Configure either through this resource's auth block. The operator also generates a stable SESSION_KEY into the same owned console Secret, so logins survive console restarts and scale-out.

Activating a license from the console ​

License activation is the one write the console performs. From the License page an admin pastes or uploads a signed license token; the backend verifies the signature and previews the decoded entitlements (features + instance limits) before anything changes; on confirm it creates or updates the License resource and its backing Secret. The operator then picks up the new entitlements on its next reconcile.

This is the same signed token used everywhere — the console embeds the same Ed25519 public key as the operator, so a token is interpreted identically on both sides. See Managing a License for the CLI path and Editions & Licensing for what the features and limits mean.

Audit & usage export (licensed) ​

The first licensed feature (management-plane-audit-export) lets an admin export how an end-user used the gateway over a time window. It is aimed at the regulated organizations that need to answer "what did this user send through the AI platform, and when?"

  • End-user identity is the user's email (x-litellm-end-user-id), carried LibreChat → LiteLLM → Langfuse.
  • LiteLLM is the primary source (timestamps, model, tokens, spend, status, and request content where stored); Langfuse supplements it with richer conversation content where available. If Langfuse is absent, the export still works from LiteLLM alone and notes it.
  • Output is normalized JSON or CSV, streamed (not buffered), with a meta block recording who ran it, the target user, the window, the instance, and the sources used.
  • Exports are themselves audited. Every export writes a meta-audit record (operator identity, target user, window, format, row count, sources) to the app log and a durable in-cluster sink — answering "who exported whose data, when".

Conversation content is sensitive: the feature is admin-only, content is never logged in plaintext, and the export is meta-audited. The console respects the upstream tools' own retention — it reads what LiteLLM/Langfuse still hold and stores nothing itself.

Security & boundaries ​

  • Least-privilege RBAC. The operator provisions the console a ServiceAccount whose only write is license activation; everything else is read-only (see What the controller reconciles).
  • AGPL-safe. The proprietary console reads the operator's resources via the Kubernetes dynamic client and does not import the operator's AGPL packages, so the open-core boundary holds. The operator merely references and deploys the image.
  • Not a replacement for Langfuse. Langfuse remains the LLM-tracing tool; the console is the cross-component admin surface that links to and pulls from it.
  • v1 non-goals: multi-tenant RBAC, write-back management of instances/models/ teams, and a built-in observability store — possible later, out of scope today.

Spec ​

FieldTypeDescription
imagestringOverride image/tag (default: operator-pinned)
ingressobjectPublic route for the console — host, TLS (cert-manager), className, and api (Ingress / Gateway). See Routing
authobjectOIDC (Entra) and/or a bootstrap local admin
discoveryobjectExplicit endpoint overrides, merged with CR auto-discovery. See Discovery
resourcesobjectCPU/memory requests & limits applied to the console container
replicasintConsole replica count (default 1)

Routing ​

The console is operator-built (not a Helm chart), so the operator emits its public route itself. Both routing APIs are supported and selected per the cluster-wide PlatformConfig.spec.routing default, overridable per-console with ingress.api:

  • Classic Ingress (api: Ingress, or the default when no mesh is active) — the operator creates a networking.k8s.io/v1 Ingress (named after the CR) routing host → the console Service. className, cert-manager TLS (tls + clusterIssuer), nginx basicAuthSecret, and custom annotations are honored.
  • Gateway API (api: Gateway, or the default when a mesh is active) — the operator emits an HTTPRoute attached to the shared managed Gateway. Requires the Gateway API CRDs; until they are present the console reports a Waiting condition.

Discovery ​

By default the console auto-discovers the running LiteLLM/Langfuse instances from their Gateway/Observability CRs. discovery.litellmEndpoints / discovery.langfuseEndpoints add explicit endpoint URLs that are merged with that auto-discovery — useful for external or cross-cluster instances that are not operator CRs. These manual endpoints appear on the dashboard and are reachability-probed; because they have no associated credential Secret, the credentialed features (usage/audit export) remain available only for CR-discovered instances.

auth ​

FieldDescription
oidcEntra: issuerURL, clientID, clientSecretRef
localAdminBootstrap admin for SSO-less / air-gapped setups

auth.localAdmin ​

FieldDescription
enabledTurn on the local-admin login
usernameLogin username (default admin)
credentialsSecretRefOptional. A Secret with username and password keys. Omit to have the operator auto-generate the credentials into the owned navique-management-plane-console Secret

What the controller reconciles ​

  1. A Deployment + Service + optional Ingress for the management-plane image — one console per cluster (see Cluster singleton & relocation). With no ManagementPlane resource it lives in the system namespace (e.g. navique-system); with a resource it lives in that resource's namespace.
  2. A ServiceAccount with least-privilege RBAC:
    • cluster get/list/watch on all *.core.navique.com resources and /status;
    • get on the LiteLLM/Langfuse credential Secrets;
    • create/update/get on licenses.core.navique.com and the license Secret (the console's only write — license activation);
    • create/patch on events (a meta-audit sink).
  3. Config from the ManagementPlane resource if present; otherwise sensible defaults.

Cluster singleton & relocation ​

The console holds cluster-wide RBAC, so running more than one is never useful. The operator enforces exactly one console per cluster:

  • Default (no resource): the console runs in the system namespace (navique-system).
  • Relocation: apply a ManagementPlane in another namespace and the operator moves the single console there — it creates the console in your namespace and deletes the default in navique-system. There is never a second console. Delete the resource and the console returns to navique-system.
  • More than one resource: the oldest ManagementPlane wins and governs the console; every younger resource reports status.phase: Superseded (Ready=False, reason Superseded) and deploys nothing. Delete the active one and the next-oldest is promoted automatically.

This is purely a controller behavior — there is no admission policy forcing a particular name, and any name is accepted.

Example ​

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

Cache tuning ​

The console caches the resource list and discovered instances so the dashboard is instant. These are tunable via the deployment's environment (each is a Go duration; defaults shown):

Env varDefaultControls
RESOURCE_RESYNC_INTERVAL10sBackground resync of the resource list cache
INSTANCES_CACHE_TTL15sTTL for instance discovery + reachability probes
LICENSE_REFRESH_INTERVAL60sHow often the License is re-read and verified

Status ​

Deployment availability, the resolved console URL, the localAdminSecret holding the local-admin credentials (when local admin is enabled), and the standard conditions and observedGeneration. A non-active resource (see Cluster singleton & relocation) reports phase: Superseded.

Open core under AGPL-3.0. Enterprise components are proprietary and license-gated.