seekrit
Docs/Signed-in coding agents

Signed-in coding agents

Claude Code and Codex can run on a subscription instead of an API key — but their sign-in lives in a file on the machine you signed in on. A fresh sandbox has no such file, so every one of them asks you to sign in again.

seekrit keeps that sign-in for you. Sign in once, from any machine, and every sandbox you start through seekrit run is already signed in — on any provider, because the only thing the sandbox needs is the seekrit CLI and a token:

# once, on your laptop
seekrit agent-login codex --app agents --env ava

# in every sandbox, from then on
seekrit run --agent-login codex -- codex exec "Add a /health endpoint"

The login is encrypted on your machine and decrypted inside the sandbox, like every other seekrit secret: the seekrit API stores ciphertext it cannot read.

No terminal handy? Sign in from the dashboard instead.

Pick the credential

You runStoreWhat the sandbox runsRefreshes?
Claude Code, many sandboxes at onceA long-lived token — seekrit agent-login claudeseekrit run -- claude -p "…"No — lasts a year
Claude Code, needing the full account sign-inIts login file — seekrit agent-login claude --from …seekrit run --agent-login claude -- claude …Yes, saved back
Codex on a ChatGPT planIts login file — seekrit agent-login codexseekrit run --agent-login codex -- codex …Yes, saved back
Either, on API billingANTHROPIC_API_KEY / OPENAI_API_KEY as plain secretsseekrit run -- …No

The column that matters is the last one. A token that never refreshes is just a secret. A login that refreshes is harder, and is what the rest of this page is about.

Claude Code: the long-lived token

claude setup-token issues a token that lasts a year and never refreshes, made for exactly this. seekrit agent-login claude runs it, asks you to paste the token it prints, and stores it as CLAUDE_CODE_OAUTH_TOKEN — the variable Claude Code reads:

seekrit agent-login claude --app agents --env ava

From then on it is an ordinary secret: any seekrit run in that environment injects it, and nothing is written back.

seekrit run -- claude -p "Add a /health endpoint" --dangerously-skip-permissions

The token covers model calls. Features tied to a full account sign-in may need the login file instead (next section). Already have a token? Pipe it in: printenv CLAUDE_CODE_OAUTH_TOKEN | seekrit agent-login claude --token-stdin.

Codex: sign in once

seekrit agent-login codex --app agents --env ava
# no browser on this machine? add --device-auth

This runs codex login in a throwaway home directory, so the login seekrit stores is a new sign-in that belongs to seekrit alone, not a copy of your laptop's. It is stored as CODEX_LOGIN.

To store a login you already have — say you signed in inside a sandbox — pass the file:

seekrit agent-login codex --from ~/.codex/auth.json --move
caution

Without --move, the file and the copy in seekrit share one refresh token, and whichever refreshes first signs the other out. Keep exactly one of them.

The same --from works for Claude Code's full login, ~/.claude/.credentials.json on Linux, stored as CLAUDE_LOGIN.

From the dashboard

Every environment page has a Coding agent sign-ins card that does the same without a terminal.

Sign in Codex runs the same device sign-in as codex login --device-auth, in the browser tab: the dashboard shows a one-time code, you enter it at auth.openai.com/codex/device, and the tab waits for you to approve. OpenAI sends the sign-in straight back to the tab — its auth endpoints accept requests from other sites — where it is turned into the same auth.json Codex writes, encrypted with the environment's key, and stored as CODEX_LOGIN. seekrit's servers never see it. Your keyring is unlocked before you are sent to OpenAI, so an approved sign-in is never lost to a cancelled unlock.

caution

Enter a code only because you started the sign-in yourself, in this dashboard. If a website or another person hands you a code, close the dialog: that is how device-code phishing works.

Add Claude Code token takes the token claude setup-token prints. Claude Code has no device sign-in, and Anthropic's token endpoint does not accept requests from other sites, so the dashboard cannot complete a Claude sign-in by itself — doing it on seekrit's servers would mean those servers saw your token. Run claude setup-token on any machine with Claude Code, paste the result, and the tab encrypts it as CLAUDE_CODE_OAUTH_TOKEN. The same dialog takes a full .credentials.json (stored as CLAUDE_LOGIN) when you need the whole account sign-in.

Run it in a sandbox

Give the sandbox the seekrit CLI and a service token bound to the environment that holds the login, then launch the agent through seekrit run --agent-login:

npm i -g @seekrit/cli @openai/codex
export SEEKRIT_TOKEN=skt_…
seekrit run --agent-login codex -- codex exec "Add a /health endpoint"

That works the same on E2B, Modal, Daytona, Vercel Sandbox, Fly, a CI runner or a container — anything that can run a command. --agent-login claude and --agent-login codex can both be given, and --agent-login codex=OTHER_NAME reads a login stored under another name.

What --agent-login does

Before the agent starts, seekrit writes the login file where the agent looks for it ($CODEX_HOME/auth.json, or $CLAUDE_CONFIG_DIR/.credentials.json; ~/.codex and ~/.claude by default). When the agent exits, the file is removed. A run never overwrites a login that seekrit did not put there.

In between, it keeps the login alive. Both agents sign in with an OAuth refresh token that changes every time it is used. If a sandbox refreshed and threw the new token away with its disk, the next sandbox would present the old one, the provider would reject it as reused, and you would be signed out. So:

  • Every refresh is saved back. The file is watched, and the moment the agent refreshes, the new login is encrypted and stored — conditioned on the version this sandbox read, so two sandboxes can never silently overwrite each other.
  • Running sandboxes pick up each other's refreshes. Near refresh time a sandbox checks for a newer copy every few seconds and writes it to disk. Both agents re-read their login before refreshing, so they adopt it instead of spending a token a sibling already used.
  • One sandbox refreshes; the rest wait. A sandbox that starts when the login is due to refresh marks it as being refreshed first. Others starting at the same moment wait for that refresh — up to two minutes — rather than each refreshing the same token.

The marker lives inside the encrypted value, so the API sees nothing but ciphertext and version numbers. seekrit never calls Anthropic's or OpenAI's token endpoints — the agent refreshes itself, exactly as on your laptop, and seekrit only moves the file.

If a refresh cannot be saved — seekrit unreachable when the agent exits — the run says so, exits non-zero, and leaves the login on disk. The next seekrit run --agent-login on that machine saves it.

Check on a login

seekrit agent-login status --app agents --env ava
NAME                     AGENT   KIND              VERSION  NEXT REFRESH
CLAUDE_CODE_OAUTH_TOKEN  claude  long-lived token  v1       never
CODEX_LOGIN              codex   login file        v14      2026-11-19T08:12:44.000Z

Signed out anyway — the provider revoked it, or a sign-in was lost? Run seekrit agent-login codex again; it replaces the stored login, and the next sandbox uses the new one.

Where to keep logins

  • One environment per person. A subscription login is a personal credential. Spreading one person's sign-in across a team's agents is account sharing as far as Anthropic and OpenAI are concerned, and usage limits are per account anyway. Keep each person's logins in an environment only they and their sandboxes can read.
  • Not a protected environment. A refresh has to be saved the moment it happens, so an environment with approvals is refused: the refresh would wait for a reviewer while the old token is already spent.
  • Little else beside them. The sandbox's token can read and write everything in its environment, and the agent can read the token. An environment holding the login and the agent's own keys — not production — keeps that small.
note

The agent holds its own login: it is the credential the agent signs in with, so it has to be on the sandbox's disk while the agent runs, and code the agent runs can read it. For credentials the agent uses rather than is — API keys for the services it calls — keep them outside the sandbox with seekrit-proxy.

Limits

  • Two sandboxes already running at refresh time can still collide. If both refresh in the same few seconds, before either sees the other's copy, one of them may be signed out. For a large parallel fleet, prefer a credential with no refresh to race: the Claude Code long-lived token, or an API key.
  • Claude Code on macOS keeps its login in the Keychain, not in .credentials.json, so --agent-login claude takes effect on Linux — sandboxes, containers and CI. The long-lived token works everywhere.
  • seekrit run only. The seekrit-run launcher and the SDKs inject variables; they do not manage login files.
  • The dashboard's Codex sign-in borrows Codex's public sign-in client. It sends exactly the requests codex login --device-auth does. If OpenAI ever stops accepting them from a browser, seekrit agent-login codex --device-auth still works, because it runs the real codex.

See also