Agents

Agent credentials

Give agents a model credential, keep it out of every place an agent could read it, and override it per project.

Agents in a sandbox need a model credential: they can't use your Mac's own Claude login. SI Fabrik stores credentials in the Keychain (or in secrets.env on a server) and keeps them out of the sandbox: a sandboxed agent holds only a placeholder, and SI Fabrik's relay adds the real credential to its model traffic. Credentials never go into hooks, $VAR resolution or files.

Which credential you need#

RunnerWhere it runsCredential
Claude CodeHost (no sandbox)None needed: your existing Claude login is used. A key in Settings is used if you set one.
Claude CodeDocker or CloudflareAn Anthropic API key (sk-ant-api…), a claude setup-token token (sk-ant-oat…), or a model gateway
CodexDocker or CloudflareAn OpenAI API key, or a model gateway

Add a credential#

  1. Create a token

    For a Claude subscription, run this in Terminal and copy the long-lived token it prints:

    Shell
    claude setup-token

    Or create an API key in the Anthropic Console.

  2. Paste it in Settings

    Open Settings → Credentials and paste it into Anthropic API key (sk-ant-…) or Claude Code OAuth token. For Codex, fill OpenAI API key. The Add Project wizard offers the same field when Docker is on and no credential is set.

You can also define ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN in Settings → Environment; Credentials then shows Using the Claude key defined in Settings → Environment.

Per-project credentials#

Set a credential name in a project's environment (Edit Project → Environment, or projects[].secrets_file on a server) to replace the global credential for that project only. The row shows credential: it's used as the project's agent credential or gateway key and never placed in hook or agent environments.

How credentials are protected#

  • Never in a Docker sandbox. The agent container gets a placeholder credential, and ANTHROPIC_BASE_URL (Claude Code) or a harness model provider (Codex) pointing at the egress proxy's model relay, port 3129 on the task's network. The relay adds the real API key, OAuth token or gateway key and forwards to the run's model endpoint: Anthropic, OpenAI or your gateway. The model hosts aren't on the sandbox's allowlist, so only the relay reaches them.
  • Held in memory only. SI Fabrik hands the credential to the proxy with docker exec, into the proxy's memory-only /run; it's never written to disk on the host, and it's removed when the run ends. If Docker restarts the proxy, SI Fabrik hands it the credentials again.
  • Never in Cloudflare. Cloudflare sandboxes see a placeholder too; SI Fabrik adds the real credential to model traffic on the host, through its relay.
  • Filtered from docker.env. ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, OPENAI_API_KEY, LITELLM_API_KEY, HARNESS_GATEWAY_API_KEY and the variable gateway.api_key names are never passed into agent, hook, terminal or linked-service containers, even if docker.env lists them.
  • Never in hooks or $VAR. Credential names are kept out of the general environment.
  • Gateway wins cleanly. With a gateway, Anthropic credentials are removed from the agent's environment so the two never conflict. A gateway key satisfies the sandbox credential check.
  • Redacted. Run history, transcripts served to clients, pull request bodies and comments are scrubbed of known secret values.
Custom Docker networks

A project with docker.network has no egress proxy, so its credential is passed into the container by name (-e NAME). That's only possible on a Mac with Allow agents to run directly on this Mac on for the project. See A custom Docker network.

When a credential is missing or rejected#

  • Missing: a sandboxed Claude Code project without any credential or gateway doesn't dispatch. The project header shows missing_agent_credentials, with where to add one. If you defined a variable that looks like a Claude key under another name, the message says so.
  • Missing gateway key: missing_gateway_key when a sandboxed project routes through a gateway that has no key.
  • Rejected: when the provider or gateway answers with an authentication error ("invalid x-api-key", "OAuth token has expired", and similar), the project stops dispatching with credentials_rejected and says which credential to update. It tries again as soon as the credential changes, or when you restart the project. See Parking, pausing and credential errors.

See also#