Skip to content

fix(cli): prefer local GitHub credentials [risk:high] - #414

Open
Leeeon233 wants to merge 3 commits into
mainfrom
fix/gh-local-credentials-first
Open

fix(cli): prefer local GitHub credentials [risk:high]#414
Leeeon233 wants to merge 3 commits into
mainfrom
fix/gh-local-credentials-first

Conversation

@Leeeon233

@Leeeon233 Leeeon233 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Risk: 🔴 high | Confidence: medium — changes credential selection and requester boundaries; regression tests and adversarial re-reviews passed, live Windows/keychain flows remain unverified.

Lody's gh wrapper could override a working local GitHub login with a restricted App token. Prefer the machine owner's valid environment credentials and active local gh login; use requester-bound managed credentials when owner authentication is missing or returns HTTP 401, or when the requester is another workspace member.

Credential selection now lives in the wrapper. Remove session-wide managed token injection and its refresh state while retaining legacy token cleanup. Authorize the requester before considering any environment token or local login. Missing or expired contexts fail closed, and each workspace wrapper uses a daemon-selected broker state path that child environment overrides cannot replace. Managed wrappers and shell startup files live outside the ordinary CLI bin, so unmanaged local shells continue using native gh.

Non-owner Session processes lose GitHub token variables after every environment overlay, including case variants on Windows. Requester changes terminate and restore ACP before delivering input; cross-requester steer queues a normal follow-up. Internal ACP replacement preserves the active turn rather than racing an unscoped termination finalizer. Commands are never replayed, and managed GitHub.com tokens are never selected for another host.

Validation:

  • Synced current main and adapted the requester gate/tests to its frozen runtime.invocation identity model. Main also supplies the corrected public Codex lockfile, resolving the Desktop E2E frozen-install failure.
  • In an isolated public checkout with pinned submodules: normal pnpm install --frozen-lockfile, pnpm typecheck, pnpm format:check, pnpm check:quick, and pnpm test:ci all passed. Explicit E2E TypeScript compilation passed too.
  • Tests: 2,539 CLI passed (4 skipped), 3,181 component, 1,016 shared, and 79 Electron tests passed. Regression coverage includes removed context, inherited tokens, forged broker authorities, workspace binding, Windows key casing, and ACP replacement ordering.
  • Independent security and lifecycle re-reviews found no remaining confirmed P0/P1. The embedded private workspace does not include the new E2E package, so its affected-check lint cannot resolve E2E types; the standalone public checks above validate the actual CI dependency graph.

Scope: this change prevents automatic credential inheritance and incorrect managed credential selection. The existing same-OS-user execution environment is not filesystem/keychain isolation; a hostile process with native credential access requires an OS/container boundary. An authentication-area owner should explicitly acknowledge this change before merge.

Centralize gh credential selection in the wrapper, preserve valid user credentials, and fall back to requester-bound managed credentials only when authentication is missing or revoked.

Model: gpt-6
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T13:20:37.809947Z 511c12f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Desktop PR regression failed on commit 511c12f2101ee451e7aa5139bdaf99e8ad8243d1.

Recordings not attached

  • Run evidence: failure-index.json is missing

The Actions artifact retains the complete trace, screenshots, logs, and runtime evidence.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 511c12f210

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +520 to +524
const contextToken = getContextToken();
if (!contextToken) {
// Old managed sessions without context must not adopt the machine owner's login.
return !process.env.LODY_GITHUB_REPO_FULL_NAME;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Require a broker context before enabling local auth

A teammate-controlled command can remove LODY_GIT_CRED_CONTEXT_TOKEN and LODY_GITHUB_REPO_FULL_NAME (for example, env -u LODY_GIT_CRED_CONTEXT_TOKEN -u LODY_GITHUB_REPO_FULL_NAME gh api user), causing this branch to authorize use of the daemon owner's saved gh login. These are ordinary child environment variables and ACP terminal overrides, so their absence is not proof of a local-owner invocation; fail closed unless the broker explicitly authorizes local authentication.

AGENTS.md reference: apps/cli/AGENTS.md:L337-L339

Useful? React with 👍 / 👎.

Comment on lines +553 to +555
for (const key of tokenKeys) {
if (!env[key]) continue;
if (await hasUsableGhAuth(ghCommand, env, target.host)) return { env };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Gate inherited environment tokens by requester ownership

Session.buildShellEnv merges process.env into every ACP terminal, so a daemon launched with GH_TOKEN, GITHUB_TOKEN, or their enterprise equivalents passes the owner's ambient credential into teammate sessions. This loop accepts that token before consulting mayUseLocalAuth, allowing a requester whose broker context has allowLocalAuth: false to run gh as the daemon owner; inherited tokens must be stripped or ownership-gated before they are treated as explicit session credentials.

AGENTS.md reference: apps/cli/AGENTS.md:L334-L339

Useful? React with 👍 / 👎.

Bind managed gh wrappers to workspace brokers, fail closed without context, and remove inherited GitHub credentials from non-owner child environments. Replace ACP on requester changes while preserving active turn finalization.

Model: gpt-6
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Desktop PR regression failed on commit 383b456dd77bcbd3cedf4ead278caa090155ed38.

Recordings not attached

  • Run evidence: failure-index.json is missing

The Actions artifact retains the complete trace, screenshots, logs, and runtime evidence.

Merge current main to pick up the corrected public Codex lockfile. Read the frozen invocation requester in the cross-user steer guard and migrate stale runtime fixtures to the current identity model.

Model: gpt-6

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: efbe2d93f6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +460 to +461
if (!this.machineOwnerUserId || this.gitIdentity.id !== this.machineOwnerUserId) {
clearGitHubTokenEnv(agentEnv);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Stop startup files from restoring owner GitHub tokens

Fresh evidence after the earlier inherited-environment finding: this scrubs only the environment passed to the process, but the generated BASH_ENV and ZDOTDIR files subsequently source the owner's original startup files (lody-bashenv.ts:20-22 and lody-zdotdir.ts:34-36,56-58). When one of those files exports a GitHub token—especially ~/.zshenv on macOS—a teammate-owned ACP can launch bash/zsh and read or use the restored token directly, bypassing the gh shim and broker authorization; non-owner startup wrappers must not reintroduce these variables.

AGENTS.md reference: apps/cli/AGENTS.md:L342-L347

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant