@elliotding/ai-agent-mcp 0.1.24 → 0.1.26

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.
Files changed (233) hide show
  1. package/README.md +27 -0
  2. package/package.json +4 -1
  3. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-generate-testcase.md +0 -101
  4. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-submit_zct_job.md +0 -158
  5. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-conf-status.md +0 -311
  6. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-sdk-log.md +0 -64
  7. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-zmb-log-errors.md +0 -84
  8. package/ai-resource-telemetry.json +0 -40
  9. package/dist/api/cached-client.d.ts +0 -48
  10. package/dist/api/cached-client.d.ts.map +0 -1
  11. package/dist/api/cached-client.js +0 -126
  12. package/dist/api/cached-client.js.map +0 -1
  13. package/dist/api/client.d.ts +0 -281
  14. package/dist/api/client.d.ts.map +0 -1
  15. package/dist/api/client.js +0 -371
  16. package/dist/api/client.js.map +0 -1
  17. package/dist/auth/index.d.ts +0 -8
  18. package/dist/auth/index.d.ts.map +0 -1
  19. package/dist/auth/index.js +0 -26
  20. package/dist/auth/index.js.map +0 -1
  21. package/dist/auth/middleware.d.ts +0 -36
  22. package/dist/auth/middleware.d.ts.map +0 -1
  23. package/dist/auth/middleware.js +0 -194
  24. package/dist/auth/middleware.js.map +0 -1
  25. package/dist/auth/permissions.d.ts +0 -60
  26. package/dist/auth/permissions.d.ts.map +0 -1
  27. package/dist/auth/permissions.js +0 -262
  28. package/dist/auth/permissions.js.map +0 -1
  29. package/dist/auth/token-validator.d.ts +0 -52
  30. package/dist/auth/token-validator.d.ts.map +0 -1
  31. package/dist/auth/token-validator.js +0 -215
  32. package/dist/auth/token-validator.js.map +0 -1
  33. package/dist/cache/cache-manager.d.ts +0 -49
  34. package/dist/cache/cache-manager.d.ts.map +0 -1
  35. package/dist/cache/cache-manager.js +0 -191
  36. package/dist/cache/cache-manager.js.map +0 -1
  37. package/dist/cache/index.d.ts +0 -6
  38. package/dist/cache/index.d.ts.map +0 -1
  39. package/dist/cache/index.js +0 -12
  40. package/dist/cache/index.js.map +0 -1
  41. package/dist/cache/redis-client.d.ts +0 -45
  42. package/dist/cache/redis-client.d.ts.map +0 -1
  43. package/dist/cache/redis-client.js +0 -210
  44. package/dist/cache/redis-client.js.map +0 -1
  45. package/dist/config/constants.d.ts +0 -28
  46. package/dist/config/constants.d.ts.map +0 -1
  47. package/dist/config/constants.js +0 -31
  48. package/dist/config/constants.js.map +0 -1
  49. package/dist/config/index.d.ts +0 -71
  50. package/dist/config/index.d.ts.map +0 -1
  51. package/dist/config/index.js +0 -190
  52. package/dist/config/index.js.map +0 -1
  53. package/dist/filesystem/manager.d.ts +0 -45
  54. package/dist/filesystem/manager.d.ts.map +0 -1
  55. package/dist/filesystem/manager.js +0 -246
  56. package/dist/filesystem/manager.js.map +0 -1
  57. package/dist/git/multi-source-manager.d.ts +0 -78
  58. package/dist/git/multi-source-manager.d.ts.map +0 -1
  59. package/dist/git/multi-source-manager.js +0 -577
  60. package/dist/git/multi-source-manager.js.map +0 -1
  61. package/dist/git/operations.d.ts +0 -27
  62. package/dist/git/operations.d.ts.map +0 -1
  63. package/dist/git/operations.js +0 -83
  64. package/dist/git/operations.js.map +0 -1
  65. package/dist/index.d.ts +0 -6
  66. package/dist/index.d.ts.map +0 -1
  67. package/dist/index.js +0 -122
  68. package/dist/index.js.map +0 -1
  69. package/dist/monitoring/health.d.ts +0 -35
  70. package/dist/monitoring/health.d.ts.map +0 -1
  71. package/dist/monitoring/health.js +0 -105
  72. package/dist/monitoring/health.js.map +0 -1
  73. package/dist/prompts/cache.d.ts +0 -69
  74. package/dist/prompts/cache.d.ts.map +0 -1
  75. package/dist/prompts/cache.js +0 -163
  76. package/dist/prompts/cache.js.map +0 -1
  77. package/dist/prompts/generator.d.ts +0 -49
  78. package/dist/prompts/generator.d.ts.map +0 -1
  79. package/dist/prompts/generator.js +0 -160
  80. package/dist/prompts/generator.js.map +0 -1
  81. package/dist/prompts/index.d.ts +0 -13
  82. package/dist/prompts/index.d.ts.map +0 -1
  83. package/dist/prompts/index.js +0 -24
  84. package/dist/prompts/index.js.map +0 -1
  85. package/dist/prompts/manager.d.ts +0 -169
  86. package/dist/prompts/manager.d.ts.map +0 -1
  87. package/dist/prompts/manager.js +0 -488
  88. package/dist/prompts/manager.js.map +0 -1
  89. package/dist/resources/index.d.ts +0 -6
  90. package/dist/resources/index.d.ts.map +0 -1
  91. package/dist/resources/index.js +0 -10
  92. package/dist/resources/index.js.map +0 -1
  93. package/dist/resources/loader.d.ts +0 -88
  94. package/dist/resources/loader.d.ts.map +0 -1
  95. package/dist/resources/loader.js +0 -492
  96. package/dist/resources/loader.js.map +0 -1
  97. package/dist/server/http.d.ts +0 -57
  98. package/dist/server/http.d.ts.map +0 -1
  99. package/dist/server/http.js +0 -435
  100. package/dist/server/http.js.map +0 -1
  101. package/dist/server.d.ts +0 -13
  102. package/dist/server.d.ts.map +0 -1
  103. package/dist/server.js +0 -200
  104. package/dist/server.js.map +0 -1
  105. package/dist/session/manager.d.ts +0 -91
  106. package/dist/session/manager.d.ts.map +0 -1
  107. package/dist/session/manager.js +0 -251
  108. package/dist/session/manager.js.map +0 -1
  109. package/dist/telemetry/index.d.ts +0 -3
  110. package/dist/telemetry/index.d.ts.map +0 -1
  111. package/dist/telemetry/index.js +0 -7
  112. package/dist/telemetry/index.js.map +0 -1
  113. package/dist/telemetry/manager.d.ts +0 -151
  114. package/dist/telemetry/manager.d.ts.map +0 -1
  115. package/dist/telemetry/manager.js +0 -367
  116. package/dist/telemetry/manager.js.map +0 -1
  117. package/dist/tools/index.d.ts +0 -12
  118. package/dist/tools/index.d.ts.map +0 -1
  119. package/dist/tools/index.js +0 -28
  120. package/dist/tools/index.js.map +0 -1
  121. package/dist/tools/manage-subscription.d.ts +0 -47
  122. package/dist/tools/manage-subscription.d.ts.map +0 -1
  123. package/dist/tools/manage-subscription.js +0 -314
  124. package/dist/tools/manage-subscription.js.map +0 -1
  125. package/dist/tools/registry.d.ts +0 -40
  126. package/dist/tools/registry.d.ts.map +0 -1
  127. package/dist/tools/registry.js +0 -85
  128. package/dist/tools/registry.js.map +0 -1
  129. package/dist/tools/search-resources.d.ts +0 -35
  130. package/dist/tools/search-resources.d.ts.map +0 -1
  131. package/dist/tools/search-resources.js +0 -159
  132. package/dist/tools/search-resources.js.map +0 -1
  133. package/dist/tools/sync-resources.d.ts +0 -54
  134. package/dist/tools/sync-resources.d.ts.map +0 -1
  135. package/dist/tools/sync-resources.js +0 -733
  136. package/dist/tools/sync-resources.js.map +0 -1
  137. package/dist/tools/track-usage.d.ts +0 -63
  138. package/dist/tools/track-usage.d.ts.map +0 -1
  139. package/dist/tools/track-usage.js +0 -90
  140. package/dist/tools/track-usage.js.map +0 -1
  141. package/dist/tools/uninstall-resource.d.ts +0 -30
  142. package/dist/tools/uninstall-resource.d.ts.map +0 -1
  143. package/dist/tools/uninstall-resource.js +0 -174
  144. package/dist/tools/uninstall-resource.js.map +0 -1
  145. package/dist/tools/upload-resource.d.ts +0 -81
  146. package/dist/tools/upload-resource.d.ts.map +0 -1
  147. package/dist/tools/upload-resource.js +0 -393
  148. package/dist/tools/upload-resource.js.map +0 -1
  149. package/dist/transport/sse.d.ts +0 -29
  150. package/dist/transport/sse.d.ts.map +0 -1
  151. package/dist/transport/sse.js +0 -271
  152. package/dist/transport/sse.js.map +0 -1
  153. package/dist/types/errors.d.ts +0 -60
  154. package/dist/types/errors.d.ts.map +0 -1
  155. package/dist/types/errors.js +0 -112
  156. package/dist/types/errors.js.map +0 -1
  157. package/dist/types/index.d.ts +0 -7
  158. package/dist/types/index.d.ts.map +0 -1
  159. package/dist/types/index.js +0 -23
  160. package/dist/types/index.js.map +0 -1
  161. package/dist/types/mcp.d.ts +0 -50
  162. package/dist/types/mcp.d.ts.map +0 -1
  163. package/dist/types/mcp.js +0 -6
  164. package/dist/types/mcp.js.map +0 -1
  165. package/dist/types/resources.d.ts +0 -109
  166. package/dist/types/resources.d.ts.map +0 -1
  167. package/dist/types/resources.js +0 -7
  168. package/dist/types/resources.js.map +0 -1
  169. package/dist/types/tools.d.ts +0 -235
  170. package/dist/types/tools.d.ts.map +0 -1
  171. package/dist/types/tools.js +0 -6
  172. package/dist/types/tools.js.map +0 -1
  173. package/dist/utils/cursor-paths.d.ts +0 -84
  174. package/dist/utils/cursor-paths.d.ts.map +0 -1
  175. package/dist/utils/cursor-paths.js +0 -166
  176. package/dist/utils/cursor-paths.js.map +0 -1
  177. package/dist/utils/log-cleaner.d.ts +0 -18
  178. package/dist/utils/log-cleaner.d.ts.map +0 -1
  179. package/dist/utils/log-cleaner.js +0 -112
  180. package/dist/utils/log-cleaner.js.map +0 -1
  181. package/dist/utils/logger.d.ts +0 -59
  182. package/dist/utils/logger.d.ts.map +0 -1
  183. package/dist/utils/logger.js +0 -292
  184. package/dist/utils/logger.js.map +0 -1
  185. package/dist/utils/validation.d.ts +0 -58
  186. package/dist/utils/validation.d.ts.map +0 -1
  187. package/dist/utils/validation.js +0 -214
  188. package/dist/utils/validation.js.map +0 -1
  189. package/src/api/cached-client.ts +0 -144
  190. package/src/api/client.ts +0 -697
  191. package/src/auth/index.ts +0 -11
  192. package/src/auth/middleware.ts +0 -244
  193. package/src/auth/permissions.ts +0 -323
  194. package/src/auth/token-validator.ts +0 -292
  195. package/src/cache/cache-manager.ts +0 -243
  196. package/src/cache/index.ts +0 -6
  197. package/src/cache/redis-client.ts +0 -249
  198. package/src/config/constants.ts +0 -33
  199. package/src/config/index.ts +0 -269
  200. package/src/filesystem/manager.ts +0 -235
  201. package/src/git/multi-source-manager.ts +0 -654
  202. package/src/git/operations.ts +0 -93
  203. package/src/index.ts +0 -157
  204. package/src/monitoring/health.ts +0 -132
  205. package/src/prompts/cache.ts +0 -140
  206. package/src/prompts/generator.ts +0 -143
  207. package/src/prompts/index.ts +0 -20
  208. package/src/prompts/manager.ts +0 -613
  209. package/src/resources/index.ts +0 -13
  210. package/src/resources/loader.ts +0 -563
  211. package/src/server/http.ts +0 -549
  212. package/src/server.ts +0 -204
  213. package/src/session/manager.ts +0 -296
  214. package/src/telemetry/index.ts +0 -10
  215. package/src/telemetry/manager.ts +0 -419
  216. package/src/tools/index.ts +0 -12
  217. package/src/tools/manage-subscription.ts +0 -385
  218. package/src/tools/registry.ts +0 -97
  219. package/src/tools/search-resources.ts +0 -185
  220. package/src/tools/sync-resources.ts +0 -827
  221. package/src/tools/track-usage.ts +0 -113
  222. package/src/tools/uninstall-resource.ts +0 -199
  223. package/src/tools/upload-resource.ts +0 -431
  224. package/src/transport/sse.ts +0 -308
  225. package/src/types/errors.ts +0 -146
  226. package/src/types/index.ts +0 -7
  227. package/src/types/mcp.ts +0 -61
  228. package/src/types/resources.ts +0 -141
  229. package/src/types/tools.ts +0 -284
  230. package/src/utils/cursor-paths.ts +0 -135
  231. package/src/utils/log-cleaner.ts +0 -92
  232. package/src/utils/logger.ts +0 -333
  233. package/src/utils/validation.ts +0 -262
@@ -1,244 +0,0 @@
1
- /**
2
- * Authentication and Permission Middlewares
3
- * Token authentication and permission checking for HTTP endpoints
4
- */
5
-
6
- import { FastifyRequest, FastifyReply } from 'fastify';
7
- import { verifyToken, TokenPayload } from './token-validator';
8
- import { checkPermission } from './permissions';
9
- import { logger } from '../utils/logger';
10
-
11
- /**
12
- * Extended request with user info
13
- */
14
- export interface AuthenticatedRequest extends FastifyRequest {
15
- user?: TokenPayload;
16
- }
17
-
18
- /**
19
- * Token Authentication Middleware
20
- * Verifies token via external REST API
21
- */
22
- export async function tokenAuthMiddleware(
23
- request: AuthenticatedRequest,
24
- reply: FastifyReply
25
- ): Promise<void> {
26
- try {
27
- // Extract token from Authorization header
28
- const authHeader = request.headers.authorization;
29
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
30
- logger.warn(
31
- {
32
- type: 'auth',
33
- operation: 'middleware',
34
- ip: request.ip,
35
- url: request.url
36
- },
37
- 'Missing or invalid Authorization header'
38
- );
39
- reply.code(401).send({
40
- error: 'Unauthorized',
41
- message: 'Missing or invalid Authorization header. Expected: Bearer <token>',
42
- });
43
- return;
44
- }
45
-
46
- const token = authHeader.substring(7); // Remove 'Bearer ' prefix
47
-
48
- // Verify token via external API
49
- const payload = await verifyToken(token);
50
- if (!payload) {
51
- logger.warn(
52
- {
53
- type: 'auth',
54
- operation: 'middleware',
55
- ip: request.ip,
56
- url: request.url
57
- },
58
- 'Token validation failed'
59
- );
60
- reply.code(401).send({
61
- error: 'Unauthorized',
62
- message: 'Invalid or expired token',
63
- });
64
- return;
65
- }
66
-
67
- // Attach user info to request
68
- request.user = payload;
69
-
70
- logger.debug(
71
- {
72
- type: 'auth',
73
- operation: 'middleware',
74
- userId: payload.userId,
75
- email: payload.email,
76
- groups: payload.groups
77
- },
78
- `Token authentication successful for user ${payload.userId}`
79
- );
80
- } catch (error) {
81
- logger.error({
82
- type: 'auth',
83
- operation: 'middleware',
84
- error: error instanceof Error ? error.message : 'Unknown error'
85
- }, 'Token authentication error');
86
- reply.code(500).send({
87
- error: 'Internal Server Error',
88
- message: 'Authentication failed',
89
- });
90
- }
91
- }
92
-
93
- /**
94
- * Token Authentication Middleware with Legacy Bearer Token Support
95
- * Supports both token validation via API and legacy bearer tokens
96
- */
97
- export async function tokenAuthOrLegacyMiddleware(
98
- request: AuthenticatedRequest,
99
- reply: FastifyReply
100
- ): Promise<void> {
101
- try {
102
- const authHeader = request.headers.authorization;
103
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
104
- logger.warn(
105
- {
106
- type: 'auth',
107
- operation: 'middleware_legacy',
108
- ip: request.ip,
109
- url: request.url
110
- },
111
- 'Missing or invalid Authorization header'
112
- );
113
- reply.code(401).send({
114
- error: 'Unauthorized',
115
- message: 'Missing or invalid Authorization header',
116
- });
117
- return;
118
- }
119
-
120
- const token = authHeader.substring(7);
121
-
122
- // Try to validate via API first
123
- const payload = await verifyToken(token);
124
- if (payload) {
125
- // API validation successful
126
- request.user = payload;
127
- logger.debug(
128
- {
129
- type: 'auth',
130
- operation: 'middleware_legacy',
131
- userId: payload.userId,
132
- email: payload.email,
133
- groups: payload.groups
134
- },
135
- `Token validated via API for user ${payload.userId}`
136
- );
137
- return;
138
- }
139
-
140
- // Fallback to legacy bearer token (for backward compatibility)
141
- logger.debug(
142
- {
143
- type: 'auth',
144
- operation: 'middleware_legacy',
145
- ip: request.ip
146
- },
147
- 'API validation failed, using legacy bearer token mode'
148
- );
149
-
150
- // In legacy mode, we don't have user info, so continue without setting request.user
151
- // The endpoint will handle the legacy token separately
152
- } catch (error) {
153
- logger.error({
154
- type: 'auth',
155
- operation: 'middleware_legacy',
156
- error: error instanceof Error ? error.message : 'Unknown error'
157
- }, 'Token authentication error');
158
- reply.code(500).send({
159
- error: 'Internal Server Error',
160
- message: 'Authentication failed',
161
- });
162
- }
163
- }
164
-
165
- /**
166
- * Permission Check Middleware Factory
167
- * Creates middleware to check permissions for a specific tool
168
- */
169
- export function requirePermission(toolName: string) {
170
- return async (request: AuthenticatedRequest, reply: FastifyReply): Promise<void> => {
171
- try {
172
- if (!request.user) {
173
- logger.error(
174
- {
175
- type: 'auth',
176
- operation: 'permission_check',
177
- url: request.url
178
- },
179
- 'Permission check called without authentication'
180
- );
181
- reply.code(401).send({
182
- error: 'Unauthorized',
183
- message: 'Authentication required',
184
- });
185
- return;
186
- }
187
-
188
- // Check permission
189
- const permissionCheck = checkPermission(toolName, request.user.groups);
190
-
191
- if (!permissionCheck.allowed) {
192
- logger.warn(
193
- {
194
- type: 'auth',
195
- operation: 'permission_check',
196
- userId: request.user.userId,
197
- email: request.user.email,
198
- groups: request.user.groups,
199
- toolName,
200
- reason: permissionCheck.reason,
201
- },
202
- `Permission denied for user ${request.user.userId} to access tool ${toolName}`
203
- );
204
- reply.code(403).send({
205
- error: 'Forbidden',
206
- message: permissionCheck.reason || 'Insufficient permissions',
207
- });
208
- return;
209
- }
210
-
211
- logger.debug(
212
- {
213
- type: 'auth',
214
- operation: 'permission_check',
215
- userId: request.user.userId,
216
- toolName
217
- },
218
- `Permission granted for user ${request.user.userId} to access tool ${toolName}`
219
- );
220
- } catch (error) {
221
- logger.error({
222
- type: 'auth',
223
- operation: 'permission_check',
224
- toolName,
225
- error: error instanceof Error ? error.message : 'Unknown error'
226
- }, 'Permission check error');
227
- reply.code(500).send({
228
- error: 'Internal Server Error',
229
- message: 'Permission check failed',
230
- });
231
- }
232
- };
233
- }
234
-
235
- /**
236
- * Permission Check for Tool Call
237
- * Checks permission when tools/call is invoked
238
- */
239
- export function checkToolCallPermission(
240
- toolName: string,
241
- user: TokenPayload
242
- ): { allowed: boolean; reason?: string } {
243
- return checkPermission(toolName, user.groups);
244
- }
@@ -1,323 +0,0 @@
1
- /**
2
- * Permission Control System
3
- * Group-based access control for MCP tools
4
- * Groups are obtained from CSP API /user/permissions (e.g., "zNet", "Client-Public")
5
- */
6
-
7
- import { logger, logAuthAttempt } from '../utils/logger';
8
-
9
- /**
10
- * Known groups from CSP
11
- * Users may belong to one or more groups
12
- */
13
- export const KnownGroups = {
14
- ZNET: 'zNet', // zNet team - full access
15
- CLIENT_PUBLIC: 'Client-Public', // Client-Public team - standard access
16
- ADMIN: 'admin', // Admin group - full access (if exists)
17
- } as const;
18
-
19
- /**
20
- * Permission level for operations
21
- */
22
- export enum PermissionLevel {
23
- READ = 'read',
24
- WRITE = 'write',
25
- ADMIN = 'admin',
26
- }
27
-
28
- /**
29
- * Tool permission configuration
30
- */
31
- export interface ToolPermission {
32
- tool: string;
33
- allowedGroups: string[]; // Changed from requiredRole to allowedGroups
34
- requiredPermission: PermissionLevel;
35
- }
36
-
37
- /**
38
- * Default permission rules for each tool
39
- * All authenticated users (with valid groups) can use these tools
40
- */
41
- const defaultPermissions: ToolPermission[] = [
42
- // sync_resources - available to all authenticated users
43
- {
44
- tool: 'sync_resources',
45
- allowedGroups: ['*'], // * means all authenticated users
46
- requiredPermission: PermissionLevel.WRITE,
47
- },
48
- // manage_subscription - available to all authenticated users
49
- {
50
- tool: 'manage_subscription',
51
- allowedGroups: ['*'],
52
- requiredPermission: PermissionLevel.WRITE,
53
- },
54
- // search_resources - read-only, all authenticated users
55
- {
56
- tool: 'search_resources',
57
- allowedGroups: ['*'],
58
- requiredPermission: PermissionLevel.READ,
59
- },
60
- // upload_resource - requires write permission
61
- {
62
- tool: 'upload_resource',
63
- allowedGroups: ['*'],
64
- requiredPermission: PermissionLevel.WRITE,
65
- },
66
- // uninstall_resource - requires write permission
67
- {
68
- tool: 'uninstall_resource',
69
- allowedGroups: ['*'],
70
- requiredPermission: PermissionLevel.WRITE,
71
- },
72
- // track_usage - internal telemetry tool, always allowed for all authenticated users
73
- {
74
- tool: 'track_usage',
75
- allowedGroups: ['*'],
76
- requiredPermission: PermissionLevel.WRITE,
77
- },
78
- ];
79
-
80
- /**
81
- * Custom permission rules (can be overridden via config)
82
- */
83
- let permissionRules: Map<string, ToolPermission> = new Map();
84
-
85
- /**
86
- * Initialize permission system
87
- */
88
- export function initializePermissions(customRules?: ToolPermission[]): void {
89
- // Load default permissions
90
- for (const perm of defaultPermissions) {
91
- permissionRules.set(perm.tool, perm);
92
- }
93
-
94
- // Override with custom rules if provided
95
- if (customRules && customRules.length > 0) {
96
- logger.info(
97
- { count: customRules.length },
98
- 'Loading custom permission rules'
99
- );
100
- for (const perm of customRules) {
101
- permissionRules.set(perm.tool, perm);
102
- }
103
- }
104
-
105
- logger.info(
106
- { toolCount: permissionRules.size },
107
- 'Permission system initialized'
108
- );
109
- }
110
-
111
- /**
112
- * Check if a user has permission to access a tool
113
- * @param toolName - The name of the tool to check
114
- * @param userGroups - The groups the user belongs to (from CSP API)
115
- */
116
- export function checkPermission(
117
- toolName: string,
118
- userGroups: string[]
119
- ): { allowed: boolean; reason?: string } {
120
- const checkStartTime = Date.now();
121
-
122
- logger.debug({
123
- type: 'permission_check',
124
- toolName,
125
- userGroups,
126
- timestamp: new Date().toISOString()
127
- }, `Checking permission for tool: ${toolName}`);
128
-
129
- // Check if tool has permission rules
130
- const permission = permissionRules.get(toolName);
131
- if (!permission) {
132
- // If no permission rule defined, deny by default
133
- logger.warn({
134
- type: 'permission_check',
135
- toolName,
136
- userGroups,
137
- result: 'denied',
138
- reason: 'no_rule',
139
- timestamp: new Date().toISOString()
140
- }, 'No permission rule found for tool, denying access');
141
-
142
- logAuthAttempt('permission_check', false, {
143
- toolName,
144
- userGroups,
145
- reason: 'no_rule',
146
- duration: Date.now() - checkStartTime
147
- });
148
-
149
- return {
150
- allowed: false,
151
- reason: `Tool '${toolName}' has no permission rule defined`,
152
- };
153
- }
154
-
155
- // If no groups provided, deny access
156
- if (!userGroups || userGroups.length === 0) {
157
- logger.warn(
158
- {
159
- type: 'permission_check',
160
- toolName,
161
- result: 'denied',
162
- reason: 'no_groups',
163
- timestamp: new Date().toISOString()
164
- },
165
- 'Permission denied: user has no groups'
166
- );
167
-
168
- logAuthAttempt('permission_check', false, {
169
- toolName,
170
- reason: 'no_groups',
171
- duration: Date.now() - checkStartTime
172
- });
173
-
174
- return {
175
- allowed: false,
176
- reason: `User must belong to at least one group to access tools`,
177
- };
178
- }
179
-
180
- // Admin group bypasses all checks
181
- if (userGroups.includes(KnownGroups.ADMIN) || userGroups.includes('admin')) {
182
- logger.info(
183
- {
184
- type: 'permission_check',
185
- toolName,
186
- userGroups,
187
- result: 'granted',
188
- reason: 'admin_bypass',
189
- duration: Date.now() - checkStartTime,
190
- timestamp: new Date().toISOString()
191
- },
192
- 'Admin group access granted'
193
- );
194
-
195
- logAuthAttempt('permission_check', true, {
196
- toolName,
197
- userGroups,
198
- reason: 'admin',
199
- duration: Date.now() - checkStartTime
200
- });
201
-
202
- return { allowed: true };
203
- }
204
-
205
- // Check if tool allows all authenticated users
206
- if (permission.allowedGroups.includes('*')) {
207
- logger.info(
208
- {
209
- type: 'permission_check',
210
- toolName,
211
- userGroups,
212
- allowedGroups: permission.allowedGroups,
213
- result: 'granted',
214
- reason: 'wildcard',
215
- duration: Date.now() - checkStartTime,
216
- timestamp: new Date().toISOString()
217
- },
218
- 'Permission granted (tool allows all authenticated users)'
219
- );
220
-
221
- logAuthAttempt('permission_check', true, {
222
- toolName,
223
- userGroups,
224
- reason: 'wildcard',
225
- duration: Date.now() - checkStartTime
226
- });
227
-
228
- return { allowed: true };
229
- }
230
-
231
- // Check if user belongs to any of the allowed groups
232
- const hasAllowedGroup = userGroups.some((group) =>
233
- permission.allowedGroups.includes(group)
234
- );
235
-
236
- if (!hasAllowedGroup) {
237
- logger.warn(
238
- {
239
- type: 'permission_check',
240
- toolName,
241
- userGroups,
242
- allowedGroups: permission.allowedGroups,
243
- result: 'denied',
244
- reason: 'group_mismatch',
245
- duration: Date.now() - checkStartTime,
246
- timestamp: new Date().toISOString()
247
- },
248
- 'Permission denied: user not in allowed groups'
249
- );
250
-
251
- logAuthAttempt('permission_check', false, {
252
- toolName,
253
- userGroups,
254
- allowedGroups: permission.allowedGroups,
255
- reason: 'group_mismatch',
256
- duration: Date.now() - checkStartTime
257
- });
258
-
259
- return {
260
- allowed: false,
261
- reason: `Tool '${toolName}' requires membership in one of: ${permission.allowedGroups.join(', ')}`,
262
- };
263
- }
264
-
265
- logger.info(
266
- {
267
- type: 'permission_check',
268
- toolName,
269
- userGroups,
270
- allowedGroups: permission.allowedGroups,
271
- result: 'granted',
272
- reason: 'group_match',
273
- duration: Date.now() - checkStartTime,
274
- timestamp: new Date().toISOString()
275
- },
276
- 'Permission granted (user in allowed groups)'
277
- );
278
-
279
- logAuthAttempt('permission_check', true, {
280
- toolName,
281
- userGroups,
282
- matchedGroups: userGroups.filter(g => permission.allowedGroups.includes(g)),
283
- duration: Date.now() - checkStartTime
284
- });
285
-
286
- return { allowed: true };
287
- }
288
-
289
- /**
290
- * Get permission info for a tool
291
- */
292
- export function getToolPermission(toolName: string): ToolPermission | undefined {
293
- return permissionRules.get(toolName);
294
- }
295
-
296
- /**
297
- * Get all permission rules
298
- */
299
- export function getAllPermissions(): ToolPermission[] {
300
- return Array.from(permissionRules.values());
301
- }
302
-
303
- /**
304
- * Update permission rule for a tool
305
- */
306
- export function updatePermission(permission: ToolPermission): void {
307
- permissionRules.set(permission.tool, permission);
308
- logger.info(
309
- { tool: permission.tool, permission },
310
- 'Permission rule updated'
311
- );
312
- }
313
-
314
- /**
315
- * Remove permission rule for a tool
316
- */
317
- export function removePermission(toolName: string): void {
318
- permissionRules.delete(toolName);
319
- logger.info({ toolName }, 'Permission rule removed');
320
- }
321
-
322
- // Initialize with default permissions
323
- initializePermissions();