feat(cloud-worker): mount subscription logins for the run and write refreshed tokens back

Merged
KJ
9d ago
+921-3

Summary

agent-relay cloud worker now mounts a workspace's subscription logins (Codex ChatGPT and Grok auth files) for the run, and writes refreshed tokens back. This is the worker half of self-hosted Coding agents (AgentWorkforce/relaycontrol, selfhost/coding-agents-subscription-logins) and mirrors how hosted Cloud mounts ~/.codex/auth.json into its sandboxes. Khaliq asked for login credentials to be held server-side the way hosted Cloud does.

Flow

  1. Payload. A control plane that holds logins adds cliCredentials to the assignment payload: { ref, expiresAt, path: "/api/v1/workers/{workerId}/assignments/<runId>/cli-credentials", credentials: [...] }. The ref is a short-lived, run-scoped reference, not the files. The new field is optional in WorkerWorkflowPayload, and payloads without it behave exactly as before.
  2. Fetch. Before spawning relayflows, the worker calls GET <baseUrl><path> with its worker token plus X-Cli-Credential-Ref.
    • Only relative /api/ paths are accepted, so the reference never leaves the control plane origin.
  3. Write. Each file goes to <runDir>/.cli-home/<dir>/<file>, with mode 0600 inside 0700 directories.
    • Only CODEX_HOME and GROK_HOME may be set, and directory and file names are validated, so a hostile response can't escape the run dir.
  4. Env. CODEX_HOME/GROK_HOME point at those directories and win over inherited values. AGENT_RELAY_SUBSCRIPTION_LOGINS=codex,grok lets relayflows give the subscription precedence over OPENAI_API_KEY/XAI_API_KEY (AgentWorkforce/relayflows#65).
  5. Write-back. After the run, any file the CLI rewrote (its own token refresh) is sent back with PUT .../cli-credentials/<id>.
  6. Cleanup. The run dir, files included, is deleted as before.
    • Nothing logs file contents or the reference.

Tests

cloud-worker-cli-credentials.test.ts:

  • File modes (0600/0700), the env, and the request headers.
  • Rejects a hostile homeEnv and a path traversal.
  • Rejects a reference path pointing at another origin.
  • Writes back only changed files.
  • An assignment-runner test: the CODEX_HOME file is present during the run, the refreshed token is written back, and the run dir is deleted.

On sf-frame: npm ci, npm run typecheck, the new tests and cloud.test.ts (78 tests) pass, and prettier is clean.

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Agent Relay sessions

  • claude session a19e66d9 · opened via gh pr create · last active 2026-11-04