Skip to content
Source
Sign inSign up
Open History to see the last commit

clientRpcPermissions.ts

108 lines5.8 KB

1import * as Schema from "effect/Schema";
2import { GitPreparePullRequestThreadInput, GitRunStackedActionInput } from "./git.ts";
3import {
4 AuthAccessWriteScope,
5 AuthEnvironmentMaintainScope,
6 AuthOrchestrationOperateScope,
7 AuthOrchestrationReadScope,
8 AuthPreviewOperateScope,
9 AuthProvidersManageScope,
10 AuthSettingsWriteScope,
11 AuthSourceControlWriteScope,
12 AuthTerminalOperateScope,
13 type AuthEnvironmentScope,
14} from "./auth.ts";
15import { ORCHESTRATION_V2_WS_METHODS } from "./orchestrationV2.ts";
16import { WS_METHODS } from "./rpc.ts";
17​
18/** Incremental client enforcement; the server still authorizes every request. */
19export const CLIENT_GUARDED_RPC_SCOPES = {
20 [WS_METHODS.providerAuthRemoveMethod]: AuthProvidersManageScope,
21 [WS_METHODS.agentSessionsImport]: AuthOrchestrationOperateScope,
22 [WS_METHODS.agentSessionsImportWithProgress]: AuthOrchestrationOperateScope,
23 [WS_METHODS.previewClose]: AuthPreviewOperateScope,
24 // Stopping a server signals its processes, as closing a terminal does.
25 [WS_METHODS.previewStopLocalServer]: AuthTerminalOperateScope,
26 [WS_METHODS.serverRunStorageCleanup]: AuthSettingsWriteScope,
27 // Restarts the server, as an update does.
28 [WS_METHODS.serverReclaimDatabaseSpace]: AuthEnvironmentMaintainScope,
29 [WS_METHODS.serverCheckOtlpEndpoint]: AuthSettingsWriteScope,
30 // Listing models spends the stored API key, so only those who can choose a model may.
31 [WS_METHODS.serverListTextGeneratorModels]: AuthSettingsWriteScope,
32 [WS_METHODS.serverRefreshProviders]: AuthOrchestrationReadScope,
33 [WS_METHODS.pullRequestsRunAction]: AuthSourceControlWriteScope,
34 [WS_METHODS.pullRequestsUpdate]: AuthSourceControlWriteScope,
35 [WS_METHODS.pullRequestsComment]: AuthSourceControlWriteScope,
36 [WS_METHODS.pullRequestsUpdateComment]: AuthSourceControlWriteScope,
37 [WS_METHODS.pullRequestsSubmitReview]: AuthSourceControlWriteScope,
38 [WS_METHODS.pullRequestsReplyToThread]: AuthSourceControlWriteScope,
39 [WS_METHODS.pullRequestsSetThreadResolution]: AuthSourceControlWriteScope,
40 [WS_METHODS.pullRequestsSetReaction]: AuthSourceControlWriteScope,
41 [WS_METHODS.pullRequestsSetFilesViewed]: AuthSourceControlWriteScope,
42 [WS_METHODS.pullRequestsRequestReviewers]: AuthSourceControlWriteScope,
43 [WS_METHODS.pullRequestsSetLabels]: AuthSourceControlWriteScope,
44 // Writing a guide runs a model on this environment's providers, which reading one does not.
45 [WS_METHODS.pullRequestsGenerateReviewGuide]: AuthOrchestrationOperateScope,
46 [WS_METHODS.projectsCreateFromThread]: AuthOrchestrationOperateScope,
47 [WS_METHODS.sourceControlCloneRepository]: AuthSourceControlWriteScope,
48 [WS_METHODS.sourceControlPublishRepository]: AuthSourceControlWriteScope,
49 [WS_METHODS.sourceControlStar]: AuthSourceControlWriteScope,
50 // Signing in replaces the server's GitHub credential, as saving a token in Settings does.
51 [WS_METHODS.sourceControlSignInStart]: AuthSettingsWriteScope,
52 [WS_METHODS.sourceControlSignInWait]: AuthSettingsWriteScope,
53 [WS_METHODS.sourceControlSignInCancel]: AuthSettingsWriteScope,
54 [WS_METHODS.projectCloneStart]: AuthSourceControlWriteScope,
55 [WS_METHODS.projectCloneCancel]: AuthSourceControlWriteScope,
56 [WS_METHODS.projectCloneRetry]: AuthSourceControlWriteScope,
57 [WS_METHODS.vcsPull]: AuthSourceControlWriteScope,
58 [WS_METHODS.gitRunStackedAction]: AuthSourceControlWriteScope,
59 [WS_METHODS.gitPreparePullRequestThread]: AuthSourceControlWriteScope,
60 [WS_METHODS.vcsCreateWorktree]: AuthSourceControlWriteScope,
61 [WS_METHODS.vcsRemoveWorktree]: AuthSourceControlWriteScope,
62 [WS_METHODS.vcsCreateRef]: AuthSourceControlWriteScope,
63 [WS_METHODS.vcsSwitchRef]: AuthSourceControlWriteScope,
64 [WS_METHODS.vcsInit]: AuthSourceControlWriteScope,
65​
66 // Starts an agent session on this environment that can read its logs and database.
67 [WS_METHODS.serverPrepareTriage]: AuthOrchestrationOperateScope,
68 [WS_METHODS.scheduledTasksUpsert]: AuthOrchestrationOperateScope,
69 [WS_METHODS.scheduledTasksSetEnabled]: AuthOrchestrationOperateScope,
70 [WS_METHODS.scheduledTasksDelete]: AuthOrchestrationOperateScope,
71 [WS_METHODS.scheduledTasksRunNow]: AuthOrchestrationOperateScope,
72 [WS_METHODS.scheduledTasksRotateWebhookToken]: AuthOrchestrationOperateScope,
73 [ORCHESTRATION_V2_WS_METHODS.stopWorkflow]: AuthOrchestrationOperateScope,
74 // Force stop kills agent processes, as Stop on a terminal does.
75 [ORCHESTRATION_V2_WS_METHODS.forceStopThread]: AuthOrchestrationOperateScope,
76 // A guest link hands thread access to someone outside, like a pairing link.
77 [WS_METHODS.guestShareCreate]: AuthAccessWriteScope,
78 [WS_METHODS.peerLinksLink]: AuthAccessWriteScope,
79 [WS_METHODS.peerLinksUnlink]: AuthAccessWriteScope,
80 // A link lets every agent here reach the other environment: Settings' bar.
81 [WS_METHODS.peerLinksAnswerRequest]: AuthAccessWriteScope,
82} as const;
83export type ClientGuardedRpcTag = keyof typeof CLIENT_GUARDED_RPC_SCOPES;
84​
85const decodePrepareThread = Schema.decodeUnknownSync(GitPreparePullRequestThreadInput);
86const decodeStackedAction = Schema.decodeUnknownSync(GitRunStackedActionInput);
87​
88export function clientRpcRequiredScopes(
89 method: string,
90 input: unknown,
91): readonly AuthEnvironmentScope[] {
92 if (method === WS_METHODS.gitPreparePullRequestThread && input !== undefined) {
93 const payload = decodePrepareThread(input);
94 if (payload.mode === "worktree" && payload.threadId !== undefined)
95 return [AuthSourceControlWriteScope, AuthOrchestrationOperateScope];
96 }
97 if (method === WS_METHODS.gitRunStackedAction && input !== undefined) {
98 const payload = decodeStackedAction(input);
99 if (
100 payload.threadId !== undefined &&
101 (payload.action === "create_pr" || payload.action === "commit_push_pr")
102 )
103 return [AuthSourceControlWriteScope, AuthOrchestrationReadScope];
104 }
105 return Object.hasOwn(CLIENT_GUARDED_RPC_SCOPES, method)
106 ? [CLIENT_GUARDED_RPC_SCOPES[method as ClientGuardedRpcTag]]
107 : [];