feat(auth): separate environment administration permissions - #9786
feat(auth): separate environment administration permissions#9786juliusmarminge wants to merge 8 commits into
Conversation
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 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.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Bugbot Autofix is ON, but a cloud agent failed to start.
Reviewed by Cursor Bugbot for commit ee2b738. Configure here.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This is a broad, auth-sensitive permission redesign that changes default pairing grants and authorization for settings, providers, maintenance, access, relay, and process operations across server, web, and mobile. It also carries unresolved keybinding correctness risks, including a stale-edit rejection scenario and incomplete duplicate-rule removal. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
ee2b738 to
5a020b3
Compare
25f5cbd to
5f1623b
Compare
| } | ||
| if (previousTarget) { | ||
| return mapAtomCommandResult( | ||
| await removeKeybinding({ environmentId, input: previousTarget }), |
There was a problem hiding this comment.
🟡 Medium components/ChatView.tsx:3599
Deleting a script removes only one shortcut rule, so duplicate bindings for the same command remain persisted and still dispatch the deleted script's command. previousTarget represents only the last match returned by keybindingValueForCommand; enumerate and remove every persisted rule for input.keybindingCommand instead.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/ChatView.tsx around line 3599:
Deleting a script removes only one shortcut rule, so duplicate bindings for the same command remain persisted and still dispatch the deleted script's command. `previousTarget` represents only the last match returned by `keybindingValueForCommand`; enumerate and remove every persisted rule for `input.keybindingCommand` instead.
| input.keybinding !== undefined && | ||
| (input.keybinding?.trim() || null) !== previousKeybinding && | ||
| (!isDeletingScript || readEnvironmentScope(environmentId, AuthSettingsWriteScope)); |
There was a problem hiding this comment.
🟠 High components/ChatView.tsx:3542
Editing a script without AuthSettingsWriteScope is rejected as an unauthorized keybinding change when another client changes the shortcut after the dialog opens, even though the user never edited the disabled keybinding field. changesKeybinding compares the stale dialog value with the current previousKeybinding; gate this detection on keybinding write access (while preserving the existing script update).
const changesKeybinding =
isElectron &&
+ readEnvironmentScope(environmentId, AuthSettingsWriteScope) &&
input.keybinding !== undefined &&🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/ChatView.tsx around lines 3542-3544:
Editing a script without `AuthSettingsWriteScope` is rejected as an unauthorized keybinding change when another client changes the shortcut after the dialog opens, even though the user never edited the disabled keybinding field. `changesKeybinding` compares the stale dialog value with the current `previousKeybinding`; gate this detection on keybinding write access (while preserving the existing script update).

Provider setup, settings changes and server maintenance all shared
orchestration:operate. Parts of Connections also required access administration to configure an environment. A workspace operator could not be granted these capabilities independently.Adds three scopes:
settings:writefor environment settings and keybindings.providers:managefor provider configuration, sign-in, installation, updates and reset credits.environment:maintainfor server updates, process signals, resource collector recovery and host power controls.Settings patches require permission for every domain they change, including
settings:writefor model pricing overrides. Web, desktop and mobile use the selected environment's grant for controls and check it again before writes. Shared settings sync includes only writable environments. Access and relay administration remain separate, and local preferences stay editable.New Standard and Administrative grants include these scopes. Existing paired clients keep their grants and must pair again to receive the new permissions. Reconnecting does not expand access.
Validation: 93 focused web tests and the mobile TypeScript check passed. Targeted formatting and diff checks passed. RPC tests cover individual settings/provider grants, mixed patches and denied maintenance actions.
Pairing controls, captured from this layer’s base and head with the same viewport and default selection:
Model: GPT-6. Harness: Codex.
Note
Add
settings:write,providers:manage, andenvironment:maintainenvironment scopesorchestration:operatepermission into three dedicated environment scopes across contracts, server RPC authorization, and both web/mobile clients.providers:manage, server updates/telemetry retry/process signaling/host power toenvironment:maintain, and keybinding/settings updates tosettings:write.requiredScopesForServerSettingsPatchin settings.ts so mixed server-settings patches can require bothsettings:writeandproviders:managedepending on the fields present.useEnvironmentScope/readEnvironmentScopehelpers before enabling controls and dispatching commands; unauthorized controls are disabled or inert.ServerUpdateActionchecks a new advertisedserverUpdateScopeon the auth descriptor, falling back toorchestration:operatefor older servers.orchestration:operatewill not have the new scopes; users must re-pair to receivesettings:write,providers:manage, andenvironment:maintain. Older servers withoutauth.serverUpdateScopestill fall back toorchestration:operatefor server updates.Macroscope summarized 5f1623b.
Note
High Risk
Authorization behavior changes across RPC, HTTP, and all clients; legacy grants will lose access to formerly bundled operations until re-paired with new scopes.
Overview
Splits what used to ride on
orchestration:operateintosettings:write,providers:manage, andenvironment:maintain. The server maps RPCs and HTTP token scopes to these grants,serverUpdateSettingschecksrequiredScopesForServerSettingsPatchso mixed patches need every domain they touch, and the auth descriptor advertisesserverUpdateScopefor self-update.Web, mobile, and desktop clients drop implicit admin bypasses in favor of
useEnvironmentScope/readEnvironmentScope, with controls disabled and writes re-checked before mutations. Notable UX: read-only sessions can still view settings (auto-settle on mobile, T3 Connect when relay read is missing), pairing only offers scopes the current grant can delegate, and provider/server maintenance actions show explicit “cannot manage” messaging.Existing paired clients keep their old scope sets until they pair again;
orchestration:operatealone no longer covers settings, providers, or maintenance.Reviewed by Cursor Bugbot for commit 5f1623b. Bugbot is set up for automated code reviews on this repo. Configure here.