Skip to content

feat(auth): separate filesystem read and write permissions - #9788

Open
juliusmarminge wants to merge 18 commits into
t3code/auth-source-control-scopefrom
t3code/auth-filesystem-scopes
Open

feat(auth): separate filesystem read and write permissions#9788
juliusmarminge wants to merge 18 commits into
t3code/auth-source-control-scopefrom
t3code/auth-filesystem-scopes

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 4, 2026

Copy link
Copy Markdown
Member

Direct workspace reads and edits currently share task permissions, while viewing local diffs requires review:write. Add filesystem:read for browsing, searching, file previews, and local diffs, and filesystem:write for file edits and saving plans. Both scopes remain in the Standard preset so narrower credentials can opt out of direct filesystem access.

Host workspace/media asset URLs require filesystem read permission when minted; attachments and project artwork retain their existing authorization. Web, desktop, and mobile controls follow each environment's grant. Losing write access stops pending autosaves and preserves unsaved drafts across closing and reopening the preview; an older editor's completed write cannot clear a newer draft's pending marker. Draft retention is released after confirmation or explicit clearing.

Retire review:write from new grants and the permission picker while keeping old credentials decodable. Existing connections must be paired again to receive filesystem scopes. These scopes govern direct client actions; they do not sandbox provider processes or terminal commands.

Validation: 17 filesystem access/browse tests, draft-retention regressions, and web/mobile typechecks pass. Offline file views distinguish connection failure from a pending permission check.

Pairing controls, captured from this layer’s base and head with the same viewport and default selection:

Before After
Before: pairing permissions After: filesystem permissions

Model: GPT-6. Harness: Codex.


Note

High Risk
Changes authentication scopes and RPC authorization for filesystem and review diff paths; existing clients without new grants lose file and local-diff access until re-paired.

Overview
Introduces filesystem:read and filesystem:write as distinct OAuth grants and wires clients and the server to honor them before touching host files, local diffs, or workspace assets.

Server: Project list/read/search, filesystem browse, and review diff RPCs now require filesystem:read; projects.writeFile requires filesystem:write. Host workspace-file / media-file asset URL minting requires read scope; attachments stay on orchestration read. Token exchange accepts AuthGrantScope (drops review:write from new grants while still decoding legacy credentials). Pairing UI and docs describe read/write files instead of write reviews.

Clients (web, mobile, shared runtime): resolveFilesystemReadAccess centralizes pending/denied/offline behavior. File trees, previews, path search, review git sections, composer t3.json reads, and asset hooks skip RPCs without read scope and show explicit empty/loading states. Write scope gates plan saves, browse preload, and autosave; losing write keeps unsaved drafts across close/reopen via FileSaveCoordinator / optimistic query retention.

Breaking: Connections with only orchestration:read or review:write no longer get direct file or local-diff access until re-paired with filesystem scopes.

Reviewed by Cursor Bugbot for commit 175e73b. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add filesystem:read and filesystem:write as separate OAuth scopes

  • Introduces filesystem:read and filesystem:write in auth.ts, removes review:write from grant validation and standard client defaults while keeping it decodable for legacy credentials
  • Server RPC authorization in RpcAuthorization.ts and ws.ts now requires filesystem:read for project file reads, entry searches, diff retrieval, and host-file asset URLs, and filesystem:write for project file writes; threaded worktree pull-request preparation additionally requires orchestration:operate
  • Web and mobile clients gate file browsing, file content queries, composer path search, file previews, asset URL resolution, and plan-to-workspace saving behind a new resolveFilesystemReadAccess resolver that waits for session and catalog readiness before granting access
  • FileSaveCoordinator and project-file query state retain unsaved drafts while write access is unavailable and persist them once access returns, with confirmation logic that prevents stale writes from overwriting newer drafts
  • Pairing dialogs in ConnectionsSettings.tsx and CLI auth scope flags now offer filesystem read/write grants; the Read-only preset requests both orchestration:read and filesystem:read
  • Risk: review:write is removed from AuthGrantScopes and AuthStandardClientScopes — existing pairing credentials or clients relying on that scope for file access will no longer validate; the AuthEnvironmentScopes decoder still accepts it for backward compatibility

Macroscope summarized 175e73b.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.6 KiB 15.1 KiB
Codex Thread snapshot wire 7.0 KiB 7.3 KiB
Codex Live turn WebSocket wire 6.6 KiB 7.8 KiB
Codex Live turn WebSocket decoded 57.1 KiB 66.4 KiB
Codex Live turn messages 10 21
Claude Total thread wire 13.6 KiB 15.1 KiB
Claude Thread snapshot wire 7.0 KiB 7.3 KiB
Claude Live turn WebSocket wire 6.5 KiB 7.8 KiB
Claude Live turn WebSocket decoded 57.8 KiB 66.4 KiB
Claude Live turn messages 9 21

Baseline: unavailable · PR result: 3a2bc88 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Comment thread apps/mobile/src/features/review/useReviewSections.ts
@juliusmarminge juliusmarminge changed the title t3code/auth filesystem scopes feat(auth): separate filesystem read and write permissions Sep 4, 2026
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from c80d93e to 3b96a67 Compare September 4, 2026 21:18
@juliusmarminge
juliusmarminge marked this pull request as ready for review September 4, 2026 21:20
Comment thread apps/web/src/assets/assetUrls.ts Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx
@macroscopeapp

macroscopeapp Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR is a broad authorization redesign that changes server scope enforcement, default client permissions, and existing filesystem workflows across mobile and web. An unresolved high-severity finding also identifies a native folder-picker path that remains available without filesystem read authorization.

Not approved because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from 3b96a67 to fb4489d Compare September 4, 2026 21:36
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from fb4489d to d7df773 Compare September 4, 2026 21:38
Comment thread apps/web/src/components/DiffPanel.tsx
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from bfb151c to eec5dfb Compare September 4, 2026 21:48
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Sep 4, 2026
Comment thread apps/web/src/components/files/FilePreviewPanel.tsx

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread packages/client-runtime/src/state/filesystem.ts
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from 38e8814 to 4b73b2d Compare September 4, 2026 22:59

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread apps/mobile/src/features/projects/AddProjectScreen.tsx Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from 4b73b2d to bef54b1 Compare September 4, 2026 23:52

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread apps/web/src/assets/assetUrls.ts Outdated
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from bef54b1 to c1d166f Compare September 5, 2026 00:08
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from c1d166f to 65d58c9 Compare September 5, 2026 00:10

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but a cloud agent failed to start.

Reviewed by Cursor Bugbot for commit 65d58c9. Configure here.

Comment thread apps/mobile/src/features/review/useReviewSections.ts Outdated
@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from 65d58c9 to 3a2bc88 Compare September 5, 2026 00:24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High

(browseEnvironmentId === primaryEnvironmentId ||

Users without AuthFilesystemReadScope can still open the native folder picker and add a selected path, bypassing the canBrowseFiles gate. Include canBrowseFiles in canOpenProjectFromFileManager so the picker is unavailable without filesystem:read.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/CommandPalette.tsx around line 2277:

Users without `AuthFilesystemReadScope` can still open the native folder picker and add a selected path, bypassing the `canBrowseFiles` gate. Include `canBrowseFiles` in `canOpenProjectFromFileManager` so the picker is unavailable without `filesystem:read`.

@juliusmarminge
juliusmarminge force-pushed the t3code/auth-filesystem-scopes branch from 3a2bc88 to 175e73b Compare September 5, 2026 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). 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.

1 participant