row 228: ZAI_API_KEY in the session env allowlist (#1729)
Lands Researcher's round 3 candidate, manifest 82cf98c6 (cf18c42b9on researcher/row228-r3, basec771a36f4), approved by Webby (29949, rev 2708). Three paths: packages/seat/src/session.mjs (ZAI_API_KEY in ENV_ALLOW), packages/seat/tests/session.test.mjs (the pass-through test) and packages/cli/README.md (the line, with the round 1 and round 2 N1 trims at :711 and :718). Round 3 is the round 2 rebase onto the row 234 landing; the two seat files carry the blobs approved in rounds 1 and 2. Evidence: Researcher's slot run oncf18c42b9: session.test.mjs 13/0, host.test.mjs 42/0 (sage-1796). Round 2's seat and cli runs, 94/0, and its killed mutant stand, since the seat blobs are unchanged. Sage's combined gate with row 238 onc515273dbplus both rows' paths (07:11:30Z to 07:23:34Z): packages/seat 165 pass, 0 fail; packages/cli 640 pass, 0 fail; all ten scripts/test-*.sh 585 pass, 0 fail (out/, run.log). bus runtime.mjs and webui reads.mjs import only readSessions from session.mjs, which this change doesn't touch. `queue review verify-commit 228` matches the manifest on all 3 paths.
This commit is contained in:
+10
-7
@@ -432,9 +432,11 @@ A Claude Code session logs in with `CLAUDE_CODE_OAUTH_TOKEN`,
|
||||
on. The bus unit loads it ("Unit" below). Nothing from the host's
|
||||
`~/.claude` reaches a session, whose `HOME` is its own. With none of them
|
||||
set, a Claude Code launch refuses `no-session-credential` before anything
|
||||
starts. A Pi session gets the same variables through the allowlist. A
|
||||
shell the harness opens, Claude Code's `Bash` or Pi's `bash`, can read
|
||||
them.
|
||||
starts. A Pi session gets the same variables through the allowlist. A Pi
|
||||
session on provider `zai` logs in with `ZAI_API_KEY`, which the allowlist
|
||||
passes. Like every allowlist variable, it reaches every session the host
|
||||
starts, Claude Code ones included. A shell the harness opens, Claude Code's
|
||||
`Bash` or Pi's `bash`, can read all of these variables.
|
||||
|
||||
A Pi session logs in only through the variables `ENV_ALLOW` passes. Its
|
||||
`HOME` is the run's own, so Pi never reads the operator's `~/.pi/agent`
|
||||
@@ -706,13 +708,14 @@ instead and sessions run `claude` from the unit's `PATH`, which in the
|
||||
sandbox finds only a `claude` under `/usr`. A running host
|
||||
keeps the environment it started with until it restarts.
|
||||
|
||||
The session credential comes from
|
||||
The session credentials come from
|
||||
`EnvironmentFile=-%h/.config/mosaic-dev/secrets/claude-session.env`, the
|
||||
one place the path is set. The file holds one line, for example
|
||||
`CLAUDE_CODE_OAUTH_TOKEN=<token>`, mode 0600. The operator writes it;
|
||||
one place the path is set. The file holds one line per variable, for
|
||||
example `CLAUDE_CODE_OAUTH_TOKEN=<token>`, mode 0600. It holds every session
|
||||
provider key, not only Claude's. The operator writes it;
|
||||
nothing in the repository creates it, and only the Case 2 precheck reads
|
||||
it, printing variable names, never values. No session sees the file
|
||||
itself, only the variable. The leading `-` lets the unit start
|
||||
itself, only the variables. The leading `-` lets the unit start
|
||||
without it, so Pi sessions still launch and a Claude Code launch refuses
|
||||
`no-session-credential`. To change the credential, edit or swap the file
|
||||
(or this line and this paragraph), then restart the unit; a running host
|
||||
|
||||
@@ -83,7 +83,7 @@ export function threadStore(dataRoot, business, thread) {
|
||||
export const ENV_ALLOW = Object.freeze([
|
||||
"HOME", "USER", "LOGNAME", "LANG", "LC_ALL", "TZ", "TERM",
|
||||
"ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_OAUTH_TOKEN",
|
||||
"OPENAI_API_KEY", "OPENROUTER_API_KEY",
|
||||
"OPENAI_API_KEY", "OPENROUTER_API_KEY", "ZAI_API_KEY",
|
||||
"MOSAIC_CLAUDE_BIN",
|
||||
]);
|
||||
|
||||
|
||||
@@ -58,6 +58,13 @@ test("sessionEnv passes only the allowlist, the repo's bin on PATH, and the run
|
||||
assert.equal(sessionEnv({ MOSAIC_CLAUDE_BIN: "/opt/claude" }, "r0123456789ab").MOSAIC_CLAUDE_BIN, "/opt/claude");
|
||||
});
|
||||
|
||||
test("ZAI_API_KEY passes the session allowlist, and ZAI_TOKEN does not", () => {
|
||||
assert.ok(ENV_ALLOW.includes("ZAI_API_KEY"));
|
||||
const env = sessionEnv({ ZAI_API_KEY: "fixture-zai", ZAI_TOKEN: "t" }, "r0123456789ab");
|
||||
assert.equal(env.ZAI_API_KEY, "fixture-zai");
|
||||
assert.equal(Object.hasOwn(env, "ZAI_TOKEN"), false);
|
||||
});
|
||||
|
||||
test("sessionExit gives a runner's signal death back as the signal; a session credential is one whole set of nonempty variables", () => {
|
||||
assert.deepEqual(sessionExit(0, null), { code: 0, signal: null });
|
||||
assert.deepEqual(sessionExit(23, null), { code: 23, signal: null });
|
||||
|
||||
Reference in New Issue
Block a user