-
Notifications
You must be signed in to change notification settings - Fork 61
fix(agent): treat an emptied sandbox env file as GitHub logout #3611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3c607e1
2e4665b
9d80e31
4923c1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,8 @@ | ||
| import { readFileSync } from "node:fs"; | ||
| import { readGithubTokenFromEnv } from "@posthog/git/signed-commit"; | ||
| import { | ||
| GITHUB_TOKEN_ENV_VARS, | ||
| readGithubTokenFromEnv, | ||
| } from "@posthog/git/signed-commit"; | ||
|
|
||
| // helpers for resolving the in-sandbox GitHub token | ||
| // Dedicated agentsh credential file (NUL-delimited `key=value` pairs) that the | ||
|
|
@@ -12,19 +15,45 @@ const SANDBOX_GITHUB_ENV_FILE = "/tmp/agent-github-env"; | |
| export function readGithubTokenFromSandboxEnvFile( | ||
| envFilePath: string = SANDBOX_GITHUB_ENV_FILE, | ||
| ): string | undefined { | ||
| let raw: string; | ||
| try { | ||
| const raw = readFileSync(envFilePath, "utf8"); | ||
| const env: Record<string, string> = {}; | ||
| for (const entry of raw.split("\0")) { | ||
| const eq = entry.indexOf("="); | ||
| if (eq > 0) { | ||
| env[entry.slice(0, eq)] = entry.slice(eq + 1); | ||
| } | ||
| raw = readFileSync(envFilePath, "utf8"); | ||
| } catch (err) { | ||
| // A genuinely absent file (local/desktop or test) is unmanaged: signal that so | ||
| // the caller falls back to the process env. But an existing-yet-unreadable file | ||
| // during an actor transition must NOT resurrect the frozen process token, so | ||
| // treat any other read error as an explicit logout (fail closed). | ||
| if ((err as NodeJS.ErrnoException).code === "ENOENT") { | ||
| return undefined; | ||
| } | ||
| // Reuse the shared token-var allowlist + precedence instead of hardcoding. | ||
| return readGithubTokenFromEnv(env); | ||
| } catch { | ||
| // No env file (local/desktop or test) — fall back to the process env. | ||
| return ""; | ||
| } | ||
| // The backend logs the sandbox out by truncating this file to zero bytes, so a | ||
| // successfully-read but empty (or whitespace-only) managed file is an explicit | ||
| // logout — return "" so the caller does NOT resurrect the previous actor's token | ||
| // from the frozen launch-time process env. Only an absent file is "unmanaged". | ||
| if (raw.trim() === "") { | ||
| return ""; | ||
| } | ||
| const env: Record<string, string> = {}; | ||
| for (const entry of raw.split("\0")) { | ||
| const eq = entry.indexOf("="); | ||
| if (eq > 0) { | ||
| env[entry.slice(0, eq)] = entry.slice(eq + 1); | ||
| } | ||
| } | ||
| // A non-empty value wins by the shared token-var precedence. | ||
| const token = readGithubTokenFromEnv(env); | ||
| if (token) { | ||
| return token; | ||
| } | ||
| // The file is the backend's live credential channel. If it carries the token | ||
| // vars but they are emptied, that is an explicit logout on an actor | ||
| // transition — return "" so the caller does NOT resurrect the previous | ||
| // actor's token from the frozen launch-time process env. Only a file with no | ||
| // token vars at all is "unmanaged" and defers to the process env. | ||
| if (GITHUB_TOKEN_ENV_VARS.some((name) => name in env)) { | ||
| return ""; | ||
| } | ||
| return undefined; | ||
| } | ||
|
Comment on lines
57
to
59
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The BE clears this file to zero bytes, which returns |
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.