Skip to content

Agent credentials

A coding agent needs to authenticate with its provider. CommandChain never asks you to type a provider key into a web form. Instead, the runner CLI reads the login you already have on your machine and uploads it to your account, where it is released to one run attempt at a time.

Credentials captured this way are per user, never shared across your workspace.

Terminal window
commandchain-runner creds push # detect all three agents, upload what is found
commandchain-runner creds push --agent codex # one agent only
commandchain-runner creds list # what is stored, metadata only
commandchain-runner creds rm claude-code # delete one stored credential

These commands authenticate with the runner’s own pairing credential, so they work on a machine that is already paired. Add --url https://your-commandchain to pick the instance if the machine is paired with more than one.

A successful push says what it uploaded and where it went, and nothing else:

Terminal window
$ commandchain-runner creds push --agent claude-code
✔ claude-code: uploaded oauth credential (secretRef: /commandchain/local/alpenglow/users/user-maya-chen/agent-creds/claude-code)
Done: 1 uploaded, 0 failed.
AgentSourceResult
claude-code$CLAUDE_CONFIG_DIR (else ~/.claude) credentials file, else ANTHROPIC_API_KEY or CLAUDE_API_KEY in the environmentOAuth or API key
codex$CODEX_HOME (else ~/.codex) auth.json, which holds either subscription tokens or an OpenAI keyOAuth or API key
geminiGEMINI_API_KEY or GOOGLE_API_KEY in the environment, else ~/.gemini login stateAPI key or OAuth

creds push is the only part of the runner that ever reads one of these files. Nothing else on the machine, and certainly no agent, reads your native login.

API keys are preferred over subscription logins

Section titled “API keys are preferred over subscription logins”

If a machine has both a provider API key and a subscription (OAuth) login for the same tool, push uploads the API key and tells you why:

Terminal window
claude-code: found both an OAuth login and a provider API key, pushing the API key
(preferred: revocable, and avoids the provider terms-of-service risk of cloud use
of a personal subscription login).

An API key is revocable on its own, without touching your account, and it is the kind of credential providers intend for automated use.

Uploading a subscription login is an explicit decision

Section titled “Uploading a subscription login is an explicit decision”

Pushing an OAuth login means a runner can act as you, with your personal subscription, on a machine you may not be sitting at. That is worth a deliberate act, so the CLI will not do it quietly.

Interactively, it prints the risk and requires you to type an exact phrase:

Terminal window
$ commandchain-runner creds push --agent claude-code
⚠ You are uploading your personal Anthropic (Claude) SUBSCRIPTION login (OAuth) to CommandChain so a
cloud runner can act as you. This may violate Anthropic (Claude)'s terms for non-interactive/cloud
use and puts your personal account at risk if the platform is compromised. Prefer a provider
API key where possible.
Type 'i understand' to continue:

Non-interactively there is no prompt to answer, so the push fails unless you passed the flag that says the same thing:

Terminal window
$ commandchain-runner creds push --agent claude-code < /dev/null
⚠ You are uploading your personal Anthropic (Claude) SUBSCRIPTION login (OAuth) to CommandChain so a
cloud runner can act as you. This may violate Anthropic (Claude)'s terms for non-interactive/cloud
use and puts your personal account at risk if the platform is compromised. Prefer a provider
API key where possible.
✖ claude-code: OAuth upload aborted - non-interactive session. Re-run with --accept-oauth-risk to acknowledge the risk explicitly.
Done: 0 uploaded, 1 failed.

Anything you acknowledge is recorded with the credential, so the account page can show later that a stored login carries that risk.

creds list prints what is stored server-side. There is no view, anywhere in the product or the API, that returns credential material:

Terminal window
$ commandchain-runner creds list
AGENT AUTH EXPIRES UPDATED
claude-code oauth 2026-07-24T03:13:08.865Z 2026-07-23T20:30:54.596Z

The same information is in the app under Settings, then Coding Agents, with one action per row:

The Coding Agents settings page, showing a connected Claude Code credential and the command to connect the other two.

Debug logging of an upload is routed through a redaction mask, so a credential value cannot reach a log line even when logging is turned all the way up.

When a run starts, the platform releases the credential for that attempt only. The runner stages it into the attempt’s synthetic home, the coding agent uses it, and the whole tree is deleted when the attempt ends. Nothing is written into the workspace, and nothing survives the attempt.

A second request to release the same credential for the same attempt is refused with a conflict. That is the design, not a fault:

  • An attempt needs its credential exactly once, at the start.
  • A second request means something is asking for a secret that has already been handed out, which is worth failing on rather than serving.

If you see that conflict in a run’s logs, treat it as a signal that the attempt was retried in an unexpected way, and look at the attempt history rather than at the credential.

creds rm <agent> deletes the stored copy, and so does Delete on the Coding Agents page. Either way the effect is immediate:

Terminal window
$ commandchain-runner creds rm claude-code
✔ removed stored claude-code credential

Your runner loses access to that credential straight away, and runs that need it fail until you push a new one. Removing the stored copy does not touch the login on your own machine.