AgentConnect
Operate & GovernSandboxing

Credential protection

How code-host tokens, provider API keys, and saved logins are kept out of agent sessions.

The daemon keeps real credentials out of agent sessions wherever it can. A session gets a placeholder instead, and the daemon's credential proxy swaps in the real credential only on requests to the destination it was issued for. Anything the agent reads from its environment or files is useless anywhere else.

Code-host credentials

GitHub, GitLab, and Gitea access works this way in every execution environment: host, srt, microsandbox, Kubernetes pool pods, and sessions a daemon group runs on another member's machine. There is nothing to enable.

  • git, gh, and glab work as usual. The proxy attaches a short-lived token scoped to the repository the request names and the agent's access level on it.
  • The session's environment, Git configuration, and files hold no usable token.
  • A token the agent was given itself, such as its own GH_TOKEN or GITLAB_TOKEN secret, passes through unchanged.
  • The former gh-token and glab-token helper commands and the gh and glab wrappers are gone. Scripts should call git, gh, or glab directly.

What the proxy refuses

RequestResult
A GitHub GraphQL mutationRefused: GraphQL is read-only. The error names the agent's code-host tool for the write (pull requests, issues, comments, reviews), and the agent retries with it.
A GitLab or Gitea API writeRefused, naming the tool for the write. API reads work.
git push to a repository the agent can only readRefused with a message that the agent lacks write access. Grant Read & write to allow it.
A REST write that names no repositoryRefused. GitHub REST writes to a repository, such as gh api, go through at the agent's access level.

Creating or changing GitHub Projects items and Discussions, which only GraphQL writes can do, is unavailable to agents; reading them still works.

A session that cannot reach the proxy, for example on a Kubernetes runtime image older than the daemon, starts with no code-host credential, and the daemon logs why.

Provider API keys

The same proxy carries model provider API keys. The runtime holds a placeholder, and the request that reaches the provider carries the real key.

KeySessions
Organization Infra → Provider keys, for an agent whose Model sign-in is Provider keyHost, srt, and microsandbox, including host sessions a daemon group runs on another member
API keys on the daemon's own machine, for the runtimes marked Proxy belowsrt and microsandbox
A Kubernetes install's keys: daemonPool.modelCredentials, modelEgress.clients.<client>.apiKey, and ANTHROPIC_API_KEY, OPENAI_API_KEY, DEEPSEEK_API_KEY, or COPILOT_PROVIDER_API_KEY mapped in daemonPool.runtimeEnvironmentPool pods (details)

The proxy adds an organization key's extra headers; they never enter the session. After a key's endpoint changes, start a new session to use it.

These still reach the session as they are:

  • a key whose endpoint is plain http://, since a placeholder is exchanged only over HTTPS;
  • a key the daemon cannot tie to one HTTPS endpoint for that runtime, such as one sent to a custom port (the daemon logs this once);
  • short-lived per-session keys issued by a key server;
  • subscription and OAuth sign-ins, covered below; and
  • the daemon machine's own keys in a host session, which can read the machine's files anyway.

Trust and network

The proxy terminates TLS for code-host and provider requests, so sessions trust a certificate authority the daemon creates. The daemon points the standard trust variables (SSL_CERT_FILE, NODE_EXTRA_CA_CERTS, GIT_SSL_CAINFO, REQUESTS_CA_BUNDLE) at a bundle of the system roots, that authority, and the authorities the operator or the session's own variables already named. Sessions reach the proxy through HTTPS_PROXY; a client that ignores it, or pins its own certificates, reaches the code host or provider with only the placeholder and is refused.

For operators:

  • Egress. The daemon makes the upstream request, so it needs outbound HTTPS to every code host and provider endpoint its agents use. On Kubernetes that is the daemon pool, not the agent pods.
  • Private authorities. The proxy verifies the upstream with the daemon's trust roots and the authorities set for the daemon.
  • Outbound proxy. A daemon that reaches the internet through its own HTTPS_PROXY sends the proxy's upstream requests through it too, and honors NO_PROXY.

Protection by runtime

The rest of this page covers logins saved on a self-hosted Linux daemon. Protection depends on the runtime and login method, and is the same in srt and microsandbox.

RuntimeOAuthAPI key
Claude CodeTool rulesProxy
CodexTool rulesProxy
DeepSeek HarnessNAProxy
OpenCodeUnshieldedProxy
piUnshieldedProxy
Grok BuildUnshieldedProxy
Qwen CodeUnshieldedProxy
Oh My PiUnshieldedProxy
AmpNAProxy
Kimi CodeUnshieldedProxy
ClineUnshieldedProxy
DevinUnshieldedNA
Antigravity ACPUnshieldedProxy
GitHub CopilotUnshieldedProxy
Qoder CLIUnshieldedUnshielded
Qoder CN CLIUnshieldedUnshielded
  • Tool rules: the runtime blocks its tools from reading or changing protected credential files.
  • Proxy: the real API key stays on the host (supported sources below).
  • Unshielded: tools may read the credential inside the sandbox.
  • NA: login mode not covered by this integration.

Claude Code and Codex also keep their tool rules when using the API proxy.

OAuth and tool rules

OAuth credentials are mounted or copied into the session. The runtime handles login and token refresh.

Claude Code and Codex use the same tool rules in SRT and microsandbox. Claude Code restricts Bash and its file tools (including Read and Edit). Codex uses permission profiles to restrict tool access to credential paths. The runtime itself can still read its credentials to authenticate.

These rules apply to the integrated runtime tools. They do not cover arbitrary helper processes or MCP servers. Other runtimes receive OAuth credentials without an additional shield.

API key proxy

For supported logins, the daemon gives the session a placeholder instead of the real API key. The host proxy replaces that placeholder in outgoing request headers only for the provider's approved HTTPS endpoint.

In both srt and microsandbox, this covers the saved keys of every runtime in the table below, and keys set in the daemon's environment or the runtime definition: ANTHROPIC_API_KEY for Claude Code, OPENAI_API_KEY for Codex, DEEPSEEK_API_KEY for DeepSeek Harness, and GitHub Copilot's and Antigravity ACP's keys. In srt, it also covers those variables for OpenCode.

The sandbox's imported credential files contain placeholders. For Oh My Pi, the daemon creates a private SQLite database with placeholders before writing any API-key records. The host's login files remain unchanged.

The proxy uses provider settings from the host. Editing settings inside the sandbox cannot authorize another destination for a key. The authorized provider receives the real key (its responses are not redacted).

Supported saved keys

RuntimeKey source
Claude CodeprimaryApiKey in the active global configuration
CodexOPENAI_API_KEY in CODEX_HOME/auth.json
DeepSeek HarnessStandard DEEPSEEK_API_KEY entry in .dsh/.credentials.yaml or .dsh/.env
OpenCodeAPI records in auth.json (type: api)
piAPI records in auth.json, or provider keys in models.json
Grok BuildPer-model keys in config.toml (model.<id>.api_key)
Qwen CodeModel-provider keys in settings.json (including legacy security.auth.apiKey)
Oh My PiAPI-key records in agent.db
AmpNative CLI entries in secrets.json (apiKey@<service URL>)
Kimi CodeProvider keys in .kimi-code/config.toml (providers.<name>.api_key)
ClineProvider API keys in providers.json (apiKey or auth.apiKey)
GitHub CopilotCOPILOT_PROVIDER_API_KEY, sent to COPILOT_PROVIDER_BASE_URL
Antigravity ACPGEMINI_API_KEY (the gemini-api-key sign-in method)

Provider limits

DeepSeek uses https://api.deepseek.com. Grok, Qwen, and Kimi Code need an explicit HTTPS endpoint in the host configuration (for Kimi Code, the provider's base_url). Claude Code, Codex, OpenCode, and pi use supported host provider settings or built-in defaults. Oh My Pi uses built-in provider defaults.

pi, Oh My Pi, and Cline support the default endpoints for Anthropic, OpenAI, DeepSeek, Google, xAI, OpenRouter, Groq, and Mistral. Cline's other providers need an HTTPS baseUrl in the provider entry. Custom Codex providers must set requires_openai_auth = true.

GitHub Copilot needs an HTTPS COPILOT_PROVIDER_BASE_URL. Antigravity ACP uses the Gemini API, or GOOGLE_GEMINI_BASE_URL when it is set to an HTTPS endpoint.

If a recognized API key has no supported route, it stays hidden and that provider is unavailable. OpenCode's other configured providers can still work. DeepSeek rejects a custom endpoint at startup.

Protection covers the saved sources above. It does not automatically cover keyrings, command-based keys, arbitrary headers, custom plugins, or new logins performed inside the sandbox. Amp's separate amp-acp/credentials.json login is outside this protection. Oh My Pi keys stored only in custom model files are also outside it. Cline's AWS credentials and custom headers stay as they are, and so does a Kimi Code provider that reads its key from a variable (api_key_env).

Qoder CLI and Qoder CN CLI keys stay unshielded: a personal access token is exchanged in a request body, and a service account key must keep a format that no placeholder can match. Devin signs in through the browser and has no separate API key login.

Supported endpoints use HTTPS without custom ports or URL credentials. Protected sessions reject custom TLS trust overrides and conflicting credential mounts.

Existing sessions and key changes

A protected VM reloads a changed host key when it resumes after stopping. A running VM keeps its current key. Changing login accounts, provider records, or credential layout can rebuild the VM (see what is preserved).

How is this guide?

On this page

How is this guide?