Model access on self-hosted runners
Let the coding agent on your self-hosted runner use your own cloud account for models, such as Amazon Bedrock, Google Vertex AI or Microsoft Foundry, so model keys never pass through kanman.
On a self-hosted runner the coding agent can use the model access you configure on the runner itself. kanman then hands the run no model credentials at all: no key of its own and no key stored in kanman. Whatever the runner’s environment provides is what the coding agent uses.
We recommend your own cloud account for this: Amazon Bedrock, Google Vertex AI or Microsoft Foundry for Claude Code, and Azure OpenAI for Codex. The credentials stay in your infrastructure, model calls run under your cloud contract and in the region you choose, and you can use the identity mechanisms you already have (IAM roles, workload identity, managed identity).
Operators are responsible for complying with their model provider’s terms when they configure the runner environment.
Turn it on for a team
The setting exists only for workspaces whose runs execute on their own runners (Workspace settings > Runs and runners, Our runners or Everything on ours under Where runs execute).
- Open the team’s Settings > Agent and models.
- Under Model access of the coding agent, choose Model access from the runner environment. In the team setup the same choice is in the executor step.
- Set the budgets in minutes and runs (see below) under Spend in the team’s Settings > Limits and budgets. Each change saves at once.
kanman cannot see model cost in this mode. Instead of euros, the team’s budgets count time and runs:
| Setting | Meaning |
|---|---|
| Minutes per run | Maximum time of one attempt, 1 to 1440 minutes (default 60). When it is reached, kanman stops the run; no pull request is created. |
| Runs per day | How many runs the team may start per day. Empty means no limit. |
| Runs per month | How many runs the team may start per month. Empty means no limit. |
Expedite and incident work still starts when a run limit is reached. The evidence pack of these runs says that model cost is not tracked. On kanman Cloud this setting is refused: runs there never use a runner’s environment.
The run page shows the time a run has used against Minutes per run instead of a cost in euros. The same goes for the run cards in the conversation, the runs list and the weekly report: they say “Cost not tracked (runner environment)” and show minutes, never “€0.00 of €2.00”.
Model access per team
A runner can serve several teams with different accounts. Once Model access from the runner environment is chosen, the same card shows This team’s model access on your runners. Leave it empty and the team uses what the runner provides. Add variables there to give the team its own access, for example:
| Access | Variables |
|---|---|
| A person’s Claude subscription login | CLAUDE_CODE_OAUTH_TOKEN (create it with claude setup-token) |
| Anthropic API | ANTHROPIC_API_KEY |
| Amazon Bedrock with an API key | CLAUDE_CODE_USE_BEDROCK = 1, AWS_REGION, AWS_BEARER_TOKEN_BEDROCK |
| Google Vertex AI | CLAUDE_CODE_USE_VERTEX = 1, CLOUD_ML_REGION, ANTHROPIC_VERTEX_PROJECT_ID (credentials from the runner’s workload identity) |
| Microsoft Foundry | CLAUDE_CODE_USE_FOUNDRY = 1, ANTHROPIC_FOUNDRY_BASE_URL, ANTHROPIC_FOUNDRY_API_KEY |
| Codex | OPENAI_API_KEY, or AZURE_OPENAI_API_KEY, AZURE_OPENAI_BASE_URL, AZURE_OPENAI_DEPLOYMENT |
| A different model for kanman’s own steps | the KANMAN_ASSISTANT_ variables below |
The team’s model access replaces the runner’s as a whole for that team: none of the runner’s model variables are used, so a person’s subscription never runs next to the runner’s key. kanman keeps the values encrypted and hands them to the runner with each run and step of the team only; the runner never stores them, and the coding agent reaches the model through the runner’s credential proxy with a placeholder instead of the value. Owners and admins change them; everyone sees the names, who set them and when. Each change is recorded in the audit log without the value. Code host tokens and other variables of the team are set under On your runners; see Several teams on one runner.
A person’s own subscription is meant for trying kanman as their own tool. The person who sets it is responsible for using it within the provider’s terms.
Review and acceptance specs
Two steps of the outcome gate also use a model: the independent reviewer and the writing of a story’s acceptance spec. In this mode kanman has no model access it could use for them from its cloud, and it never falls back to its own. Turn on Run everything on your runners to run them on your runner with this same model access. Without it, a story that needs an acceptance spec stays in Refining with the note Waiting for your runner, and a run whose changes are ready for review is parked with the same explanation on its run page. Nothing fails and no attempts are used up while it waits.
One configuration for every step
With Everything on ours, every step that uses a model runs on your runner with the access you configure there: the coding agent, drafting stories from a requirement, the independent reviewer, acceptance specs, kanman’s replies in the conversation, answers from team context and the maintenance reviewers. With Amazon Bedrock, Google Vertex AI, Microsoft Foundry or an Anthropic key, all of these steps use the same Claude client as the coding agent. Amazon Bedrock through the runner’s IAM role, for example, covers drafting and review as well; no extra key is needed for them. The model pins below (ANTHROPIC_DEFAULT_SONNET_MODEL and so on) apply to these steps too.
A runner with only Azure OpenAI or an OpenAI key answers these steps with that provider. To use a different model for these steps, see Different models for coding and for the other steps.
For each of these steps the runner reports the tokens and the estimated model cost to kanman. In this mode they are recorded with the step’s entry in the audit log and do not count against the team’s budgets, which count minutes and runs.
What the runner passes on
In this mode the coding agent and kanman’s other model steps see the runner’s environment, except kanman’s own tokens. Set the variables of your provider on the runner container. When the runner starts, its log names the providers it found (for example bedrock), never their values.
Commands from your repository are different: acceptance checks and the local verify command never see the runner’s environment, only a minimal one plus the secrets and CI variables you name for them. See Runner secrets.
The variables below are the ones Claude Code and Codex read. To pin model versions on Bedrock, Vertex AI or Foundry, set ANTHROPIC_DEFAULT_SONNET_MODEL, ANTHROPIC_DEFAULT_OPUS_MODEL and ANTHROPIC_DEFAULT_HAIKU_MODEL to the model IDs enabled in your account; kanman’s model choice per story then resolves to them.
Amazon Bedrock
| Variable | Value |
|---|---|
CLAUDE_CODE_USE_BEDROCK |
1 |
AWS_REGION |
Region with Bedrock model access, for example eu-central-1 |
| Credentials | An IAM role (instance profile, ECS task role, EKS pod identity), or AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and optionally AWS_SESSION_TOKEN, or a Bedrock API key in AWS_BEARER_TOKEN_BEDROCK |
Google Vertex AI
| Variable | Value |
|---|---|
CLAUDE_CODE_USE_VERTEX |
1 |
CLOUD_ML_REGION |
Region with Claude models enabled, for example europe-west1 |
ANTHROPIC_VERTEX_PROJECT_ID |
Your Google Cloud project ID |
GOOGLE_APPLICATION_CREDENTIALS |
Path to a mounted service account key file. Not needed with workload identity on GKE. |
Microsoft Foundry
| Variable | Value |
|---|---|
CLAUDE_CODE_USE_FOUNDRY |
1 |
ANTHROPIC_FOUNDRY_RESOURCE |
Name of your Foundry resource, or instead ANTHROPIC_FOUNDRY_BASE_URL with the full address |
| Credentials | ANTHROPIC_FOUNDRY_API_KEY, or Azure credentials such as a managed identity |
Codex with Azure OpenAI
| Variable | Value |
|---|---|
AZURE_OPENAI_API_KEY |
Key of your Azure OpenAI resource |
AZURE_OPENAI_BASE_URL |
https://<resource>.openai.azure.com/openai/v1 |
AZURE_OPENAI_DEPLOYMENT |
Name of your model deployment |
AI gateways in the runner environment
If your company routes model traffic through an AI gateway that is reachable only inside your network, point the runner at it with the variables the coding agents read. This works for the coding agent and, unless you configure a separate assistant model (next section), for kanman’s own steps too.
OpenAI-compatible gateway (kanman’s own steps, and Codex when the gateway offers the OpenAI Responses API):
| Variable | Value |
|---|---|
OPENAI_BASE_URL |
The gateway’s OpenAI-compatible base URL, for example https://ai-gateway.corp.example/v1 |
OPENAI_API_KEY |
The gateway’s key |
AI_GATEWAY_AUTH_HEADER |
Optional. The header that carries the key, for example api-key. Default: Authorization: Bearer |
AI_GATEWAY_HEADERS |
Optional. Extra headers as a JSON object, for example {"x-tenant-id":"acme"} |
AI_GATEWAY_MODEL |
The model name for drafting and conversation, as the gateway names it, for example openai/gpt-5 |
AI_GATEWAY_REVIEW_MODEL |
Optional. The model for the reviewer and acceptance specs (default: AI_GATEWAY_MODEL) |
AI_GATEWAY_CODING_MODEL |
Optional. The model for Codex (default: AI_GATEWAY_MODEL) |
AI_GATEWAY_REASONING_EFFORT |
Optional. How much a reasoning model thinks before it drafts or replies: low (default), medium or high; an empty value leaves the setting out |
Anthropic-compatible gateway (Claude Code, and kanman’s own steps through the same client):
| Variable | Value |
|---|---|
ANTHROPIC_BASE_URL |
The gateway’s Anthropic-compatible address, for example https://ai-gateway.corp.example/anthropic |
ANTHROPIC_AUTH_TOKEN |
The gateway’s key, sent as Authorization: Bearer. Or ANTHROPIC_API_KEY if your gateway expects x-api-key. |
ANTHROPIC_MODEL |
The model name as the gateway names it |
ANTHROPIC_CUSTOM_HEADERS |
Optional. Extra headers, one Name: value per line |
Claude Code needs the Anthropic-compatible endpoint, Codex needs the gateway’s OpenAI Responses API (/responses); current Codex versions do not support Chat Completions. A gateway with only Chat Completions can serve kanman’s own steps, but no coding agent. See Which coding agent works with which gateway.
A team that stores its gateway key in kanman (Use a gateway or proxy instead under Workspace settings > Model access) does not need these variables: the runner receives the key, the headers and the model names for each run and each step of that team, and never stores them.
Example: Codex and kanman’s own steps through an internal gateway that expects the key in an api-key header:
docker run -d --name kanman-runner --restart unless-stopped \
-e KANMAN_API_KEY=km_your_runner_token \
-e RUNNER_EXECUTORS=codex \
-e OPENAI_BASE_URL=https://ai-gateway.corp.example/v1 \
-e OPENAI_API_KEY=your_gateway_key \
-e AI_GATEWAY_AUTH_HEADER=api-key \
-e 'AI_GATEWAY_HEADERS={"x-tenant-id":"acme"}' \
-e AI_GATEWAY_MODEL=openai/gpt-5 \
ghcr.io/kanman-ai/executor-host
Different models for coding and for the other steps
You can give kanman’s own steps (drafting stories, the reviewer, acceptance specs, replies in the conversation, answers from team context, the maintenance reviewers) a different model than the coding agent, for example your company’s AI gateway, while the coding agent keeps using Claude. Everything is configured on the runner:
| Variable | Meaning |
|---|---|
KANMAN_ASSISTANT_BASE_URL |
Base address of the gateway, for example https://aigateway.eu/core/v1 |
KANMAN_ASSISTANT_API_KEY |
The gateway’s key. Leave it out if your gateway needs none. |
KANMAN_ASSISTANT_AUTH_HEADER |
Optional. The header that carries the key. Default Authorization: Bearer; for example api-key or x-api-key sends the key as it is. |
KANMAN_ASSISTANT_MODEL |
The model name the gateway expects, for example mistral/mistral-large-2411 |
KANMAN_ASSISTANT_MODEL_DRAFTING, _REVIEW, _SPEC, _CONVERSATION |
Optional. Another model for drafting, for the reviewer and maintenance reviews, for acceptance specs, or for conversation replies and answers |
KANMAN_ASSISTANT_FORMAT |
Optional. openai (default) for gateways with an OpenAI-compatible chat completions endpoint, anthropic for gateways with an Anthropic Messages endpoint (/v1/messages) |
KANMAN_ASSISTANT_REASONING_EFFORT |
Optional, openai format only. How much a reasoning model (for example GPT-5) thinks before it drafts stories or replies in the conversation: low (default), medium or high. Set it to an empty value if your gateway or model does not accept the setting. |
KANMAN_ASSISTANT_MAX_OUTPUT_TOKENS |
Optional, openai format only. The most output tokens, thinking included, that a step may use on its first try. Default 32000. |
Reasoning models spend part of their output on thinking before they answer. kanman leaves room for that, and if an answer still stops at the limit, it asks once more with twice the room. If that answer is cut off too, kanman tells you the model ran out of output tokens, instead of showing a broken draft. Then send the request in smaller parts, or raise KANMAN_ASSISTANT_MAX_OUTPUT_TOKENS. If your gateway rejects the reasoning setting, kanman repeats the call once without it on its own; setting KANMAN_ASSISTANT_REASONING_EFFORT to an empty value avoids that extra call.
Which model access a step uses:
- The team’s own key, if the team uses one in kanman.
- Otherwise the assistant model above: the team’s own (
KANMAN_ASSISTANT_variables in the team’s model access), else the runner’s, unless the team brings its own model access. - Otherwise the coding agent’s model access: the team’s own on your runners, else the runner’s.
The coding agent never sees the KANMAN_ASSISTANT_ variables. When the runner starts, its log names the configured gateway host, format and models, never the key. Each step’s entry in the audit log says which of the three sources answered it, with its tokens.
Example: Claude on Amazon Bedrock for coding, and the company gateway for everything else:
services:
kanman-runner:
image: ghcr.io/kanman-ai/executor-host
restart: unless-stopped
environment:
KANMAN_API_KEY: ${KANMAN_API_KEY}
RUNNER_EXECUTORS: claude-code
CLAUDE_CODE_USE_BEDROCK: "1"
AWS_REGION: eu-central-1
KANMAN_ASSISTANT_BASE_URL: https://aigateway.eu/core/v1
KANMAN_ASSISTANT_API_KEY: ${GATEWAY_KEY}
KANMAN_ASSISTANT_MODEL: mistral/mistral-large-2411
KANMAN_ASSISTANT_MODEL_REVIEW: openai/gpt-5
Steps that run on a gateway report tokens but no cost, because kanman does not know the gateway’s prices.
Docker Compose example
A runner that offers Claude Code on Amazon Bedrock with the host’s IAM role:
services:
kanman-runner:
image: ghcr.io/kanman-ai/executor-host
restart: unless-stopped
environment:
KANMAN_API_KEY: ${KANMAN_API_KEY}
RUNNER_NAME: runner-fra-1
RUNNER_EXECUTORS: claude-code
CLAUDE_CODE_USE_BEDROCK: "1"
AWS_REGION: eu-central-1
ANTHROPIC_DEFAULT_SONNET_MODEL: eu.anthropic.claude-sonnet-4-5-20250929-v1:0
The same runner on Google Vertex AI with a mounted service account key:
services:
kanman-runner:
image: ghcr.io/kanman-ai/executor-host
restart: unless-stopped
environment:
KANMAN_API_KEY: ${KANMAN_API_KEY}
RUNNER_EXECUTORS: claude-code
CLAUDE_CODE_USE_VERTEX: "1"
CLOUD_ML_REGION: europe-west1
ANTHROPIC_VERTEX_PROJECT_ID: acme-ai-prod
GOOGLE_APPLICATION_CREDENTIALS: /secrets/gcp-key.json
volumes:
- ./gcp-key.json:/secrets/gcp-key.json:ro
Kubernetes example
A runner on Microsoft Foundry for Claude Code and Azure OpenAI for Codex. Keys live in a Kubernetes Secret:
apiVersion: v1
kind: Secret
metadata:
name: kanman-runner
type: Opaque
stringData:
KANMAN_API_KEY: km_your_runner_token
ANTHROPIC_FOUNDRY_API_KEY: your_foundry_key
AZURE_OPENAI_API_KEY: your_azure_openai_key
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kanman-runner
spec:
replicas: 1
selector:
matchLabels:
app: kanman-runner
template:
metadata:
labels:
app: kanman-runner
spec:
containers:
- name: runner
image: ghcr.io/kanman-ai/executor-host
envFrom:
- secretRef:
name: kanman-runner
env:
- name: RUNNER_EXECUTORS
value: claude-code,codex
- name: CLAUDE_CODE_USE_FOUNDRY
value: "1"
- name: ANTHROPIC_FOUNDRY_RESOURCE
value: acme-foundry
- name: AZURE_OPENAI_BASE_URL
value: https://acme-openai.openai.azure.com/openai/v1
- name: AZURE_OPENAI_DEPLOYMENT
value: gpt-5
With workload identity (Vertex AI on GKE) or a managed identity (Foundry on AKS), leave the key out of the Secret and attach the identity to the pod’s service account instead.
Related pages
Last updated: January 1, 0001
Open kanman