Skip to content

Commit 646f66a

Browse files
committed
feat(cloud): inject the ChatGPT subscription credential into serve container
Verified end-to-end in the live container BEFORE wiring (temp /__diag probe): vendored codex read a dropped ~/.codex/auth.json, `codex login status` = 'Logged in using ChatGPT', container egressed, real turn completed (gpt-5.5, HELLO_FROM_CLOUD). Subscription path works headless — no API key. - index.ts: pass CODEX_AUTH_JSON through startProcess env to the container. - start-serve.sh: write it to $CODEX_HOME/auth.json (0600) before serve starts, so Helmor's sidecar-spawned codex authenticates as the user's subscription. Phase-1 will swap the whole-credential passthrough for a control-plane token broker (mint per-turn access_token via auth.openai.com/oauth/token public client; inject a ChatgptAuthTokens auth.json), keeping the rotating refresh token in the durable control plane, never the ephemeral container.
1 parent 0eb34f0 commit 646f66a

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

cloud/scripts/start-serve.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ if pgrep -f "${HELMOR_HOME}/helmor serve" >/dev/null 2>&1; then
4040
exit 0
4141
fi
4242

43+
# Cloud run identity (subscription): the Worker injects the ChatGPT auth.json via
44+
# CODEX_AUTH_JSON; drop it where codex looks (CODEX_HOME, default ~/.codex) so the
45+
# agent authenticates as the user's subscription. Verified end-to-end in-container
46+
# (codex login status = "Logged in using ChatGPT", real turn completed). Phase-1
47+
# will inject a per-turn short-lived token from the control-plane broker instead.
48+
if [ -n "${CODEX_AUTH_JSON:-}" ]; then
49+
codex_dir="${CODEX_HOME:-${HOME:-/root}/.codex}"
50+
mkdir -p "$codex_dir"
51+
printf '%s' "$CODEX_AUTH_JSON" >"$codex_dir/auth.json"
52+
chmod 600 "$codex_dir/auth.json"
53+
echo "helmor-start-serve: wrote $codex_dir/auth.json ($(wc -c <"$codex_dir/auth.json") bytes)"
54+
fi
55+
4356
# 1. Independent Xvfb daemon (idempotent — skip if one is already running).
4457
if ! pgrep -x Xvfb >/dev/null 2>&1; then
4558
Xvfb "$DISPLAY" -screen 0 1280x800x24 -nolisten tcp >/tmp/xvfb.log 2>&1 &

cloud/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ interface Env {
2121
HELMOR_COMPANION_TOKEN: string;
2222
/** PAT for PR6 clone / push, injected into the serve process env (secret). */
2323
GITHUB_TOKEN?: string;
24+
/** Cloud run identity: ChatGPT auth.json (the user's subscription), written to
25+
* the container's ~/.codex/auth.json so the agent authenticates as that
26+
* subscription. Phase-0 passes the whole credential through; Phase-1 will have
27+
* the control-plane broker mint a per-turn short-lived token instead. */
28+
CODEX_AUTH_JSON?: string;
2429
}
2530

2631
/** Boot script staged in the image (Xvfb daemon → readiness → `helmor serve`). */
@@ -78,6 +83,7 @@ async function ensureServe(
7883
HELMOR_COMPANION_TOKEN: env.HELMOR_COMPANION_TOKEN,
7984
HELMOR_SERVE_PORT: String(port),
8085
...(env.GITHUB_TOKEN ? { GITHUB_TOKEN: env.GITHUB_TOKEN } : {}),
86+
...(env.CODEX_AUTH_JSON ? { CODEX_AUTH_JSON: env.CODEX_AUTH_JSON } : {}),
8187
},
8288
});
8389

0 commit comments

Comments
 (0)