Scheduled automations cannot access GitHub API in default sandbox despite allowlisted gh api and loaded token

Resolved 💬 6 comments Opened Feb 26, 2026 by codingscape-jay Closed Jun 22, 2026

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

Version 26.224.1209 (697)

What subscription do you have?

Plus

What platform is your computer?

macOS arm

What issue are you seeing?

Summary

Scheduled automation runs appear to enforce network denial regardless of .env token loading and default.rules allowlists. The same commands succeed only when execution is elevated/unrestricted.

Impact

GitHub-dependent scheduled automations (PR review/reporting workflows) are non-functional in default scheduled runtime.

Suspected cause

Scheduler/runtime policy mismatch:

  • allowlist rules and env loading are present
  • but network egress remains blocked in default scheduled execution.

What steps can reproduce the bug?

  1. Configure:
  • ~/.codex/.env with GH_TOKEN, GITHUB_TOKEN, GH_HOST=github.com
  • ~/.codex/rules/default.rules with:
  • prefix_rule(pattern=["gh","api"], decision="allow")
  1. Run scheduled automation (default permissions) with:
  • echo "CODEX_SANDBOX_NETWORK_DISABLED=$CODEX_SANDBOX_NETWORK_DISABLED"
  • [ -n "$GH_TOKEN" ] && echo "GH_TOKEN=set" || echo "GH_TOKEN=missing"
  • gh api /user --jq '.login'
  1. Observe API failure.
  2. In same run:
  • source ~/.codex/.env
  • gh api /user --jq '.login'
  1. Observe API still fails.
  2. Re-run same commands under elevated/unrestricted execution.
  3. Observe API succeeds.

What is the expected behavior?

Per docs, automations run with default sandbox settings and allowlisted commands can run outside sandbox.

Given:

  • prefix_rule(pattern=["gh","api"], decision="allow")
  • GH_TOKEN provided via ~/.codex/.env

The automation should be able to execute gh api /user successfully.

Additional information

Actual behavior

In scheduled/default context:

  • CODEX_SANDBOX_NETWORK_DISABLED=1
  • GH_TOKEN=missing
  • gh api /user --jq '.login' fails with:
  • error connecting to api.github.com
  • check your internet connection or https://githubstatus.com

Even after explicitly sourcing env in-shell:

  • source ~/.codex/.env
  • GH_TOKEN=set
  • CODEX_SANDBOX_NETWORK_DISABLED=0 (shell var)
  • gh api /user still fails with the same connectivity error

In elevated/unrestricted context, the exact same gh commands succeed.

View original on GitHub ↗

6 Comments

louspringer · 4 months ago

Additional confirmed repro + root-cause signal from today (2026-02-27, macOS 26.3, Codex desktop 26.226.940, CLI 0.105.0).

I forced an immediate run of automation eudorus-control-tower and captured both automation and host-shell evidence:

  1. New automation run thread created: 019ca111-20ba-7a23-af42-9dd0b48156af
  2. Run result: PENDING_REVIEW with inbox title GitHub preflight now network-blocked
  3. In the same wall-clock window, host shell succeeds:
  • gh api user --jq .login -> louspringer
  • GIT_TERMINAL_PROMPT=0 git ls-remote https://github.com/energration/eudorus.git HEAD -> HEAD resolves
  1. Local state DB for that automation thread shows sandbox policy includes "network_access":false:
  • threads.id=019ca111-20ba-7a23-af42-9dd0b48156af
  • sandbox_policy={...,"network_access":false,...}

This strongly indicates automation runtime policy is forcing network off (or misapplying policy) even when host session has healthy GitHub connectivity and auth.

If useful, I also added a deterministic preflight script in the automation (gh auth status, gh api user, git ls-remote) specifically to avoid false token-vs-DNS attribution.

moreaki · 4 months ago

I can reproduce this in Codex Desktop on macOS, and I have stronger local evidence that the failure is caused by the automation runner starting with a different sandbox/network policy than an interactive chat session.

What I verified just now:

  • In a live interactive Codex session, GitHub access works normally.
  • gh auth status shows I am logged into github.com with a valid token (repo scope present).
  • gh api repos/mangerlahn/Latest --jq '{full_name, default_branch, open_issues_count}' succeeds.

What the scheduled automation runs show:

  • The automation is Watch Latest Upstream.
  • Its config only sets execution_environment = "worktree" in ~/.codex/automations/watch-latest-upstream/automation.toml.
  • The archived rollout JSONL for scheduled runs shows the developer-injected permission block starts with:
  • sandbox_mode = workspace-write
  • Network access is restricted
  • In those same rollout sessions, shell commands to GitHub fail with DNS errors:
  • curl: (6) Could not resolve host: api.github.com
  • curl: (6) Could not resolve host: github.com

Affected rollout files on my machine:

  • rollout-2026-03-16T14-36-01-019cf6dc-59bd-7480-adfc-79b51ec59331.jsonl
  • rollout-2026-03-16T15-36-20-019cf713-91fa-79a2-b3a4-53783dec93a8.jsonl
  • rollout-2026-03-16T17-36-23-019cf781-7974-7a50-8d83-d52648551db0.jsonl

Important distinction:

  • This is not just “gh token missing” or “GitHub API flaky”.
  • In the interactive chat environment, gh works immediately.
  • In the automation rollout environment, the session itself is launched with restricted networking, and DNS to GitHub fails before auth even matters.

So the bug appears to be:

  • scheduled/background automation runs are not inheriting the same effective network policy as interactive Codex sessions
  • or automations are being hard-forced into a workspace-write + network-disabled policy regardless of live app capabilities/config

Impact:

  • GitHub-dependent automations are effectively unusable unless they fall back to the web tool or the user manually re-enters the thread in a context with different permissions.
  • This breaks unattended monitoring/reporting workflows that depend on gh.

If useful, I can attach sanitized excerpts from the rollout JSONL showing:

  1. the initial developer permissions block with Network access is restricted
  2. the later command failures resolving api.github.com
  3. the same machine/session successfully reaching GitHub with gh api outside the scheduled automation rollout
moreaki · 4 months ago

I investigated this locally and have a concrete root-cause hypothesis plus a small fix.

Root cause hypothesis

Trusted execpolicy matches already get classified as ExecApprovalRequirement::Skip { bypass_sandbox: true, .. }, but the first exec attempt only converts that into SandboxType::None.

The same first attempt still inherits the turn's network_sandbox_policy, so in scheduled/default runs an allowlisted command like gh api is launched without network access even though execpolicy marked it as trusted.

That matches the report here:

  • allowlist is present for gh api
  • credentials may be available after loading env
  • the command still fails until rerun in an unrestricted context

Proposed fix

Treat trusted execpolicy skips differently from ordinary explicit escalation:

  • keep default first-attempt behavior unchanged
  • keep with_escalated_permissions behavior unchanged except for sandbox bypass
  • when execpolicy returns Skip { bypass_sandbox: true }, bypass the first-attempt sandbox and force NetworkSandboxPolicy::Enabled

In practice this is a small orchestrator change:

  • add a distinct sandbox override variant for trusted execpolicy commands
  • derive both the initial sandbox and the initial network policy for the first attempt
  • only enable network for the trusted-execpolicy case above

Validation

I tested this locally with targeted unit coverage for:

  • default behavior
  • explicit escalation preserving the existing network policy
  • trusted execpolicy commands enabling network on the first attempt

I also ran:

  • just fmt
  • cargo test -p codex-core

The new tests passed. In my environment, cargo test -p codex-core still has three unrelated existing failures:

  • seatbelt::tests::create_seatbelt_args_with_read_only_git_pointer_file
  • seatbelt::tests::create_seatbelt_args_with_read_only_git_and_codex_subpaths
  • shell_snapshot::tests::snapshot_shell_does_not_inherit_stdin

If helpful, I have the patch prepared on my fork and can open it if a maintainer wants a PR.

Rahulkumar-G · 3 months ago

+1

JHenzi · 3 months ago

Please fix this. I have codex designing it's own automations using CURL right now - they will fail.

Keesan12 · 2 months ago

This is a classic browser-auth vs runtime-auth style mismatch, except here it is scheduler policy vs shell policy. The useful receipt would be explicit at automation start: env loaded yes or no, network egress allowed yes or no, allowlist rule matched yes or no, and which layer denied the call. Right now users do the detective work after the failure. That kind of preflight receipt is exactly what keeps automation loops from burning time on impossible work.