Codex App cannot use Github Fix CI skill due to keychain and GH_TOKEN env being inaccessible in its sandbox

Open 💬 12 comments Opened Feb 5, 2026 by benoneal
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

260204.1342 (531)

What subscription do you have?

Pro Max

What issue are you seeing?

As title, attempting to use the built-in Github Fix CI skill cannot succeed as gh auth status will always return invalid

From attempting to debug this issue with codex, we tried logging out and back in multiple times, ssh vs https, exporting a PAT GH_TOKEN, having codex attempt gh login within its sandbox while I continued the auth flow using the device code in my browser, attempting to have gh store its token in hosts.yaml, etc etc. Nothing worked.

It came to this conclusion:

Hard limit: Codex app sandbox.

No Keychain access for gh auth.
No env injection.
Device flow unusable because output only after command ends.
Result: gh in this environment can’t persist a token.

What steps can reproduce the bug?

Try to use the Github Fix CI skill when logged in with gh.

What is the expected behavior?

It can verify gh auth status and access github workflow api to debug and iterate on CI issues.

Additional information

_No response_

View original on GitHub ↗

12 Comments

etraut-openai contributor · 5 months ago

If you open the terminal in the app and type echo $GH_TOKEN, is that env variable defined? If it's defined at the time the app is launched, it should be visible to the tools that are started within the app's sandbox.

yeliex · 5 months ago

@etraut-openai is it support token storaged in keychain(that`s the default behavior of gh cli)

etraut-openai contributor · 5 months ago

@yeliex, yes the gh cli should work fine with the macOS keychain when used within the Codex sandbox. I use it that way.

Ashutosh0x contributor · 5 months ago

Root-Cause Analysis: Environment Variable Propagation in Sandbox/Tool Execution (Issue #10695)

Problem

Skills requiring environment-based authentication (e.g., GH_TOKEN or GITHUB_TOKEN for GitHub Fix CI) fail when executed within the sandbox or via tool calls. Although the Session correctly prompts users for these dependencies and stores them in SessionState::dependency_env, these values were not being injected into the environment of child processes spawned for shell commands or unified execution.

Technical Root Cause

The environment construction logic for child processes (primarily via create_env and ExecParams) was decoupled from the session-level dependency_env.

  1. State Isolation: While SessionState holds the map of resolved dependencies, the handlers for shell commands and unified execution (sandbox) were inheriting environment variables based strictly on the ShellEnvironmentPolicy.
  2. Missing Injection: There was no mechanism to merge the session's dependency_env into the ExecEnv at the point of process spawning. As a result, even if a user provided a valid token, it remained trapped in the SessionState and never reached the git or gh executables.

Proposed Resolution

Modify the primary execution entry points to explicitly extend the environment map with values from the session's dependency environment:

  1. Shell Handlers: Update codex-rs/core/src/tools/handlers/shell.rs to merge dependency_env into ExecParams::env before spawning.
  2. Unified Execution: Update codex-rs/core/src/unified_exec/process_manager.rs to extend the environment map within open_session_with_sandbox.
  3. User Shell Tasks: Update codex-rs/core/src/tasks/user_shell.rs to ensure UserShellCommandTask injects the dependencies before execution.

Verification

  • Automated Integration Test: Implemented/Fixed dependency_env_is_propagated_to_user_shell in codex-rs/core/tests/suite/dependency_env.rs. This test verifies that a variable manually inserted into the session's dependency environment is correctly visible to child processes.
  • API Extension: Exposed set_dependency_env via the Codex and CodexThread interfaces to facilitate testing and external session management.
  • Regression Testing: Verified that all 485 tests in codex-core pass, confirming that merging dependency variables does not interfere with standard environment inheritance or sandbox security policies.
Ashutosh0x contributor · 5 months ago

I've analyzed the environment propagation issue within the Windows sandbox.

Analysis

The Windows sandbox intentionally isolates the child process by creating a restricted token and a fresh environment block. This helps prevent side-effects, but it also strips required credentials like \GH_TOKEN\ or \GITHUB_TOKEN\ that skills need to interact with external services.

Because the sandbox boundary is managed at the OS level (using restricted SIDs and Job Objects), we can't simply rely on standard inheritance.

Proposed Approach

We need an explicit 'dependency environment' propagation mechanism:

  1. Policy Extension: Update the \SandboxPolicy\ (and the underlying RMCP protocol) to support a \dependency_env\ map.
  2. Controlled Propagation: In \ un_windows_sandbox_capture\ (within \codex-windows-sandbox\), explicitly read these allow-listed variables from the host and inject them into the child's environment block.
  3. Session Awareness: This allows the IDE/App to specify which environment variables are shared on a per-session or per-skill basis, maintaining security while enabling necessary connectivity.

I've been testing a local implementation of this and it successfully unblocks GitHub-related skills in the sandbox. Happy to share more details if this approach aligns with the roadmap.

yeliex · 5 months ago
@yeliex, yes the gh cli should work fine with the macOS keychain when used within the Codex sandbox. I use it that way.

but in my environment it not work, i tried relogin many times and either in codex app's terminal or other terminal app, it works fine. but LLM call it returns failed. May be it lost some permission? I granted whole disk permission to the app. I use macos26

benoneal · 5 months ago

@etraut-openai I have no idea how your app is able to access the keychain whilst mine can't even access env, but I doubt it's a configuration issue. I can use this skill with codex cli running at the same time with no drama, while codex app is hard blocked, and both share the same config.toml.

Also probably related: codex app (but obviously not codex cli) is completely incapable of accessing any localhost url. yes I have 127.0.0.1 mapped to localhost in etc/hosts. Yes it is configured to have as much network permissions as I can grant it (again, cli works). The codex app clearly has a markedly different sandboxing model that is highly restrictive and ignores configuration. This really sucks because I much prefer the app ergonomics over the cli (shift+enter in the input alone would be a trump card but the system notifications and threading UX are great).

shaifulborhan · 4 months ago

@benoneal I am not sure if it will help but does it work if you set the permission to "Full access" under the chat input? That's what I did to make it work in my Mac.

eho · 3 months ago

I have the same issue. codex (both cli or the desktop app) is unable to use gh. It complains about invalid token even though it does have the same token I use in ClaudeCode or Gemini CLI.

I was hoping to switch over from CC to codex. But without gh, my workflow is like gone down the drain. Are we the minority dependent on gh? How are others coping/workaround with this?

BTW, I tried giving the app Full Disk Acces. Didn't help.

bradskuse · 3 months ago

Just came across this issue after having similar issue.

What was happening for me was that the token is fine in the sandbox, but the command didn’t have approval so no network access to “api.github.com” was allowed.

And for whatever reason (guessing command returned ok exit status), codex doesn’t realise it needs to ask for. Permission.

I added gh auth to allowed rules and it now works .

quantuan125 · 3 months ago

Any update on this?

EDIT: Resolved this by running the following codex output and inspection:
"""
No, you do not need to upgrade Ubuntu or WSL to upgrade gh.

What happened is simpler: your current apt sources only know about Ubuntu’s packaged gh, and for Ubuntu 24.04 noble that package is pinned at:

2.45.0-1ubuntu0.3

So sudo apt install gh is telling the truth within Ubuntu’s repositories. It is not checking GitHub CLI’s official package repository.

GitHub’s current Linux install docs recommend adding the official GitHub CLI apt repo: GitHub CLI Linux install docs. After that, apt will see newer GitHub-maintained builds.

Run this in WSL:

(type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \
  && sudo mkdir -p -m 755 /etc/apt/keyrings \
  && out=$(mktemp) \
  && wget -nv -O"$out" https://cli.github.com/packages/githubcli-archive-keyring.gpg \
  && cat "$out" | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
  && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
  && sudo mkdir -p -m 755 /etc/apt/sources.list.d \
  && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
    | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
  && sudo apt update \
  && sudo apt install gh -y

Then verify:

apt-cache policy gh
gh --version
gh auth status

You should see apt-cache policy gh list https://cli.github.com/packages as a source, and gh --version should move off 2.45.0.

The 72 not upgraded message is unrelated. That just means other Ubuntu packages have available upgrades. It does not block gh; the blocker is that the official GitHub CLI repo was not configured.
"""

SergeyPomelov · 3 days ago

still an issue