Skip to main content
Agents on a Hybrid install never use xpander’s keys. Keys live in the organization (Platform > AI governance > Models) or on the install (secrets.static). This page covers the install side.

Managing LLM API keys

Use helm 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:
After the upgrade, pods that use the updated secrets will automatically restart. Verify with 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

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.
Fable- and Mythos-class Anthropic models on Bedrock need the AWS account’s data-retention opt-in, per region. With the default mode Bedrock answers 400 data retention mode 'default' is not available for this model. There is no console switch: PUT https://bedrock.<region>.amazonaws.com/data-retention with {"mode": "provider_data_share"} (or aws_review where offered), SigV4-signed with bedrock:PutAccountDataRetention, in every region a global. inference profile can route to, on whichever account signs the call (the controller’s, or the organization’s own Bedrock key account). Details on AI vendors.

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.
  • names starting with AWS_ (except AWS_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_ or KUBE
  • names ending with _SERVICE_API_KEY, _PASSWORD, _PRIVATE_KEY, _SECRET, _SECRET_KEY, _SESSION_TOKEN or _TOKEN_FILE
  • the platform’s own service keys (DEPLOYMENT_MANAGER_API_KEY, AGENT_CONTROLLER_API_KEY and the like)
Model endpoints on metadata addresses are refused. This applies to a model endpoint set on an agent, a custom provider, the organization’s default model or an Azure key. xpander refuses it when it resolves to a metadata or link-local address (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.