Skip to content

fix(server): start Claude full access without forbidden permission modes (#4927) - #2

Closed
matsvarn wants to merge 2 commits into
mainfrom
cursor/claude-bypass-policy-88f3
Closed

matsvarn wants to merge 2 commits into
mainfrom
cursor/claude-bypass-policy-88f3

Conversation

@matsvarn

@matsvarn matsvarn commented Aug 16, 2026 •

Copy link
Copy Markdown
Owner

Fixes pingdotgg#4927

What Changed

Claude startSession now resolves the same filesystem settings cascade as the SDK session (user, project, local; managed policy still loads regardless) before requesting bypassPermissions or auto.

If resolved policy forbids the requested mode, the adapter:

  • keeps the thread's requested runtime mode
  • starts Claude in the next allowed mode: Auto if only bypass is locked, Supervised if Auto is locked too
  • omits allowDangerouslySkipPermissions unless effective mode is still bypass
  • records requested vs effective mode on the session span
  • logs a warning without settings contents, paths, or credentials

Existing Full access behavior is unchanged when policy allows bypass. Auto-accept-edits and supervised keep their current mappings.

Settings resolve for isolated Claude homes temporarily sets CLAUDE_CONFIG_DIR under a mutex and always restores it, including when resolve throws.

Why

Verified root cause

On origin/main (bab4b6f02), ClaudeAdapter.startSession mapped "full-access" straight to permissionMode: "bypassPermissions" plus allowDangerouslySkipPermissions: true. It never read Claude's resolved policy. Current Claude docs say permissions.disableBypassPermissionsMode: "disable" (user settings or managed policy) forbids that mode. The adapter still sent it, so the Claude CLI/SDK rejected the session.

The first draft only remapped Full access to Auto. Claude also accepts disableAutoMode: "disable" (top-level or permissions.disableAutoMode). Sending Auto in that case is the same class of bug. Claude docs say a session that would start in Auto then starts in default / Manual instead.

Why this seam

Option Verdict
UI-only disable of Full access Rejected. Chat, compact menu, mobile sheets, command palette, and RPC can all still request the mode.
Shared server+UI policy contract Rejected for this bug. No existing provider-state field for "bypass locked", and it would expand contracts/web/mobile.
Hard error instead of Auto Weaker than the issue's working workaround. Auto already starts cleanly when it is allowed.
Server-side check in the Claude adapter Selected. One Claude-only seam, same startSession public interface, strongest policy guarantee, UI can still be added later.

Requested vs effective mode

  • Requested: session.runtimeMode stays what the client asked for (full-access or auto).
  • Effective: claude.query.permission_mode is the allowed mode (bypassPermissions, auto, or omitted for Supervised); claude.query.requested_permission_mode keeps the original mapping.
  • Plan-mode restore uses the effective base mode (auto, or default when Supervised).

Tests and commands

vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
vp run --filter t3 typecheck
vp lint apps/server/src/provider/Layers/ClaudeAdapter.ts apps/server/src/provider/Layers/ClaudeAdapter.test.ts

85 tests passed. Typecheck passed. No new lint on the changed logic. No real Claude account, credentials, or managed policy required. Policy tests inject settings fixtures. CLAUDE_CONFIG_DIR tests inject the inner SDK resolve so they observe the env swap without hitting disk or MDM.

Covered matrix: permissive + full access; bypass locked + full access → Auto; bypass and Auto locked + full access → Supervised; Auto locked + Auto runtime → Supervised; Auto locked + full access still bypass; top-level and permissions.disableAutoMode; non-"disable" policy values; settings resolution failure (fail closed to Auto); plan restore after Auto or Supervised downgrade; resolve call uses cwd + ["user","project","local"]; instance CLAUDE_CONFIG_DIR is visible during resolve and restored after success or throw.

Risk, compatibility, and rollout

  • Server-only safety backstop. Web, desktop, and mobile still offer Full access; the session no longer dies.
  • resolveSettings() is an alpha Claude Agent SDK API. We call it with the same sources as query().
  • Custom CLAUDE_CONFIG_DIR is applied around the in-process resolve call under a mutex so user settings from isolated Claude homes are visible. The SDK call itself stays interruptible; acquire/release restore the previous env.
  • Resolve failure still fail-closes to Auto (the issue author's working workaround), not Supervised.
  • No credentials or policy JSON are logged.

UI Changes

None in this draft. Composer, compact menu, and mobile still show Full access. A later change can grey it out once provider state surfaces "bypass locked".

Remaining uncertainty

  • Current Claude CLI may silently remap bypass to default in some versions rather than hard-failing. Either way, T3 must not send the forbidden request.
  • Whether Full access should snap the visible thread mode to Auto, stay as Full access, or become a hard picker error still needs a product call.
  • UI disable across web, mobile, command palette, and defaults is intentionally out of scope.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Model: Cursor Grok 4.6. Harness: Cursor cloud agent.

Status: DRAFT — NOT READY FOR REVIEW.

Open in Web Open in Cursor 

Claude full access mapped straight to bypassPermissions even when
resolved settings set disableBypassPermissionsMode to disable. Resolve
the same filesystem sources as the session and omit the forbidden
request so the session can start.

Co-authored-by: Mats Varnskühler <imMxts@users.noreply.github.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 16, 2026
Honor disableAutoMode as well as disableBypassPermissionsMode so a
locked Auto fallback does not send another forbidden mode. Swap
CLAUDE_CONFIG_DIR only around settings resolve and restore it if
resolve throws.

Co-authored-by: Mats Varnskühler <imMxts@users.noreply.github.com>
@cursor cursor Bot changed the title fix(server): start Claude full access as auto when bypass is locked (#4927) fix(server): start Claude full access without forbidden permission modes (#4927) Aug 16, 2026
@matsvarn matsvarn closed this Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Claude "full access" fails to start when bypassPermissions is disabled by policy

2 participants