Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit 46264d8

Browse files
committed
fix(agent): treat a zero-byte credential file as logout
The backend logs the sandbox out by truncating the github env file to zero bytes. The resolver returned undefined for that shape, letting consumers fall back to the frozen process-env token and resurrect the previous actor's credentials. Treat an empty (or whitespace-only) managed file as an explicit logout (return ""), with regression tests for the zero-byte case.
1 parent 8aca9c7 commit 46264d8

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

packages/agent/src/utils/github-token.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ describe("github-token", () => {
6666
expect(readGithubTokenFromSandboxEnvFile(path)).toBe("");
6767
});
6868

69+
it("returns '' (logout) when the managed file is truncated to zero bytes", () => {
70+
// The backend logs the sandbox out by writing an empty file, not emptied vars.
71+
expect(readGithubTokenFromSandboxEnvFile(writeEnvFile(""))).toBe("");
72+
expect(readGithubTokenFromSandboxEnvFile(writeEnvFile(" \n"))).toBe("");
73+
});
74+
6975
it("returns undefined when the file carries no token var at all", () => {
7076
const path = writeEnvFile("PATH=/usr/bin\0HOME=/root\0");
7177
expect(readGithubTokenFromSandboxEnvFile(path)).toBeUndefined();
@@ -99,6 +105,13 @@ describe("github-token", () => {
99105
expect(resolveGithubToken(path)).toBe("");
100106
});
101107

108+
it("does not resurrect the process-env token when the file is zero bytes (logout)", () => {
109+
// The backend's actual logout truncates the file to zero bytes; resolving
110+
// must treat that as logout, not fall back to the frozen process env.
111+
vi.stubEnv("GH_TOKEN", "ghs_previous_actor");
112+
expect(resolveGithubToken(writeEnvFile(""))).toBe("");
113+
});
114+
102115
it("falls back to the process env when the file carries no token var", () => {
103116
vi.stubEnv("GH_TOKEN", "ghs_fromprocess");
104117
const path = writeEnvFile("PATH=/usr/bin\0");

packages/agent/src/utils/github-token.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ export function readGithubTokenFromSandboxEnvFile(
2828
}
2929
return "";
3030
}
31+
// The backend logs the sandbox out by truncating this file to zero bytes, so a
32+
// successfully-read but empty (or whitespace-only) managed file is an explicit
33+
// logout — return "" so the caller does NOT resurrect the previous actor's token
34+
// from the frozen launch-time process env. Only an absent file is "unmanaged".
35+
if (raw.trim() === "") {
36+
return "";
37+
}
3138
const env: Record<string, string> = {};
3239
for (const entry of raw.split("\0")) {
3340
const eq = entry.indexOf("=");

0 commit comments

Comments
 (0)