row 228: ZAI_API_KEY in the session env allowlist (#1729)
(cherry picked from commit 4fa2ed1e3d5e20ad5a0c98a1578e35d4ba055c67)
This commit is contained in:
1 parent
9b53620185
commit
3a2b547c3f
3 files changed
+16
-5
No files matched your search
@@ -432,8 +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
|
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
|
`~/.claude` reaches a session, whose `HOME` is its own. With none of them
|
||||||
set, a Claude Code launch refuses `no-session-credential` before anything
|
set, a Claude Code launch refuses `no-session-credential` before anything
|
||||||
starts. A Pi session gets the same variables through the allowlist. A
|
starts. A Pi session gets the same variables through the allowlist. A Pi
|
||||||
shell the harness opens, Claude Code's `Bash` or Pi's `bash`, can read
|
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, and a shell inside any of them can read
|
||||||
|
it. A shell the harness opens, Claude Code's `Bash` or Pi's `bash`, can read
|
||||||
them.
|
them.
|
||||||
|
|
||||||
A Pi session logs in only through the variables `ENV_ALLOW` passes. Its
|
A Pi session logs in only through the variables `ENV_ALLOW` passes. Its
|
||||||
@@ -708,8 +711,9 @@ keeps the environment it started with until it restarts.
|
|||||||
|
|
||||||
The session credential comes from
|
The session credential comes from
|
||||||
`EnvironmentFile=-%h/.config/mosaic-dev/secrets/claude-session.env`, the
|
`EnvironmentFile=-%h/.config/mosaic-dev/secrets/claude-session.env`, the
|
||||||
one place the path is set. The file holds one line, for example
|
one place the path is set. The file holds one line per variable, for
|
||||||
`CLAUDE_CODE_OAUTH_TOKEN=<token>`, mode 0600. The operator writes it;
|
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
|
nothing in the repository creates it, and only the Case 2 precheck reads
|
||||||
it, printing variable names, never values. No session sees the file
|
it, printing variable names, never values. No session sees the file
|
||||||
itself, only the variable. The leading `-` lets the unit start
|
itself, only the variable. The leading `-` lets the unit start
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export function threadStore(dataRoot, business, thread) {
|
|||||||
export const ENV_ALLOW = Object.freeze([
|
export const ENV_ALLOW = Object.freeze([
|
||||||
"HOME", "USER", "LOGNAME", "LANG", "LC_ALL", "TZ", "TERM",
|
"HOME", "USER", "LOGNAME", "LANG", "LC_ALL", "TZ", "TERM",
|
||||||
"ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL", "CLAUDE_CODE_OAUTH_TOKEN",
|
"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",
|
"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");
|
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", () => {
|
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(0, null), { code: 0, signal: null });
|
||||||
assert.deepEqual(sessionExit(23, null), { code: 23, signal: null });
|
assert.deepEqual(sessionExit(23, null), { code: 23, signal: null });
|
||||||
|
|||||||
Reference in new issue
Block a user