secrets.static). This page covers the install side.
Managing LLM API keys
Usehelm upgrade with --reset-then-reuse-values (Helm 3.14 or later) to add or change API keys: it keeps the values you set and applies the chart’s defaults for everything else:
kubectl get pods -n xpander.
The xpander-static secret has a Helm resource keep policy, so helm upgrade may not update it on subsequent installs. If a key isn’t picked up, patch the secret directly: see API key not being picked up after helm upgrade.
Secret field names
Helm value to secret field mapping
Helm value to secret field mapping
Using Kubernetes Secrets (recommended for production)
Your own keys and credits
Keys can also live in the product: per provider under Platform > AI governance > Models, or as an agent-level credential (checked first). A call on a key you brought is never charged credits, but xpander still measures it, so budgets and usage stay accurate. Claude Code, Codex and OpenCode turns follow the same rule.Amazon Bedrock: keyless IAM or API key
Bedrock calls take one of two paths, each with its own credentials:
Chat and agent tasks.
--bedrock-auth iam signs calls with the pods’ AWS identity (EKS Pod Identity or IRSA), in images built after 27 August 2026. The role needs the Bedrock permissions itself (bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream, bedrock:Converse, bedrock:ConverseStream on *) and must be bound to both ServiceAccounts the LLM services run as: default and agent-controller. The chat and task paths do not assume a second role.
--bedrock-auth key (default when --bedrock-key is given) stores a bearer token. Either way, the account must be opted in to Bedrock’s data retention mode for your models. The “IAM role” method under Platform > AI governance > Models covers only the Claude Code path below. If chat fails with a Bedrock entry set that way, remove it and restart the agent-controller, agent-worker, agents, actions and functions deployments.
Claude Code on Bedrock. The CLI calls the in-cluster LLM Gateway directly, and the gateway gets the Bedrock credential from the Agent Controller. The controller resolves AWS auth itself, in this order: AWS_BEARER_TOKEN_BEDROCK, then BEDROCK_ASSUME_ROLE_ARN (STS, self-refreshing), then static keys, then the pod’s default credential chain (Pod Identity / IRSA). Set whichever you use as controller environment through the chart’s env values, with BEDROCK_REGION or AWS_REGION next to it. An organization Bedrock key under Platform > AI governance > Models is preferred over the controller’s credential.
Key names read from an environment variable
An agent, a custom model provider or the organization’s default model can name its API key by an environment variable on agent-controller (agent-controller.env or global.env, for example MY_VLLM_TOKEN). Such a name never reads one of the install’s own credentials. Names that match the reserved list below read as no key.
The standard provider names (OPENAI_API_KEY, ANTHROPIC_API_KEY, AWS_BEARER_TOKEN_BEDROCK, GOOGLE_API_KEY, AZURE_OPENAI_API_KEY, OPENROUTER_API_KEY and the other provider keys) keep working, and so does any other name, such as VLLM_API_KEY. Rename a name that matches the list (for example VLLM_SECRET to VLLM_API_KEY) in both places: the agent-controller env that carries the value and the setting that names it.
Reserved names that read as no key
Reserved names that read as no key
- names starting with
AWS_(exceptAWS_BEARER_TOKEN_BEDROCK),XPANDER_,FLEET_,LLM_GW,LLM_GATEWAY,LITELLM_,GITHUB_APP,SUPABASE,REDIS,OAUTH,JWT,LICENSE,MONGO,POSTGRES,PG_,ON_PREM_PG,SMTP,REGISTRY,SANDBOX_,HARNESS_orKUBE - names ending with
_SERVICE_API_KEY,_PASSWORD,_PRIVATE_KEY,_SECRET,_SECRET_KEY,_SESSION_TOKENor_TOKEN_FILE - the platform’s own service keys (
DEPLOYMENT_MANAGER_API_KEY,AGENT_CONTROLLER_API_KEYand the like)
169.254.0.0/16, fe80::/10, the cloud metadata hosts). The check runs when the endpoint is saved and again on every call, against the address actually dialled. Private addresses (a vLLM or model gateway on your own network) keep working.
