@burdenoff/mcp-libs 2026.1009.2 → 2026.1012.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,104 @@
1
- import { mcpToolName, errorResult } from '../../chunk-G76DKEPI.js';
1
+ import { mcpToolName, errorResult, jsonResult } from '../../chunk-G76DKEPI.js';
2
2
  import { z } from 'zod';
3
3
 
4
+ // src/modules/rbac/operations.ts
5
+ var LIST_ROLES = `
6
+ query ListRoles($filter: RoleFilterInput, $pagination: PaginationInput, $scopeId: String!) {
7
+ roles(filter: $filter, pagination: $pagination, scopeId: $scopeId) {
8
+ id
9
+ name
10
+ description
11
+ isSystem
12
+ scopeId
13
+ priority
14
+ defaultPermissions {
15
+ level
16
+ resourceType
17
+ }
18
+ }
19
+ }
20
+ `;
21
+ var GET_ROLE = `
22
+ query GetRole($id: ID!) {
23
+ role(id: $id) {
24
+ id
25
+ name
26
+ description
27
+ isSystem
28
+ scopeId
29
+ priority
30
+ defaultPermissions {
31
+ level
32
+ resourceType
33
+ }
34
+ }
35
+ }
36
+ `;
37
+ var CREATE_ROLE = `
38
+ mutation CreateRole($input: CreateRoleInput!) {
39
+ createRole(input: $input) {
40
+ id
41
+ name
42
+ description
43
+ scopeId
44
+ }
45
+ }
46
+ `;
47
+ var UPDATE_ROLE = `
48
+ mutation UpdateRole($id: ID!, $input: UpdateRoleInput!) {
49
+ updateRole(id: $id, input: $input) {
50
+ id
51
+ name
52
+ description
53
+ priority
54
+ }
55
+ }
56
+ `;
57
+ var DELETE_ROLE = `
58
+ mutation DeleteRole($id: ID!, $reassignToRoleId: ID) {
59
+ deleteRole(id: $id, reassignToRoleId: $reassignToRoleId)
60
+ }
61
+ `;
62
+ var CHECK_PERMISSION = `
63
+ query CheckPermission($input: PermissionCheckInput!) {
64
+ checkPermission(input: $input) {
65
+ allowed
66
+ decisionPath
67
+ roleName
68
+ roleLevel
69
+ overrideType
70
+ }
71
+ }
72
+ `;
73
+ var LIST_POLICY_REFERENCES = `
74
+ query PolicyReferences($filter: PolicyReferenceFilterInput, $pagination: PaginationInput) {
75
+ policyReferences(filter: $filter, pagination: $pagination) {
76
+ id
77
+ name
78
+ description
79
+ opaPackage
80
+ resourceType
81
+ action
82
+ isActive
83
+ priority
84
+ createdAt
85
+ updatedAt
86
+ }
87
+ }
88
+ `;
89
+
90
+ // src/modules/rbac/tools.ts
91
+ var LayerEnum = z.enum(["workspace", "global"]);
92
+ var ActorTypeEnum = z.enum(["USER", "BOT", "GROUP", "INTEGRATION", "DELEGATED_AGENT"]);
93
+ function clientForLayer(ctx, layer) {
94
+ return layer === "workspace" ? ctx.gql.workspace : ctx.gql.global;
95
+ }
96
+ function defaultScopeId(ctx, layer) {
97
+ const auth = ctx.auth.read();
98
+ if (!auth) return null;
99
+ if (layer === "workspace") return auth.workspaceId ?? null;
100
+ return auth.organizationId ?? null;
101
+ }
4
102
  function stubbedTool(server, toolName, title, description, featureNote, inputSchema, altSuggestions) {
5
103
  server.registerTool(
6
104
  toolName,
@@ -14,89 +112,288 @@ function stubbedTool(server, toolName, title, description, featureNote, inputSch
14
112
  )
15
113
  );
16
114
  }
17
- function registerRbacTools(server, _ctx, track) {
18
- const featureNote = "Live alpha removed the rbac policies surface (no `attachPolicyToRole` / `detachPolicyFromRole` mutations; `roles` / `policies` queries are gone).";
19
- const alts = ["the next alpha release that re-exposes the rbac surface"];
20
- stubbedTool(
21
- server,
22
- track(mcpToolName(_ctx.productName, "rbac_check")),
23
- "Check Permission",
24
- "Check whether the calling actor has a given permission.",
25
- featureNote,
26
- { permission: z.string() },
27
- alts
115
+ function registerRbacTools(server, ctx, track) {
116
+ server.registerTool(
117
+ track(mcpToolName(ctx.productName, "rbac_roles_list")),
118
+ {
119
+ title: "List Roles",
120
+ description: "List RBAC roles for a workspace or global scope.",
121
+ inputSchema: {
122
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)"),
123
+ scopeId: z.string().optional().describe("Override scope id (workspace or tenant)"),
124
+ includeSystem: z.boolean().optional().describe("Include system roles"),
125
+ limit: z.number().optional().describe("Page size")
126
+ }
127
+ },
128
+ async ({ layer, scopeId, includeSystem, limit }) => {
129
+ try {
130
+ const targetLayer = layer ?? "workspace";
131
+ const resolvedScope = scopeId ?? defaultScopeId(ctx, targetLayer);
132
+ if (!resolvedScope) {
133
+ return errorResult(
134
+ `No ${targetLayer} scope. Pass scopeId or authenticate to a workspace/organization.`
135
+ );
136
+ }
137
+ const filter = {};
138
+ if (includeSystem) filter.includeSystem = true;
139
+ const data = await clientForLayer(ctx, targetLayer).request(
140
+ LIST_ROLES,
141
+ {
142
+ filter: Object.keys(filter).length ? filter : void 0,
143
+ pagination: { limit: limit ?? 100, offset: 0 },
144
+ scopeId: resolvedScope
145
+ }
146
+ );
147
+ return jsonResult(data.roles);
148
+ } catch (error) {
149
+ ctx.logger.error("rbac_roles_list failed", { error: String(error) });
150
+ return errorResult(
151
+ `Failed to list roles: ${error instanceof Error ? error.message : String(error)}`
152
+ );
153
+ }
154
+ }
28
155
  );
29
- stubbedTool(
30
- server,
31
- track(mcpToolName(_ctx.productName, "rbac_policies_list")),
32
- "List Policy References",
33
- "List references to a policy across the system.",
34
- featureNote,
35
- { policyId: z.string() },
36
- alts
156
+ server.registerTool(
157
+ track(mcpToolName(ctx.productName, "rbac_roles_get")),
158
+ {
159
+ title: "Get Role",
160
+ description: "Get a role by id from the workspace or global layer.",
161
+ inputSchema: {
162
+ id: z.string().describe("Role ID"),
163
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)")
164
+ }
165
+ },
166
+ async ({ id, layer }) => {
167
+ try {
168
+ const targetLayer = layer ?? "workspace";
169
+ const data = await clientForLayer(ctx, targetLayer).request(
170
+ GET_ROLE,
171
+ { id }
172
+ );
173
+ if (!data.role) return errorResult(`Role ${id} not found`);
174
+ return jsonResult(data.role);
175
+ } catch (error) {
176
+ ctx.logger.error("rbac_roles_get failed", { error: String(error) });
177
+ return errorResult(
178
+ `Failed to get role: ${error instanceof Error ? error.message : String(error)}`
179
+ );
180
+ }
181
+ }
37
182
  );
38
- stubbedTool(
39
- server,
40
- track(mcpToolName(_ctx.productName, "rbac_policies_attach")),
41
- "Attach Policy to Role",
42
- "Attach a policy to a role.",
43
- featureNote,
44
- { roleId: z.string(), policyId: z.string() },
45
- alts
183
+ server.registerTool(
184
+ track(mcpToolName(ctx.productName, "rbac_roles_create")),
185
+ {
186
+ title: "Create Role",
187
+ description: "Create a new RBAC role at the workspace or global layer.",
188
+ inputSchema: {
189
+ name: z.string().describe("Role name"),
190
+ description: z.string().optional().describe("Role description"),
191
+ parentId: z.string().optional().describe("Parent role id"),
192
+ priority: z.number().optional().describe("Priority"),
193
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)"),
194
+ scopeId: z.string().optional().describe("Override scope id"),
195
+ scopeType: z.string().optional().describe("wspace|entity (global layer only)")
196
+ }
197
+ },
198
+ async ({ name, description, parentId, priority, layer, scopeId, scopeType }) => {
199
+ try {
200
+ const targetLayer = layer ?? "workspace";
201
+ const resolvedScope = scopeId ?? defaultScopeId(ctx, targetLayer);
202
+ if (!resolvedScope) {
203
+ return errorResult(
204
+ `No ${targetLayer} scope. Pass scopeId or authenticate to a workspace/organization.`
205
+ );
206
+ }
207
+ const input = { name, scopeId: resolvedScope };
208
+ if (description !== void 0) input.description = description;
209
+ if (parentId !== void 0) input.parentId = parentId;
210
+ if (priority !== void 0) input.priority = priority;
211
+ if (targetLayer === "global" && scopeType) input.scopeType = scopeType;
212
+ const data = await clientForLayer(ctx, targetLayer).request(
213
+ CREATE_ROLE,
214
+ { input }
215
+ );
216
+ return jsonResult(data.createRole);
217
+ } catch (error) {
218
+ ctx.logger.error("rbac_roles_create failed", { error: String(error) });
219
+ return errorResult(
220
+ `Failed to create role: ${error instanceof Error ? error.message : String(error)}`
221
+ );
222
+ }
223
+ }
46
224
  );
47
- stubbedTool(
48
- server,
49
- track(mcpToolName(_ctx.productName, "rbac_policies_detach")),
50
- "Detach Policy from Role",
51
- "Detach a policy from a role.",
52
- featureNote,
53
- { roleId: z.string(), policyId: z.string() },
54
- alts
225
+ server.registerTool(
226
+ track(mcpToolName(ctx.productName, "rbac_roles_update")),
227
+ {
228
+ title: "Update Role",
229
+ description: "Update an existing role.",
230
+ inputSchema: {
231
+ id: z.string().describe("Role ID"),
232
+ name: z.string().optional().describe("Updated name"),
233
+ description: z.string().optional().describe("Updated description"),
234
+ priority: z.number().optional().describe("Updated priority"),
235
+ parentId: z.string().optional().describe("Updated parent role id"),
236
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)")
237
+ }
238
+ },
239
+ async ({ id, name, description, priority, parentId, layer }) => {
240
+ try {
241
+ const targetLayer = layer ?? "workspace";
242
+ const input = {};
243
+ if (name !== void 0) input.name = name;
244
+ if (description !== void 0) input.description = description;
245
+ if (priority !== void 0) input.priority = priority;
246
+ if (parentId !== void 0) input.parentId = parentId;
247
+ if (!Object.keys(input).length) {
248
+ return errorResult("No updates specified");
249
+ }
250
+ const data = await clientForLayer(ctx, targetLayer).request(
251
+ UPDATE_ROLE,
252
+ { id, input }
253
+ );
254
+ return jsonResult(data.updateRole);
255
+ } catch (error) {
256
+ ctx.logger.error("rbac_roles_update failed", { error: String(error) });
257
+ return errorResult(
258
+ `Failed to update role: ${error instanceof Error ? error.message : String(error)}`
259
+ );
260
+ }
261
+ }
55
262
  );
56
- stubbedTool(
57
- server,
58
- track(mcpToolName(_ctx.productName, "rbac_roles_list")),
59
- "List Roles",
60
- "List roles (workspace or global layer).",
61
- featureNote,
62
- { layer: z.enum(["workspace", "global"]).optional() },
63
- alts
263
+ server.registerTool(
264
+ track(mcpToolName(ctx.productName, "rbac_roles_delete")),
265
+ {
266
+ title: "Delete Role",
267
+ description: "Delete a role, optionally reassigning actors to another role.",
268
+ inputSchema: {
269
+ id: z.string().describe("Role ID"),
270
+ reassignToRoleId: z.string().optional().describe("Reassign actors to this role"),
271
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)")
272
+ }
273
+ },
274
+ async ({ id, reassignToRoleId, layer }) => {
275
+ try {
276
+ const targetLayer = layer ?? "workspace";
277
+ const data = await clientForLayer(ctx, targetLayer).request(
278
+ DELETE_ROLE,
279
+ { id, reassignToRoleId }
280
+ );
281
+ return jsonResult({ deleted: data.deleteRole, roleId: id });
282
+ } catch (error) {
283
+ ctx.logger.error("rbac_roles_delete failed", { error: String(error) });
284
+ return errorResult(
285
+ `Failed to delete role: ${error instanceof Error ? error.message : String(error)}`
286
+ );
287
+ }
288
+ }
64
289
  );
65
- stubbedTool(
66
- server,
67
- track(mcpToolName(_ctx.productName, "rbac_roles_get")),
68
- "Get Role",
69
- "Get a role by ID.",
70
- featureNote,
71
- { id: z.string() },
72
- alts
290
+ server.registerTool(
291
+ track(mcpToolName(ctx.productName, "rbac_policies_list")),
292
+ {
293
+ title: "List Policy References",
294
+ description: "List OPA policy references registered on the chosen gateway (workspace or global), optionally filtered by resource/action/active state. Returns an array of PolicyReference.",
295
+ inputSchema: {
296
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)"),
297
+ resourceType: z.string().optional().describe("Filter by resource type (e.g. project)"),
298
+ action: z.string().optional().describe("Filter by action (e.g. read/write/delete)"),
299
+ isActive: z.boolean().optional().describe("Only active/inactive policies"),
300
+ limit: z.number().int().optional().describe("Page size (default 100)"),
301
+ offset: z.number().int().optional().describe("Pagination offset (default 0)")
302
+ }
303
+ },
304
+ async ({ layer, resourceType, action, isActive, limit, offset }) => {
305
+ try {
306
+ const targetLayer = layer ?? "workspace";
307
+ const filter = {};
308
+ if (resourceType !== void 0) filter.resourceType = resourceType;
309
+ if (action !== void 0) filter.action = action;
310
+ if (isActive !== void 0) filter.isActive = isActive;
311
+ const data = await clientForLayer(ctx, targetLayer).request(LIST_POLICY_REFERENCES, {
312
+ filter: Object.keys(filter).length ? filter : void 0,
313
+ pagination: { limit: limit ?? 100, offset: offset ?? 0 }
314
+ });
315
+ return jsonResult(data.policyReferences);
316
+ } catch (error) {
317
+ ctx.logger.error("rbac_policies_list failed", { error: String(error) });
318
+ return errorResult(
319
+ `Failed to list policy references: ${error instanceof Error ? error.message : String(error)}`
320
+ );
321
+ }
322
+ }
73
323
  );
74
324
  stubbedTool(
75
325
  server,
76
- track(mcpToolName(_ctx.productName, "rbac_roles_create")),
77
- "Create Role",
78
- "Create a new role.",
79
- featureNote,
80
- { name: z.string() },
81
- alts
326
+ track(mcpToolName(ctx.productName, "rbac_policies_attach")),
327
+ "Attach Policy To Role",
328
+ "Attach an OPA policy reference to a role on the chosen gateway. Returns the attached PolicyReference.",
329
+ "Live alpha does not expose `Mutation.attachPolicyToRole` \u2014 the rbac service has never defined it. Policy-role attachment is implicit in `createRole(input)` and `assignRoleToActor` instead.",
330
+ {
331
+ roleId: z.string().describe("Role ID"),
332
+ policyId: z.string().describe("PolicyReference ID"),
333
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)")
334
+ },
335
+ [
336
+ "the next alpha release that adds `attachPolicyToRole` to the rbac service",
337
+ "the SDK rbac.attachPolicyToRole when it lands"
338
+ ]
82
339
  );
83
340
  stubbedTool(
84
341
  server,
85
- track(mcpToolName(_ctx.productName, "rbac_roles_update")),
86
- "Update Role",
87
- "Update a role.",
88
- featureNote,
89
- { id: z.string() },
90
- alts
342
+ track(mcpToolName(ctx.productName, "rbac_policies_detach")),
343
+ "Detach Policy From Role",
344
+ "Detach an OPA policy reference from a role on the chosen gateway. Returns { detached: boolean, roleId, policyId }.",
345
+ "Live alpha does not expose `Mutation.detachPolicyFromRole` \u2014 same as attach/detach (see above).",
346
+ {
347
+ roleId: z.string().describe("Role ID"),
348
+ policyId: z.string().describe("PolicyReference ID"),
349
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)")
350
+ },
351
+ ["the next alpha release that adds `detachPolicyFromRole` to the rbac service"]
91
352
  );
92
- stubbedTool(
93
- server,
94
- track(mcpToolName(_ctx.productName, "rbac_roles_delete")),
95
- "Delete Role",
96
- "Delete a role.",
97
- featureNote,
98
- { id: z.string() },
99
- alts
353
+ server.registerTool(
354
+ track(mcpToolName(ctx.productName, "rbac_check")),
355
+ {
356
+ title: "Check Permission",
357
+ description: "Check whether an actor has permission for an action on a resource.",
358
+ inputSchema: {
359
+ actorId: z.string().describe("Actor id (user/app/service/super_admin)"),
360
+ action: z.string().describe("Action like read/write/delete"),
361
+ resourceType: z.string().describe("Resource type like project/task"),
362
+ actorType: ActorTypeEnum.optional().describe("Actor type (default: USER)"),
363
+ resourceId: z.string().optional().describe("Specific resource id (optional)"),
364
+ scopeId: z.string().optional().describe("Scope id (workspaceId or tenantId)"),
365
+ layer: LayerEnum.optional().describe("workspace or global (default: workspace)")
366
+ }
367
+ },
368
+ async ({ actorId, action, resourceType, actorType, resourceId, scopeId, layer }) => {
369
+ try {
370
+ const targetLayer = layer ?? "workspace";
371
+ const resolvedScope = scopeId ?? defaultScopeId(ctx, targetLayer);
372
+ if (!resolvedScope) {
373
+ return errorResult(
374
+ `No ${targetLayer} scope. Pass scopeId or authenticate to a workspace/organization.`
375
+ );
376
+ }
377
+ const input = {
378
+ actorId,
379
+ actorType: actorType ?? "USER",
380
+ action,
381
+ resourceType,
382
+ scopeId: resolvedScope
383
+ };
384
+ if (resourceId !== void 0) input.resourceId = resourceId;
385
+ const data = await clientForLayer(ctx, targetLayer).request(
386
+ CHECK_PERMISSION,
387
+ { input }
388
+ );
389
+ return jsonResult(data.checkPermission);
390
+ } catch (error) {
391
+ ctx.logger.error("rbac_check failed", { error: String(error) });
392
+ return errorResult(
393
+ `Failed to check permission: ${error instanceof Error ? error.message : String(error)}`
394
+ );
395
+ }
396
+ }
100
397
  );
101
398
  }
102
399
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/rbac/tools.ts","../../../src/modules/rbac/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { errorResult, mcpToolName, type McpContext } from '../../core/index.js';\n\ntype StubInputSchema = Record<string, z.ZodTypeAny>;\nfunction stubbedTool(\n server: McpServer,\n toolName: string,\n title: string,\n description: string,\n featureNote: string,\n inputSchema: StubInputSchema,\n altSuggestions: string[],\n): void {\n server.registerTool(\n toolName,\n {\n title,\n description: `${description} [STUB]`,\n inputSchema,\n },\n async () =>\n errorResult(\n `[stubbed] ${featureNote} Use ${altSuggestions.join(', ')} instead. The tool remains registered so callers receive a meaningful response instead of a schema-validation error.`,\n ),\n );\n}\n\nexport function registerRbacTools(\n server: McpServer,\n _ctx: McpContext,\n track: (n: string) => string,\n): void {\n // BOFF-8195: `Mutation.attachPolicyToRole` / `detachPolicyFromRole`\n // removed from the live alpha gateway (gateway returned a missing-\n // `@rbac`-directive error). The `rbac_check` and `rbac_policies_list`\n // queries are gone too (`Query.roles` / `Query.policies` do not\n // exist). Whole rbac module unreachable today. Stubs preserve the\n // per-call wiring for the day the service re-exposes the surface.\n const featureNote =\n 'Live alpha removed the rbac policies surface (no `attachPolicyToRole` / `detachPolicyFromRole` mutations; `roles` / `policies` queries are gone).';\n const alts = ['the next alpha release that re-exposes the rbac surface'];\n\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_check')),\n 'Check Permission',\n 'Check whether the calling actor has a given permission.',\n featureNote,\n { permission: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_policies_list')),\n 'List Policy References',\n 'List references to a policy across the system.',\n featureNote,\n { policyId: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_policies_attach')),\n 'Attach Policy to Role',\n 'Attach a policy to a role.',\n featureNote,\n { roleId: z.string(), policyId: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_policies_detach')),\n 'Detach Policy from Role',\n 'Detach a policy from a role.',\n featureNote,\n { roleId: z.string(), policyId: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_roles_list')),\n 'List Roles',\n 'List roles (workspace or global layer).',\n featureNote,\n { layer: z.enum(['workspace', 'global']).optional() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_roles_get')),\n 'Get Role',\n 'Get a role by ID.',\n featureNote,\n { id: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_roles_create')),\n 'Create Role',\n 'Create a new role.',\n featureNote,\n { name: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_roles_update')),\n 'Update Role',\n 'Update a role.',\n featureNote,\n { id: z.string() },\n alts,\n );\n stubbedTool(\n server,\n track(mcpToolName(_ctx.productName, 'rbac_roles_delete')),\n 'Delete Role',\n 'Delete a role.',\n featureNote,\n { id: z.string() },\n alts,\n );\n}\n","/**\n * RBAC module — role-based access control across workspace + global layers.\n *\n * Tools:\n * <product>_rbac_roles_{list,get,create,update,delete}\n * <product>_rbac_check\n *\n * Backend: ~/products/wspace/rbac/wspace-rbac-svc/, ~/products/global/rbac/global-rbac-svc/.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { McpContext, McpModule, ModuleRegistration } from '../../core/index.js';\nimport { registerRbacTools } from './tools.js';\n\nconst rbacModule: McpModule = {\n id: 'rbac',\n version: '0.0.1',\n displayName: 'RBAC',\n dependsOn: ['auth'],\n capabilities: { tools: {} },\n\n register(server: McpServer, ctx: McpContext): ModuleRegistration {\n const tools: string[] = [];\n const track = (n: string): string => {\n tools.push(n);\n return n;\n };\n\n registerRbacTools(server, ctx, track);\n\n return { tools, resources: [], prompts: [] };\n },\n};\n\nexport default rbacModule;\n"]}
1
+ {"version":3,"sources":["../../../src/modules/rbac/operations.ts","../../../src/modules/rbac/tools.ts","../../../src/modules/rbac/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const LIST_ROLES = `\n query ListRoles($filter: RoleFilterInput, $pagination: PaginationInput, $scopeId: String!) {\n roles(filter: $filter, pagination: $pagination, scopeId: $scopeId) {\n id\n name\n description\n isSystem\n scopeId\n priority\n defaultPermissions {\n level\n resourceType\n }\n }\n }\n`;\n\nexport const GET_ROLE = `\n query GetRole($id: ID!) {\n role(id: $id) {\n id\n name\n description\n isSystem\n scopeId\n priority\n defaultPermissions {\n level\n resourceType\n }\n }\n }\n`;\n\nexport const CREATE_ROLE = `\n mutation CreateRole($input: CreateRoleInput!) {\n createRole(input: $input) {\n id\n name\n description\n scopeId\n }\n }\n`;\n\nexport const UPDATE_ROLE = `\n mutation UpdateRole($id: ID!, $input: UpdateRoleInput!) {\n updateRole(id: $id, input: $input) {\n id\n name\n description\n priority\n }\n }\n`;\n\nexport const DELETE_ROLE = `\n mutation DeleteRole($id: ID!, $reassignToRoleId: ID) {\n deleteRole(id: $id, reassignToRoleId: $reassignToRoleId)\n }\n`;\n\nexport const CHECK_PERMISSION = `\n query CheckPermission($input: PermissionCheckInput!) {\n checkPermission(input: $input) {\n allowed\n decisionPath\n roleName\n roleLevel\n overrideType\n }\n }\n`;\n\nexport const LIST_POLICY_REFERENCES = `\n query PolicyReferences($filter: PolicyReferenceFilterInput, $pagination: PaginationInput) {\n policyReferences(filter: $filter, pagination: $pagination) {\n id\n name\n description\n opaPackage\n resourceType\n action\n isActive\n priority\n createdAt\n updatedAt\n }\n }\n`;\n\nexport const ATTACH_POLICY = `\n mutation AttachPolicy($roleId: ID!, $policyId: ID!) {\n attachPolicyToRole(roleId: $roleId, policyId: $policyId) {\n id\n name\n resourceType\n action\n isActive\n }\n }\n`;\n\nexport const DETACH_POLICY = `\n mutation DetachPolicy($roleId: ID!, $policyId: ID!) {\n detachPolicyFromRole(roleId: $roleId, policyId: $policyId)\n }\n`;\n","import { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { jsonResult, errorResult, mcpToolName, type McpContext } from '../../core/index.js';\nimport {\n LIST_ROLES,\n GET_ROLE,\n CREATE_ROLE,\n UPDATE_ROLE,\n DELETE_ROLE,\n CHECK_PERMISSION,\n LIST_POLICY_REFERENCES,\n} from './operations.js';\n\nconst LayerEnum = z.enum(['workspace', 'global']);\nconst ActorTypeEnum = z.enum(['USER', 'BOT', 'GROUP', 'INTEGRATION', 'DELEGATED_AGENT']);\n\ntype Layer = 'workspace' | 'global';\n\nfunction clientForLayer(ctx: McpContext, layer: Layer) {\n return layer === 'workspace' ? ctx.gql.workspace : ctx.gql.global;\n}\n\nfunction defaultScopeId(ctx: McpContext, layer: Layer): string | null {\n const auth = ctx.auth.read();\n if (!auth) return null;\n if (layer === 'workspace') return auth.workspaceId ?? null;\n return auth.organizationId ?? null;\n}\n\n// BOFF-9166 (un-stub pass for PR #25's rbac module):\n// 7 of the 9 stubbed tools are real here — the rbac service exposes\n// `roles` / `role` / `createRole` / `updateRole` / `deleteRole` /\n// `checkPermission` / `policyReferences` with proper `@rbac` directives.\n// The remaining 2 (`rbac_policies_attach` / `rbac_policies_detach`)\n// reference `Mutation.attachPolicyToRole` / `Mutation.detachPolicyFromRole`,\n// which the rbac service has never defined (policy-role attachment is\n// implicit in `createRole(input)` and `assignRoleToActor` instead). The\n// original BOFF-8195 error \"missing @rbac directive\" was a transient /\n// misread — `git log -S attachPolicyToRole` returns nothing. The two\n// tools stay stubbed until the rbac service gains the mutations (or the\n// SDK manifest drops the surface); every other rbac tool calls the real\n// gateway and surfaces real data on alpha.\ntype StubInputSchema = Record<string, z.ZodTypeAny>;\nfunction stubbedTool(\n server: McpServer,\n toolName: string,\n title: string,\n description: string,\n featureNote: string,\n inputSchema: StubInputSchema,\n altSuggestions: string[],\n): void {\n server.registerTool(\n toolName,\n {\n title,\n description: `${description} [STUB]`,\n inputSchema,\n },\n async () =>\n errorResult(\n `[stubbed] ${featureNote} Use ${altSuggestions.join(', ')} instead. The tool remains registered so callers receive a meaningful response instead of a schema-validation error.`,\n ),\n );\n}\n\nexport function registerRbacTools(\n server: McpServer,\n ctx: McpContext,\n track: (n: string) => string,\n): void {\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_roles_list')),\n {\n title: 'List Roles',\n description: 'List RBAC roles for a workspace or global scope.',\n inputSchema: {\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n scopeId: z.string().optional().describe('Override scope id (workspace or tenant)'),\n includeSystem: z.boolean().optional().describe('Include system roles'),\n limit: z.number().optional().describe('Page size'),\n },\n },\n async ({ layer, scopeId, includeSystem, limit }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const resolvedScope = scopeId ?? defaultScopeId(ctx, targetLayer);\n if (!resolvedScope) {\n return errorResult(\n `No ${targetLayer} scope. Pass scopeId or authenticate to a workspace/organization.`,\n );\n }\n const filter: Record<string, unknown> = {};\n if (includeSystem) filter.includeSystem = true;\n const data = await clientForLayer(ctx, targetLayer).request<{ roles: unknown }>(\n LIST_ROLES,\n {\n filter: Object.keys(filter).length ? filter : undefined,\n pagination: { limit: limit ?? 100, offset: 0 },\n scopeId: resolvedScope,\n },\n );\n return jsonResult(data.roles);\n } catch (error) {\n ctx.logger.error('rbac_roles_list failed', { error: String(error) });\n return errorResult(\n `Failed to list roles: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_roles_get')),\n {\n title: 'Get Role',\n description: 'Get a role by id from the workspace or global layer.',\n inputSchema: {\n id: z.string().describe('Role ID'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n },\n },\n async ({ id, layer }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const data = await clientForLayer(ctx, targetLayer).request<{ role: unknown | null }>(\n GET_ROLE,\n { id },\n );\n if (!data.role) return errorResult(`Role ${id} not found`);\n return jsonResult(data.role);\n } catch (error) {\n ctx.logger.error('rbac_roles_get failed', { error: String(error) });\n return errorResult(\n `Failed to get role: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_roles_create')),\n {\n title: 'Create Role',\n description: 'Create a new RBAC role at the workspace or global layer.',\n inputSchema: {\n name: z.string().describe('Role name'),\n description: z.string().optional().describe('Role description'),\n parentId: z.string().optional().describe('Parent role id'),\n priority: z.number().optional().describe('Priority'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n scopeId: z.string().optional().describe('Override scope id'),\n scopeType: z.string().optional().describe('wspace|entity (global layer only)'),\n },\n },\n async ({ name, description, parentId, priority, layer, scopeId, scopeType }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const resolvedScope = scopeId ?? defaultScopeId(ctx, targetLayer);\n if (!resolvedScope) {\n return errorResult(\n `No ${targetLayer} scope. Pass scopeId or authenticate to a workspace/organization.`,\n );\n }\n const input: Record<string, unknown> = { name, scopeId: resolvedScope };\n if (description !== undefined) input.description = description;\n if (parentId !== undefined) input.parentId = parentId;\n if (priority !== undefined) input.priority = priority;\n if (targetLayer === 'global' && scopeType) input.scopeType = scopeType;\n const data = await clientForLayer(ctx, targetLayer).request<{ createRole: unknown }>(\n CREATE_ROLE,\n { input },\n );\n return jsonResult(data.createRole);\n } catch (error) {\n ctx.logger.error('rbac_roles_create failed', { error: String(error) });\n return errorResult(\n `Failed to create role: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_roles_update')),\n {\n title: 'Update Role',\n description: 'Update an existing role.',\n inputSchema: {\n id: z.string().describe('Role ID'),\n name: z.string().optional().describe('Updated name'),\n description: z.string().optional().describe('Updated description'),\n priority: z.number().optional().describe('Updated priority'),\n parentId: z.string().optional().describe('Updated parent role id'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n },\n },\n async ({ id, name, description, priority, parentId, layer }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const input: Record<string, unknown> = {};\n if (name !== undefined) input.name = name;\n if (description !== undefined) input.description = description;\n if (priority !== undefined) input.priority = priority;\n if (parentId !== undefined) input.parentId = parentId;\n if (!Object.keys(input).length) {\n return errorResult('No updates specified');\n }\n const data = await clientForLayer(ctx, targetLayer).request<{ updateRole: unknown }>(\n UPDATE_ROLE,\n { id, input },\n );\n return jsonResult(data.updateRole);\n } catch (error) {\n ctx.logger.error('rbac_roles_update failed', { error: String(error) });\n return errorResult(\n `Failed to update role: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_roles_delete')),\n {\n title: 'Delete Role',\n description: 'Delete a role, optionally reassigning actors to another role.',\n inputSchema: {\n id: z.string().describe('Role ID'),\n reassignToRoleId: z.string().optional().describe('Reassign actors to this role'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n },\n },\n async ({ id, reassignToRoleId, layer }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const data = await clientForLayer(ctx, targetLayer).request<{ deleteRole: unknown }>(\n DELETE_ROLE,\n { id, reassignToRoleId },\n );\n return jsonResult({ deleted: data.deleteRole, roleId: id });\n } catch (error) {\n ctx.logger.error('rbac_roles_delete failed', { error: String(error) });\n return errorResult(\n `Failed to delete role: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── Policies ────────────────────────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_policies_list')),\n {\n title: 'List Policy References',\n description:\n 'List OPA policy references registered on the chosen gateway (workspace or global), optionally filtered by resource/action/active state. Returns an array of PolicyReference.',\n inputSchema: {\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n resourceType: z.string().optional().describe('Filter by resource type (e.g. project)'),\n action: z.string().optional().describe('Filter by action (e.g. read/write/delete)'),\n isActive: z.boolean().optional().describe('Only active/inactive policies'),\n limit: z.number().int().optional().describe('Page size (default 100)'),\n offset: z.number().int().optional().describe('Pagination offset (default 0)'),\n },\n },\n async ({ layer, resourceType, action, isActive, limit, offset }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const filter: Record<string, unknown> = {};\n if (resourceType !== undefined) filter.resourceType = resourceType;\n if (action !== undefined) filter.action = action;\n if (isActive !== undefined) filter.isActive = isActive;\n const data = await clientForLayer(ctx, targetLayer).request<{\n policyReferences: unknown[];\n }>(LIST_POLICY_REFERENCES, {\n filter: Object.keys(filter).length ? filter : undefined,\n pagination: { limit: limit ?? 100, offset: offset ?? 0 },\n });\n return jsonResult(data.policyReferences);\n } catch (error) {\n ctx.logger.error('rbac_policies_list failed', { error: String(error) });\n return errorResult(\n `Failed to list policy references: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-9166: keep attach/detach as stubs — the underlying mutations don't\n // exist in any subgraph. See the file-header comment for context.\n stubbedTool(\n server,\n track(mcpToolName(ctx.productName, 'rbac_policies_attach')),\n 'Attach Policy To Role',\n 'Attach an OPA policy reference to a role on the chosen gateway. Returns the attached PolicyReference.',\n 'Live alpha does not expose `Mutation.attachPolicyToRole` — the rbac service has never defined it. Policy-role attachment is implicit in `createRole(input)` and `assignRoleToActor` instead.',\n {\n roleId: z.string().describe('Role ID'),\n policyId: z.string().describe('PolicyReference ID'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n },\n [\n 'the next alpha release that adds `attachPolicyToRole` to the rbac service',\n 'the SDK rbac.attachPolicyToRole when it lands',\n ],\n );\n\n stubbedTool(\n server,\n track(mcpToolName(ctx.productName, 'rbac_policies_detach')),\n 'Detach Policy From Role',\n 'Detach an OPA policy reference from a role on the chosen gateway. Returns { detached: boolean, roleId, policyId }.',\n 'Live alpha does not expose `Mutation.detachPolicyFromRole` — same as attach/detach (see above).',\n {\n roleId: z.string().describe('Role ID'),\n policyId: z.string().describe('PolicyReference ID'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n },\n ['the next alpha release that adds `detachPolicyFromRole` to the rbac service'],\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'rbac_check')),\n {\n title: 'Check Permission',\n description: 'Check whether an actor has permission for an action on a resource.',\n inputSchema: {\n actorId: z.string().describe('Actor id (user/app/service/super_admin)'),\n action: z.string().describe('Action like read/write/delete'),\n resourceType: z.string().describe('Resource type like project/task'),\n actorType: ActorTypeEnum.optional().describe('Actor type (default: USER)'),\n resourceId: z.string().optional().describe('Specific resource id (optional)'),\n scopeId: z.string().optional().describe('Scope id (workspaceId or tenantId)'),\n layer: LayerEnum.optional().describe('workspace or global (default: workspace)'),\n },\n },\n async ({ actorId, action, resourceType, actorType, resourceId, scopeId, layer }) => {\n try {\n const targetLayer: Layer = layer ?? 'workspace';\n const resolvedScope = scopeId ?? defaultScopeId(ctx, targetLayer);\n if (!resolvedScope) {\n return errorResult(\n `No ${targetLayer} scope. Pass scopeId or authenticate to a workspace/organization.`,\n );\n }\n const input: Record<string, unknown> = {\n actorId,\n actorType: actorType ?? 'USER',\n action,\n resourceType,\n scopeId: resolvedScope,\n };\n if (resourceId !== undefined) input.resourceId = resourceId;\n const data = await clientForLayer(ctx, targetLayer).request<{ checkPermission: unknown }>(\n CHECK_PERMISSION,\n { input },\n );\n return jsonResult(data.checkPermission);\n } catch (error) {\n ctx.logger.error('rbac_check failed', { error: String(error) });\n return errorResult(\n `Failed to check permission: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n}\n","/**\n * RBAC module — role-based access control across workspace + global layers.\n *\n * Tools:\n * <product>_rbac_roles_{list,get,create,update,delete}\n * <product>_rbac_check\n *\n * Backend: ~/products/wspace/rbac/wspace-rbac-svc/, ~/products/global/rbac/global-rbac-svc/.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { McpContext, McpModule, ModuleRegistration } from '../../core/index.js';\nimport { registerRbacTools } from './tools.js';\n\nconst rbacModule: McpModule = {\n id: 'rbac',\n version: '0.0.1',\n displayName: 'RBAC',\n dependsOn: ['auth'],\n capabilities: { tools: {} },\n\n register(server: McpServer, ctx: McpContext): ModuleRegistration {\n const tools: string[] = [];\n const track = (n: string): string => {\n tools.push(n);\n return n;\n };\n\n registerRbacTools(server, ctx, track);\n\n return { tools, resources: [], prompts: [] };\n },\n};\n\nexport default rbacModule;\n"]}