Skip to main content
Fracta supports multiple LLM runtimes: Claude, Codex, and OpenCode. This guide covers how to configure each runtime in fracta.yaml, how auth is wired for local and K8s deployments, and how to set up K8s manifests for non-Claude runtimes. For adding a new runtime from scratch, see host-onboarding.md. For deployment mode architecture, see deployment-modes.md.

Runtime Capabilities


fracta.yaml Configuration

Basic: Local Development

Older configs with a top-level runtimes: map still load for compatibility, but new configs should use agents.agent_runtimes.

Key Fields

Spawning with a Specific Runtime

The --host-type flag is deprecated but still accepted.

Authentication

Auth configuration lives in the auth.credentials.profiles section. Each runtime references a profile by name via auth_profile. The credential system is runtime-agnostic — the same profile structure works for all runtimes. What differs is the binding type and the env vars each runtime expects. For the canonical reference on binding types, credential source types, profile layout, and which names are schema keywords versus local labels versus external env/Secret names, see credential-pipeline.md.

Claude (Bedrock)

Claude Code authenticates via Bedrock. The credential pipeline:
  1. A runtime auth resolver (command) runs inside the agent to get a bearer token
  2. The token is injected via a claude_api_key_helper binding into Claude’s settings.json
  3. Required env vars: CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_SKIP_BEDROCK_AUTH, AWS_REGION
  4. Forbidden: CLAUDE_CODE_SIMPLE (disables settings.json loading entirely)

Codex (OpenAI API Key)

Codex authenticates via OPENAI_API_KEY. Two approaches: Local — env var injection:
K8s — Secret-backed env:
The secret_ref creates a K8s envFrom mount in the agent pod. No command resolver needed — the key is static.

OpenCode (Bedrock Bearer Token)

OpenCode uses Anthropic models via Bedrock. It reads AWS_BEARER_TOKEN_BEDROCK directly (no settings.json indirection like Claude). Local-process — credential pipeline with command_output:
K8s — pre-seeded token from secret:
Both paths materialize the bearer token before spawn and inject it into AWS_BEARER_TOKEN_BEDROCK. Model ID note: For Bedrock in ap-southeast-2, OpenCode model IDs must use the au. prefix (e.g. amazon-bedrock/au.anthropic.claude-sonnet-4-6). OpenCode auto-generates apac. for this region which is invalid. Important limitation: OpenCode does not have a Claude-style runtime helper projection. A runtime-only source such as http_header_token with scope: agent_runtime does not populate AWS_BEARER_TOKEN_BEDROCK by itself today. OpenCode currently needs a concrete token value at spawn time. Key difference from Claude auth: Claude uses claude_api_key_helper binding and can re-run the helper on TTL. OpenCode uses bearer_env binding and gets a point-in-time token value in AWS_BEARER_TOKEN_BEDROCK.

OpenCode (OpenAI Key — Alternative)

OpenCode also supports OpenAI models. Same pattern as Codex:

K8s Deployment

Batch Mode (Jobs)

All three runtimes work as K8s Jobs out of the box. The controlplane config needs the runtime entries in the ConfigMap:
Each runtime’s WriteWorkspace automatically creates the correct config files in the agent workspace:
  • Claude: .claude/settings.json (MCP + permissions)
  • Codex: .codex/config.toml (MCP gateway endpoint)
  • OpenCode: opencode.json (MCP + permissions + task:deny)

Stream Mode (Long-lived Pods)

Stream mode uses persistent Pods instead of Jobs. The orchestrator automatically:
  1. Launches a Pod running the runtime’s serve command
  2. Waits for readiness (TCP probe for Codex, HTTP probe for OpenCode)
  3. Connects the StreamSession over the network
Codex stream pod:
  • Command: codex app-server --listen ws://0.0.0.0:8080
  • Transport: WebSocket (JSON-RPC)
  • Auth: Capability token generated per-session, injected as env var
  • Readiness: TCP socket probe on port 8080
  • No liveness HTTP endpoint (app-server has none)
OpenCode stream pod:
  • Command: opencode serve --port 4096 --hostname 0.0.0.0
  • Transport: HTTP REST + SSE
  • Auth: Password generated per-session, basic auth on all HTTP calls
  • Readiness: GET /global/health:4096 returns 200
  • Env: OPENCODE_SERVER_PASSWORD, OPENCODE_DB (emptyDir path), OPENCODE_CONFIG_CONTENT (config as env)
Example K8s pod spec for OpenCode serve (for reference — the orchestrator builds this automatically):

Per-Runtime Container Images

If runtimes need different base images (common when OpenCode/Codex aren’t in the shared agent image):

OpenCode Safety: Subagent Monitoring

OpenCode has no equivalent to Claude’s CLAUDE_CODE_MAX_TURNS. To prevent runaway subagent spawning:
  1. task:deny permission — Written by WriteWorkspace into opencode.json. Blocks the task tool (subagent spawning) by default.
  2. Step count monitoring — The ServeSession counts step_start SSE events during each Send() call. Warnings are logged at milestones (5, 10, 15, 20). If the count exceeds the threshold (default: 20), the session is aborted via POST /session/:id/abort.
The step limit is hardcoded at 20 for now. It can be made config-driven via RuntimeEntry in a future iteration.

Auth Decision Tree


Complete Example: Three Runtimes in One Config

Then spawn agents with any runtime: