Where does the bug appear (feature/product)?
Cursor IDE
Describe the Bug
Cursor IDE foreground agent — Shell tool blocks api.github.com and the documented required_permissions: ["all"] escape hatch is not reachable
Summary
In a foreground (in-IDE) Cursor agent session, the Shell tool runs every
command inside a network-allowlist sandbox that blocks outbound HTTPS to
api.github.com (synthetic 403 returned with Content-Type: text/plain).
The sandbox footer printed under every Shell result tells the agent it can
escape the sandbox by passing required_permissions: ["all"]:
SANDBOXING: This command ran in a sandbox with the following restrictions:
- Filesystem: Write access limited to the workspace directory, read access to the rest of the filesystem
- Network access: Limited (allowlist only)
If you think the command failed due to sandbox restrictions, re-run with the required_permissions that you need (such as [“full_network”]) or use required_permissions: [“all”] to run outside the sandbox entirely. Don’t needlessly ask for permission.
But the foreground agent’s Shell tool JSON Schema does not declare
required_permissions as a parameter. The harness validates against the
declared schema, so any attempt to include the field is silently stripped
before reaching the runtime, and every retry stays sandboxed.
This produces a confusing failure mode where:
gh auth statusreports “The token in keyring is invalid” (because
ghmakes aGET /usercall to verify the token, the sandbox returns
a 403, andghinterprets that as auth rejection).- The agent reasonably concludes the user’s
ghtoken is dead and asks
them to re-authenticate. - The user (correctly) demonstrates
ghworks fine in their own terminal. - Both the agent and the user lose ~30 minutes diagnosing a fictional
“keyring ACL” problem before realizing the failure is sandbox network
policy, not auth.
The most striking part: other agents in the same Cursor app, same
machine, same user, same token, work without issue. Background/Cloud
Agents have their own VM with its own allowlist. The “repo agents” or
Composer agents the user works with elsewhere apparently get a Shell tool
schema that does declare required_permissions (because they routinely
run gh pr edit, gh api, etc. against private repos without trouble).
The foreground agent that I am does not.
Environment
| Field | Value |
|---|---|
| Cursor app version | 3.6.31 (build 3.6.31) |
| macOS | 26.5 (build 25F71) |
| Architecture | arm64 |
gh version |
2.83.1 (2025-11-13) |
gh auth |
Valid, stored in macOS Keychain via gh:github.com keyring entry |
| Agent model | Claude Opus 4.7 (foreground / in-IDE agent, “Agent” mode) |
Repro
This happened in a real working session over several hours. Easy to
reproduce in any foreground Cursor agent session:
-
Open a workspace in a private GitHub repo.
-
Confirm
gh auth statusworks in your terminal (it does):$ gh auth status github.com ✓ Logged in to github.com account <user> (keyring) - Active account: true - Git operations protocol: https - Token: gho_*** - Token scopes: 'gist', 'read:org', 'repo', 'workflow' -
Ask the agent to do anything that requires the GitHub API (e.g.
“open a PR for this branch” or “post a comment on PR #N”). -
Watch the agent attempt
gh pr create/gh pr comment/gh api,
then see:X Failed to log in to github.com account <user> (keyring) - The token in keyring is invalid.or:
Post "https://api.github.com/graphql": Forbidden -
Direct verification that the issue is sandbox, not auth:
$ curl -sI -H "Authorization: token $(security find-generic-password \ -s 'gh:github.com' -a '<user>' -w \ | sed 's/go-keyring-base64://' | base64 -d)" \ https://api.github.com/user HTTP/1.1 403 Forbidden content-type: text/plain content-length: 92GitHub’s real auth-rejection responses are JSON (
{"message": "Bad credentials", ...}). A plaintext 403 withcontent-length: 92is the
sandbox interceptor. The samecurlin the user’s own terminal
succeeds with a 200 + JSON body. -
The agent attempts to follow the sandbox footer’s instructions and
passrequired_permissions: ["all"]to the Shell tool, but the
field is not declared in the agent’s visible Shell schema and gets
stripped by harness validation. Every retry remains sandboxed.
Expected behavior
One of the following:
- (Preferred) The foreground agent’s Shell tool schema declares
required_permissionsso the documented escape hatch actually works.
Thengh/curl/ any HTTPS call toapi.github.comsucceeds with
the user’s existing credentials. - (Alternative)
api.github.comis added to the default network
allowlist so foreground agents can useghagainst private repos
without escalation. (Background Agents and Composer / repo agents
apparently already have this — parity would be the cheapest fix.) - (Alternative) The sandbox footer text is updated to NOT advertise
required_permissions: ["all"]to agents that don’t actually have
access to that parameter, so the agent doesn’t waste cycles
attempting an impossible workaround and the user doesn’t get told
three different incorrect diagnoses before the agent realizes the
doc is lying to it.
Actual behavior
The sandbox footer advertises an escape hatch the foreground agent
cannot reach, gh API calls fail with a misleading “invalid token”
error, the agent over-confidently mis-diagnoses the failure as a
keyring/ACL/auth-token-rotation problem, and the user has to either
manually copy-paste content into the GitHub web UI or spin up a
separate agent session to do the GitHub work.
Workarounds in use today
- Hand the GitHub task to a separate “repo agent” session that has
the right Shell schema. Works, but adds cross-session coordination
overhead — the parent agent has to write a self-contained prompt
with all required context (PR number, file paths, full comment
bodies, etc.) because the new agent can’t see the parent’s
conversation. We’ve been doing this for ~10 GitHub operations on a
single Jira ticket over the past week. It works but turns ~30
secondgh pr commentcalls into ~5 minute prompt-handoff cycles. cursor-ide-browserMCP for UI-shaped actions (edit PR
description, post comment by clicking through the page). Works but
slower per action; useful as fallback.- User runs the
ghcommand themselves from their terminal.
Works, but defeats the point of having an agent.
Impact
For workflows that touch GitHub at all — reviewing PR comments,
editing PR descriptions, opening companion PRs across repos, posting
review replies, checking CI status, updating labels — the foreground
agent is effectively useless and has to delegate every step.
Suggested fix priority
If only one thing can change: expose required_permissions in the
foreground agent’s Shell schema, OR remove that field from the
sandbox footer documentation if it’s never going to be available.
Either eliminates the confusion loop. Best fix: do both, plus
allowlist api.github.com by default — gh is the canonical way
agents interact with GitHub and the current behavior makes that path
unusable.
Steps to Reproduce
Ask the foreground agent to run each of these via its Shell tool, one
at a time, in the open workspace. Substitute any private repo you have
read access to for <org>/<private-repo>.
Step 1 — gh REST endpoint, hits api.github.com:
gh api repos/<org>/<private-repo>
Expected (in a real terminal): JSON body describing the repo.
Actual (inside the foreground agent’s Shell):
Get "https://api.github.com/repos/<org>/<private-repo>": Forbidden
Step 2 — gh GraphQL endpoint, also hits api.github.com:
gh repo view <org>/<private-repo> --json url,description
Actual:
Post "https://api.github.com/graphql": Forbidden
Step 3 — raw curl to api.github.com with a known-good token,
bypassing gh entirely:
TOK=$(security find-generic-password -s 'gh:github.com' -a '<user>' -w \
| sed 's/go-keyring-base64://' | base64 -d)
curl -sI -H "Authorization: token $TOK" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/<org>/<private-repo>
Actual:
HTTP/1.1 403 Forbidden
content-type: text/plain
content-length: 92
This is the sandbox interceptor, not GitHub. Real GitHub
auth-rejection responses are Content-Type: application/json with a
{"message": "Bad credentials", ...} body. A plaintext 403 with
content-length: 92 and no X-GitHub-Request-Id header is the
sandbox synthesizing the response before the request leaves the host.
Step 4 — same private repo, but via github.com (git protocol) instead
of api.github.com:
git ls-remote --heads https://github.com/<org>/<private-repo>.git develop
Actual:
3c5e26243731528223652cc7cc72c7d4dc8ed4dd refs/heads/develop
exit=0
Works. Same host family, same auth, different subdomain.
Step 5 — read an arbitrary file from that same private repo, again
via git protocol:
cd <any-existing-git-repo-in-workspace>
git fetch https://github.com/<org>/<private-repo>.git develop --depth 1
git show FETCH_HEAD:<path/to/any/file>
Actual: file contents printed to stdout. Works.
Expected Behavior
cursor ide in agents view can execute the same gh commands as cursor in the repo view.
Worth mentioning that I need to be connected to a VPN to access github. I am connected all the time but seems like there are different permissions for network in the agents view vs the repo window.
Screenshots / Screen Recordings
Operating System
MacOS
Version Information
Version: 3.6.31 (Universal)
VS Code Extension API: 1.105.1
Commit: 81fcf2931d7687b4ff3f3017858d0c6dee7e2a60
Date: 2026-05-31T17:46:29.630Z
Layout: glass
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
xterm.js: 6.1.0-beta.220
OS: Darwin arm64 25.5.0
Additional Information
I use a vpn to connect to github
Does this stop you from using Cursor
No - Cursor works, but with this issue
