This repository was archived by the owner on Aug 6, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 66
fix(agent): treat an emptied sandbox env file as GitHub logout #3611
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
adeca00
fix(agent): treat an emptied sandbox env file as GitHub logout
VojtechBartos 9c7441b
fix(agent): run gh attribution/whoami as the current actor
VojtechBartos 8aca9c7
fix(agent): honor the logout sentinel in every token consumer
VojtechBartos 46264d8
fix(agent): treat a zero-byte credential file as logout
VojtechBartos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.