LLM backends: API key vs subscription CLI
LLM configuration is data, persisted in MongoDB and editable from the Admin UI — not baked into env. Two scopes:
- Per agent — each agent document carries its own backend/provider/model (Agents → edit → Model & backend).
- System-wide — the planner, summarizer, and embeddings read from the
settingsdocument (Admin UI → Settings → LLM defaults), with adefaultendpoint plus optional per-role overrides. TheNEXUS_PLANNER_*/NEXUS_EMBED_MODELenv vars are only seed fallbacks used until the settings document is saved once.
You can mix backends freely. Two families exist:
| Backend | Auth | Use when |
|---|---|---|
openai-api, anthropic-api | API key (per-token billing) | you have provider API keys |
claude-code-cli, codex-cli | a subscription login persisted on a volume | you pay a monthly Claude/Codex plan and want to use it instead of API billing |
Both are first-class and always available; pick per agent.
How CLI (subscription) backends work
The claude and codex CLIs are baked into the agent base image. They are not
logged in at build time — credentials are supplied at runtime from a small
PersistentVolumeClaim that you populate once with an interactive login:
CLAUDE_CONFIG_DIR=/creds/claudeCODEX_HOME=/creds/codex
The creds PVC is mounted (read-write) into every agent run pod, so each run reuses the same subscription login. No API key is needed for CLI agents.
One-time login (agent runs)
A long-lived nexus-agent-login pod mounts the same creds volume. Log in
through it:
# Open an interactive shell in the login pod
kubectl -n nexus-agents exec -it deploy/nexus-agent-login -- bash
# Claude Code (subscription / Max plan): launch it and run the /login command
claude
# › /login → pick "Subscription", approve in your browser
# OpenAI Codex
codex login
Both print a URL + device code; open it in your browser and approve. Codex's OAuth uses a localhost callback — if it doesn't complete inside the pod, port-forward it during login:
kubectl -n nexus-agents port-forward deploy/nexus-agent-login 1455:1455
Credentials land on the PVC (/creds) and persist across pod restarts and image
upgrades. To re-auth, just run the login command again.
Enable/disable and size the volume via Helm values:
agentCreds:
enabled: true # set false to run purely on API keys
pvcName: nexus-agent-creds
storageClass: microk8s-hostpath
size: 1Gi
The planner / summarizer
The control-plane worker also makes a few LLM calls (goal → task decomposition,
HISTORY compaction). Configure these in Settings → LLM defaults (the
default endpoint, or the Planner / Summarizer overrides). The
worker.plannerBackend Helm value is just the seed fallback before anything is
saved:
worker:
plannerBackend: openai-api # seed only; Admin UI Settings takes over once saved
- For an API backend, the worker uses
OPENAI_API_KEY/ANTHROPIC_API_KEYfrom its secret. - For a CLI backend, the worker image includes the CLIs (
WITH_CLI=1) and needs its own creds volume — PVCs are namespace-scoped, so this is separate from the agent creds. Enable it and log in once:
plannerCreds:
enabled: true
pvcName: nexus-planner-creds
storageClass: microk8s-hostpath
size: 1Gi
kubectl -n nexus exec -it deploy/nexus-planner-login -- bash
# then: `claude` → /login, and/or `codex login`
If neither an API key nor a CLI backend is available, the planner and compaction loops simply idle (the rest of the system keeps running).
Running fully on subscriptions (no API key)
- Set agents' backend to
claude-code-cliorcodex-cliin the Admin UI. agentCreds.enabled: true, then log in vianexus-agent-login.- In Settings → LLM defaults, set the default (or Planner/Summarizer
overrides) to a CLI backend,
plannerCreds.enabled: true, then log in vianexus-planner-login.
Related
- Security & permissions — runner pod hardening, secret injection
- Agent run flow