@frontmcp/plugin-approval 1.8.5 → 1.8.7

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.
package/README.md CHANGED
@@ -72,6 +72,24 @@ class DangerousTool extends ToolContext {
72
72
  }
73
73
  ```
74
74
 
75
+ A refused call reaches the client as an error result whose text is exactly the tool's `approvalMessage` and whose
76
+ `_meta.code` is `APPROVAL_REQUIRED`, in production too: the approval errors extend `PublicMcpError`.
77
+
78
+ A grant made through `this.approval` records the signed-in caller as its grantor, `userGrantor(<user id>)`
79
+ (`{ source: 'user', identifier, method: 'interactive' }`), or `{ source: 'user' }` when there is no signed-in user
80
+ (an anonymous `anon:` subject included). Pass `grantedBy` to record something else:
81
+
82
+ ```typescript
83
+ import { policyGrantor, userGrantor } from '@frontmcp/plugin-approval';
84
+
85
+ await this.approval.grantSessionApproval('ops:deploy', { grantedBy: policyGrantor('safe-list') });
86
+ await this.approval.grantUserApproval('ops:deploy', {
87
+ grantedBy: userGrantor('user-123', 'Jane Doe', { method: 'interactive' }),
88
+ });
89
+ ```
90
+
91
+ `revokeApproval()` records `revokedBy` by the same rule.
92
+
75
93
  ### Approval Scopes
76
94
 
77
95
  | Scope | Description |
@@ -1,17 +1,18 @@
1
1
  /**
2
2
  * Error classes for approval operations.
3
3
  *
4
- * These are standalone error classes that can be extended by plugins
5
- * for MCP-specific error handling.
4
+ * They are public MCP errors: a refusal is an answer for the caller, so its message reaches the
5
+ * client as written, in every environment, instead of being wrapped as an internal server error.
6
6
  *
7
- * @module @frontmcp/utils/approval
7
+ * @module @frontmcp/plugin-approval
8
8
  */
9
+ import { PublicMcpError } from '@frontmcp/sdk';
9
10
  import type { ApprovalScope } from './types';
10
11
  /**
11
12
  * Base class for approval-related errors.
12
13
  */
13
- export declare class ApprovalError extends Error {
14
- constructor(message: string);
14
+ export declare class ApprovalError extends PublicMcpError {
15
+ constructor(message: string, code?: string, statusCode?: number);
15
16
  }
16
17
  /**
17
18
  * Error thrown when tool approval is required but not granted.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/approval/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;aAEpC,OAAO,EAAE;QACvB,sBAAsB;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,6BAA6B;QAC7B,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACxC,0BAA0B;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,0CAA0C;QAC1C,eAAe,CAAC,EAAE;YAChB,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;YAChC,YAAY,CAAC,EAAE,aAAa,CAAC;YAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;gBAfe,OAAO,EAAE;QACvB,sBAAsB;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,6BAA6B;QAC7B,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACxC,0BAA0B;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,0CAA0C;QAC1C,eAAe,CAAC,EAAE;YAChB,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;YAChC,YAAY,CAAC,EAAE,aAAa,CAAC;YAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;IAMH;;OAEG;IACH,cAAc;;;;;;;;gCAfQ,aAAa,EAAE;+BAChB,aAAa;2BACjB,MAAM;2BACN,MAAM;4BACL,MAAM;;;;CAuBzB;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,aAAa;aAErC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO;aACvC,MAAM,EAAE,MAAM;gBADd,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EACvC,MAAM,EAAE,MAAM;IAMhC;;OAEG;IACH,cAAc;;;;;;;;CAUf;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,aAAa;aAE3C,cAAc,EAAE,aAAa;aAC7B,aAAa,EAAE,aAAa,EAAE;gBAD9B,cAAc,EAAE,aAAa,EAC7B,aAAa,EAAE,aAAa,EAAE;IAShD;;OAEG;IACH,cAAc;;;;;;;;;CAWf;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,aAAa;aAEnC,MAAM,EAAE,MAAM;aACd,SAAS,EAAE,MAAM;gBADjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM;IAMnC;;OAEG;IACH,cAAc;;;;;;;;;CAWf;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,aAAa;aAEvC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc;gBAA5D,MAAM,GAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAA0B,EACxF,OAAO,CAAC,EAAE,MAAM;IAMlB;;OAEG;IACH,cAAc;;;;;;;;CAUf"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/approval/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;GAEG;AACH,qBAAa,aAAc,SAAQ,cAAc;gBACnC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAsB,EAAE,UAAU,SAAM;CAI1E;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;aAEpC,OAAO,EAAE;QACvB,sBAAsB;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,6BAA6B;QAC7B,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACxC,0BAA0B;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,0CAA0C;QAC1C,eAAe,CAAC,EAAE;YAChB,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;YAChC,YAAY,CAAC,EAAE,aAAa,CAAC;YAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;gBAfe,OAAO,EAAE;QACvB,sBAAsB;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,6BAA6B;QAC7B,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACxC,0BAA0B;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,0CAA0C;QAC1C,eAAe,CAAC,EAAE;YAChB,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;YAChC,YAAY,CAAC,EAAE,aAAa,CAAC;YAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;IAMH;;OAEG;IACH,cAAc;;;;;;;;gCAfQ,aAAa,EAAE;+BAChB,aAAa;2BACjB,MAAM;2BACN,MAAM;4BACL,MAAM;;;;CAuBzB;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,aAAa;aAErC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO;aACvC,MAAM,EAAE,MAAM;gBADd,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EACvC,MAAM,EAAE,MAAM;IAMhC;;OAEG;IACH,cAAc;;;;;;;;CAUf;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,aAAa;aAE3C,cAAc,EAAE,aAAa;aAC7B,aAAa,EAAE,aAAa,EAAE;gBAD9B,cAAc,EAAE,aAAa,EAC7B,aAAa,EAAE,aAAa,EAAE;IAWhD;;OAEG;IACH,cAAc;;;;;;;;;CAWf;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,aAAa;aAEnC,MAAM,EAAE,MAAM;aACd,SAAS,EAAE,MAAM;gBADjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM;IAMnC;;OAEG;IACH,cAAc;;;;;;;;;CAWf;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,aAAa;aAEvC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc;gBAA5D,MAAM,GAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAA0B,EACxF,OAAO,CAAC,EAAE,MAAM;IAMlB;;OAEG;IACH,cAAc;;;;;;;;CAUf"}
package/esm/index.mjs CHANGED
@@ -27,9 +27,10 @@ import {
27
27
  } from "@frontmcp/sdk";
28
28
 
29
29
  // plugins/plugin-approval/src/approval/errors.ts
30
- var ApprovalError = class extends Error {
31
- constructor(message) {
32
- super(message);
30
+ import { PublicMcpError } from "@frontmcp/sdk";
31
+ var ApprovalError = class extends PublicMcpError {
32
+ constructor(message, code = "APPROVAL_REQUIRED", statusCode = 403) {
33
+ super(message, code, statusCode);
33
34
  this.name = "ApprovalError";
34
35
  }
35
36
  };
@@ -59,7 +60,7 @@ var ApprovalRequiredError = class extends ApprovalError {
59
60
  };
60
61
  var ApprovalOperationError = class extends ApprovalError {
61
62
  constructor(operation, reason) {
62
- super(`Approval ${operation} failed: ${reason}`);
63
+ super(`Approval ${operation} failed: ${reason}`, "APPROVAL_OPERATION_FAILED", 400);
63
64
  this.operation = operation;
64
65
  this.reason = reason;
65
66
  this.name = "ApprovalOperationError";
@@ -84,7 +85,9 @@ var ApprovalOperationError = class extends ApprovalError {
84
85
  var ApprovalScopeNotAllowedError = class extends ApprovalError {
85
86
  constructor(requestedScope, allowedScopes) {
86
87
  super(
87
- `Approval scope '${requestedScope}' is not allowed for this tool. Allowed scopes: ${allowedScopes.join(", ")}`
88
+ `Approval scope '${requestedScope}' is not allowed for this tool. Allowed scopes: ${allowedScopes.join(", ")}`,
89
+ "APPROVAL_SCOPE_NOT_ALLOWED",
90
+ 400
88
91
  );
89
92
  this.requestedScope = requestedScope;
90
93
  this.allowedScopes = allowedScopes;
@@ -110,7 +113,7 @@ var ApprovalScopeNotAllowedError = class extends ApprovalError {
110
113
  };
111
114
  var ApprovalExpiredError = class extends ApprovalError {
112
115
  constructor(toolId, expiredAt) {
113
- super(`Approval for tool '${toolId}' expired at ${new Date(expiredAt).toISOString()}`);
116
+ super(`Approval for tool '${toolId}' expired at ${new Date(expiredAt).toISOString()}`, "APPROVAL_EXPIRED", 403);
114
117
  this.toolId = toolId;
115
118
  this.expiredAt = expiredAt;
116
119
  this.name = "ApprovalExpiredError";
@@ -135,7 +138,7 @@ var ApprovalExpiredError = class extends ApprovalError {
135
138
  };
136
139
  var ChallengeValidationError = class extends ApprovalError {
137
140
  constructor(reason = "invalid", message) {
138
- super(message ?? `PKCE challenge validation failed: ${reason}`);
141
+ super(message ?? `PKCE challenge validation failed: ${reason}`, "CHALLENGE_VALIDATION_FAILED", 400);
139
142
  this.reason = reason;
140
143
  this.name = "ChallengeValidationError";
141
144
  }
@@ -589,7 +592,7 @@ ApprovalCheckPlugin = __decorateClass([
589
592
  ], ApprovalCheckPlugin);
590
593
 
591
594
  // plugins/plugin-approval/src/services/approval.service.ts
592
- import { Provider, ProviderScope } from "@frontmcp/sdk";
595
+ import { isAnonymousSubject, Provider, ProviderScope } from "@frontmcp/sdk";
593
596
  var ApprovalService = class {
594
597
  constructor(store, sessionId, userId, requirementOf = () => void 0) {
595
598
  this.store = store;
@@ -605,6 +608,27 @@ var ApprovalService = class {
605
608
  checkGrant(toolId, scope, ttlMs) {
606
609
  return checkGrantAgainstPolicy(toolId, scope, ttlMs, this.requirementOf(toolId));
607
610
  }
611
+ /** The caller's user id, when it names a principal: an anonymous subject (`anon:…`) names no one. */
612
+ get signedInUserId() {
613
+ return this.userId && !isAnonymousSubject(this.userId) ? this.userId : void 0;
614
+ }
615
+ /**
616
+ * Who a grant is recorded as when the call names no one: the signed-in user whose tool call made it.
617
+ * It used to be `'policy'`, so an audit trail showed every approval a user gave as a policy's.
618
+ * Without a signed-in user it is a user with no identifier.
619
+ *
620
+ * The method is `'implicit'`: a tool that grants through `this.approval` asked no one, so the grant
621
+ * is not an `'interactive'` answer. A tool that did ask passes `grantedBy: userGrantor(id)`.
622
+ */
623
+ defaultGrantor() {
624
+ const userId = this.signedInUserId;
625
+ return userId ? userGrantor(userId, void 0, { method: "implicit" }) : { source: "user", method: "implicit" };
626
+ }
627
+ /** Who a revocation is recorded as when the call names no one, by the same rule as a grant. */
628
+ defaultRevoker() {
629
+ const userId = this.signedInUserId;
630
+ return userId ? { source: "user", identifier: userId, method: "implicit" } : { source: "user", method: "implicit" };
631
+ }
608
632
  // ─────────────────────────────────────────────────────────────────────────────
609
633
  // Query Methods
610
634
  // ─────────────────────────────────────────────────────────────────────────────
@@ -660,6 +684,13 @@ var ApprovalService = class {
660
684
  (record) => record.sessionId === this.sessionId || this.userId !== void 0 && record.userId === this.userId
661
685
  );
662
686
  }
687
+ /**
688
+ * The caller's recent revocations of a tool, newest last: each is the approval that was revoked,
689
+ * with `revokedBy`, `revokedAt` and `revocationReason`. Empty when the store keeps no revocations.
690
+ */
691
+ async getRevocations(toolId) {
692
+ return await this.store.getRevocations?.(toolId, this.sessionId, this.userId) ?? [];
693
+ }
663
694
  // ─────────────────────────────────────────────────────────────────────────────
664
695
  // Grant Methods
665
696
  // ─────────────────────────────────────────────────────────────────────────────
@@ -673,7 +704,7 @@ var ApprovalService = class {
673
704
  scope: "session" /* SESSION */,
674
705
  ttlMs,
675
706
  sessionId: this.sessionId,
676
- grantedBy: options.grantedBy ?? "policy",
707
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
677
708
  reason: options.reason,
678
709
  metadata: options.metadata
679
710
  });
@@ -691,7 +722,7 @@ var ApprovalService = class {
691
722
  scope: "user" /* USER */,
692
723
  ttlMs,
693
724
  userId: this.userId,
694
- grantedBy: options.grantedBy ?? "policy",
725
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
695
726
  reason: options.reason,
696
727
  metadata: options.metadata
697
728
  });
@@ -707,7 +738,7 @@ var ApprovalService = class {
707
738
  ttlMs,
708
739
  sessionId: this.sessionId,
709
740
  userId: this.userId,
710
- grantedBy: options.grantedBy ?? "policy",
741
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
711
742
  reason: options.reason,
712
743
  metadata: options.metadata
713
744
  });
@@ -724,7 +755,7 @@ var ApprovalService = class {
724
755
  context,
725
756
  sessionId: this.sessionId,
726
757
  userId: this.userId,
727
- grantedBy: options.grantedBy ?? "policy",
758
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
728
759
  reason: options.reason,
729
760
  metadata: options.metadata
730
761
  });
@@ -741,7 +772,7 @@ var ApprovalService = class {
741
772
  toolId,
742
773
  sessionId: this.sessionId,
743
774
  userId: this.userId,
744
- revokedBy: options.revokedBy ?? "policy",
775
+ revokedBy: options.revokedBy ?? this.defaultRevoker(),
745
776
  reason: options.reason
746
777
  });
747
778
  }
@@ -927,14 +958,18 @@ function createMemoryChallengeService(options = {}) {
927
958
  import { Provider as Provider3, ProviderScope as ProviderScope3 } from "@frontmcp/sdk";
928
959
  import {
929
960
  createMemoryStorage as createMemoryStorage2,
961
+ createNamespacedStorage,
930
962
  createStorage as createStorage2
931
963
  } from "@frontmcp/utils";
932
964
  function escapePattern(str) {
933
965
  return str.replace(/[*?[\]\\]/g, "\\$&");
934
966
  }
967
+ var REVOCATION_RETENTION_SECONDS = 24 * 60 * 60;
935
968
  var TIME_LIMITED_KEY_SEGMENT = `scope:${"time_limited" /* TIME_LIMITED */}`;
936
969
  var ApprovalStorageStore = class {
937
970
  storage;
971
+ /** Revoked approvals live beside the live ones, in a namespace no live-approval query scans. */
972
+ revocationStorage;
938
973
  options;
939
974
  cleanupInterval;
940
975
  initialized = false;
@@ -970,6 +1005,13 @@ var ApprovalStorageStore = class {
970
1005
  }
971
1006
  this.initialized = true;
972
1007
  }
1008
+ get revocations() {
1009
+ this.revocationStorage ??= createNamespacedStorage(
1010
+ this.storage.root,
1011
+ `${this.storage.prefix.replace(/:$/, "")}-revoked`
1012
+ );
1013
+ return this.revocationStorage;
1014
+ }
973
1015
  ensureInitialized() {
974
1016
  if (!this.initialized) {
975
1017
  throw new Error("ApprovalStorageStore not initialized. Call initialize() first.");
@@ -1131,27 +1173,43 @@ var ApprovalStorageStore = class {
1131
1173
  const keys = await this.storage.keys(`${escapePattern(toolId)}:*`);
1132
1174
  const values = await this.storage.mget(keys);
1133
1175
  const keysToDelete = [];
1176
+ const revoked = /* @__PURE__ */ new Map();
1134
1177
  for (let i = 0; i < keys.length; i++) {
1135
1178
  const record = this.parseRecord(values[i]);
1136
1179
  if (!record || record.toolId !== toolId || record.state === "denied" /* DENIED */) continue;
1180
+ const matches = keysToDelete.length;
1137
1181
  if (context) {
1138
1182
  const sameSession = sessionId !== void 0 && record.sessionId === sessionId;
1139
1183
  if (record.context?.type === context.type && record.context.identifier === context.identifier && (!sessionId || sameSession) && // A context approval granted to the session before it had a user applies to that user too.
1140
1184
  (!userId || record.userId === userId || sameSession && record.userId === void 0)) {
1141
1185
  keysToDelete.push(keys[i]);
1142
1186
  }
1143
- continue;
1144
- }
1145
- if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1187
+ } else if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1146
1188
  keysToDelete.push(keys[i]);
1147
1189
  }
1190
+ if (keysToDelete.length > matches) revoked.set(keys[i], record);
1148
1191
  }
1149
1192
  if (keysToDelete.length === 0) {
1150
1193
  return false;
1151
1194
  }
1195
+ const revokedAt = Date.now();
1196
+ const revokedBy = normalizeRevoker(options.revokedBy);
1197
+ for (const [key, record] of revoked) {
1198
+ const entry = { ...record, revokedAt, revokedBy, revocationReason: options.reason };
1199
+ await this.revocations.set(key, JSON.stringify(entry), { ttlSeconds: REVOCATION_RETENTION_SECONDS });
1200
+ }
1152
1201
  await this.storage.mdelete(keysToDelete);
1153
1202
  return true;
1154
1203
  }
1204
+ async getRevocations(toolId, sessionId, userId, context) {
1205
+ this.ensureInitialized();
1206
+ const records = [];
1207
+ for (const key of this.callerKeys(toolId, sessionId, userId, context)) {
1208
+ const record = this.parseRecord(await this.revocations.get(key));
1209
+ if (record && record.toolId === toolId) records.push(record);
1210
+ }
1211
+ return records.sort((a, b) => (a.revokedAt ?? 0) - (b.revokedAt ?? 0));
1212
+ }
1155
1213
  async isApproved(toolId, sessionId, userId, context) {
1156
1214
  const approval = await this.getApproval(toolId, sessionId, userId, context);
1157
1215
  return approval?.state === "approved" /* APPROVED */;
@@ -1227,6 +1285,7 @@ var ApprovalStorageStore = class {
1227
1285
  if (this.ownedStorage && this.storage) {
1228
1286
  await this.storage.root.disconnect();
1229
1287
  }
1288
+ this.revocationStorage = void 0;
1230
1289
  this.initialized = false;
1231
1290
  }
1232
1291
  };
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-approval",
3
- "version": "1.8.5",
3
+ "version": "1.8.7",
4
4
  "description": "Approval plugin for FrontMCP - tool authorization workflow with PKCE webhook security",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -49,13 +49,13 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@frontmcp/sdk": "1.8.5",
53
- "@frontmcp/utils": "1.8.5",
52
+ "@frontmcp/sdk": "1.8.7",
53
+ "@frontmcp/utils": "1.8.7",
54
54
  "ioredis": "^5.8.0",
55
55
  "reflect-metadata": "^0.2.2"
56
56
  },
57
57
  "peerDependencies": {
58
- "@frontmcp/lazy-zod": "1.8.5",
58
+ "@frontmcp/lazy-zod": "1.8.7",
59
59
  "@vercel/kv": "^2.0.0 || ^3.0.0"
60
60
  },
61
61
  "peerDependenciesMeta": {
package/index.js CHANGED
@@ -76,12 +76,13 @@ __export(index_exports, {
76
76
  module.exports = __toCommonJS(index_exports);
77
77
 
78
78
  // plugins/plugin-approval/src/approval.plugin.ts
79
- var import_sdk5 = require("@frontmcp/sdk");
79
+ var import_sdk6 = require("@frontmcp/sdk");
80
80
 
81
81
  // plugins/plugin-approval/src/approval/errors.ts
82
- var ApprovalError = class extends Error {
83
- constructor(message) {
84
- super(message);
82
+ var import_sdk = require("@frontmcp/sdk");
83
+ var ApprovalError = class extends import_sdk.PublicMcpError {
84
+ constructor(message, code = "APPROVAL_REQUIRED", statusCode = 403) {
85
+ super(message, code, statusCode);
85
86
  this.name = "ApprovalError";
86
87
  }
87
88
  };
@@ -111,7 +112,7 @@ var ApprovalRequiredError = class extends ApprovalError {
111
112
  };
112
113
  var ApprovalOperationError = class extends ApprovalError {
113
114
  constructor(operation, reason) {
114
- super(`Approval ${operation} failed: ${reason}`);
115
+ super(`Approval ${operation} failed: ${reason}`, "APPROVAL_OPERATION_FAILED", 400);
115
116
  this.operation = operation;
116
117
  this.reason = reason;
117
118
  this.name = "ApprovalOperationError";
@@ -136,7 +137,9 @@ var ApprovalOperationError = class extends ApprovalError {
136
137
  var ApprovalScopeNotAllowedError = class extends ApprovalError {
137
138
  constructor(requestedScope, allowedScopes) {
138
139
  super(
139
- `Approval scope '${requestedScope}' is not allowed for this tool. Allowed scopes: ${allowedScopes.join(", ")}`
140
+ `Approval scope '${requestedScope}' is not allowed for this tool. Allowed scopes: ${allowedScopes.join(", ")}`,
141
+ "APPROVAL_SCOPE_NOT_ALLOWED",
142
+ 400
140
143
  );
141
144
  this.requestedScope = requestedScope;
142
145
  this.allowedScopes = allowedScopes;
@@ -162,7 +165,7 @@ var ApprovalScopeNotAllowedError = class extends ApprovalError {
162
165
  };
163
166
  var ApprovalExpiredError = class extends ApprovalError {
164
167
  constructor(toolId, expiredAt) {
165
- super(`Approval for tool '${toolId}' expired at ${new Date(expiredAt).toISOString()}`);
168
+ super(`Approval for tool '${toolId}' expired at ${new Date(expiredAt).toISOString()}`, "APPROVAL_EXPIRED", 403);
166
169
  this.toolId = toolId;
167
170
  this.expiredAt = expiredAt;
168
171
  this.name = "ApprovalExpiredError";
@@ -187,7 +190,7 @@ var ApprovalExpiredError = class extends ApprovalError {
187
190
  };
188
191
  var ChallengeValidationError = class extends ApprovalError {
189
192
  constructor(reason = "invalid", message) {
190
- super(message ?? `PKCE challenge validation failed: ${reason}`);
193
+ super(message ?? `PKCE challenge validation failed: ${reason}`, "CHALLENGE_VALIDATION_FAILED", 400);
191
194
  this.reason = reason;
192
195
  this.name = "ChallengeValidationError";
193
196
  }
@@ -304,7 +307,7 @@ var ChallengeServiceToken = /* @__PURE__ */ Symbol.for(
304
307
  );
305
308
 
306
309
  // plugins/plugin-approval/src/hooks/approval-check.hook.ts
307
- var import_sdk = require("@frontmcp/sdk");
310
+ var import_sdk2 = require("@frontmcp/sdk");
308
311
 
309
312
  // plugins/plugin-approval/src/approval/schemas.ts
310
313
  var import_lazy_zod = require("@frontmcp/lazy-zod");
@@ -524,7 +527,7 @@ function isApiGrantor(grantor) {
524
527
 
525
528
  // plugins/plugin-approval/src/hooks/approval-check.hook.ts
526
529
  var passedApprovalStores = /* @__PURE__ */ new WeakMap();
527
- var ApprovalCheckPlugin = class extends import_sdk.DynamicPlugin {
530
+ var ApprovalCheckPlugin = class extends import_sdk2.DynamicPlugin {
528
531
  async checkApproval(flowCtx) {
529
532
  const { tool, toolContext } = flowCtx.state;
530
533
  if (!tool || !toolContext) return;
@@ -629,10 +632,10 @@ var ApprovalCheckPlugin = class extends import_sdk.DynamicPlugin {
629
632
  }
630
633
  };
631
634
  __decorateClass([
632
- import_sdk.ToolHook.Will("execute", { priority: 100, appliesTo: "uncovered-apps" })
635
+ import_sdk2.ToolHook.Will("execute", { priority: 100, appliesTo: "uncovered-apps" })
633
636
  ], ApprovalCheckPlugin.prototype, "checkApproval", 1);
634
637
  ApprovalCheckPlugin = __decorateClass([
635
- (0, import_sdk.Plugin)({
638
+ (0, import_sdk2.Plugin)({
636
639
  name: "approval:check",
637
640
  description: "Checks tool approval state before execution",
638
641
  // A server where a tool or agent declares `approval` and this gate does not reach it refuses to start.
@@ -641,7 +644,7 @@ ApprovalCheckPlugin = __decorateClass([
641
644
  ], ApprovalCheckPlugin);
642
645
 
643
646
  // plugins/plugin-approval/src/services/approval.service.ts
644
- var import_sdk2 = require("@frontmcp/sdk");
647
+ var import_sdk3 = require("@frontmcp/sdk");
645
648
  var ApprovalService = class {
646
649
  constructor(store, sessionId, userId, requirementOf = () => void 0) {
647
650
  this.store = store;
@@ -657,6 +660,27 @@ var ApprovalService = class {
657
660
  checkGrant(toolId, scope, ttlMs) {
658
661
  return checkGrantAgainstPolicy(toolId, scope, ttlMs, this.requirementOf(toolId));
659
662
  }
663
+ /** The caller's user id, when it names a principal: an anonymous subject (`anon:…`) names no one. */
664
+ get signedInUserId() {
665
+ return this.userId && !(0, import_sdk3.isAnonymousSubject)(this.userId) ? this.userId : void 0;
666
+ }
667
+ /**
668
+ * Who a grant is recorded as when the call names no one: the signed-in user whose tool call made it.
669
+ * It used to be `'policy'`, so an audit trail showed every approval a user gave as a policy's.
670
+ * Without a signed-in user it is a user with no identifier.
671
+ *
672
+ * The method is `'implicit'`: a tool that grants through `this.approval` asked no one, so the grant
673
+ * is not an `'interactive'` answer. A tool that did ask passes `grantedBy: userGrantor(id)`.
674
+ */
675
+ defaultGrantor() {
676
+ const userId = this.signedInUserId;
677
+ return userId ? userGrantor(userId, void 0, { method: "implicit" }) : { source: "user", method: "implicit" };
678
+ }
679
+ /** Who a revocation is recorded as when the call names no one, by the same rule as a grant. */
680
+ defaultRevoker() {
681
+ const userId = this.signedInUserId;
682
+ return userId ? { source: "user", identifier: userId, method: "implicit" } : { source: "user", method: "implicit" };
683
+ }
660
684
  // ─────────────────────────────────────────────────────────────────────────────
661
685
  // Query Methods
662
686
  // ─────────────────────────────────────────────────────────────────────────────
@@ -712,6 +736,13 @@ var ApprovalService = class {
712
736
  (record) => record.sessionId === this.sessionId || this.userId !== void 0 && record.userId === this.userId
713
737
  );
714
738
  }
739
+ /**
740
+ * The caller's recent revocations of a tool, newest last: each is the approval that was revoked,
741
+ * with `revokedBy`, `revokedAt` and `revocationReason`. Empty when the store keeps no revocations.
742
+ */
743
+ async getRevocations(toolId) {
744
+ return await this.store.getRevocations?.(toolId, this.sessionId, this.userId) ?? [];
745
+ }
715
746
  // ─────────────────────────────────────────────────────────────────────────────
716
747
  // Grant Methods
717
748
  // ─────────────────────────────────────────────────────────────────────────────
@@ -725,7 +756,7 @@ var ApprovalService = class {
725
756
  scope: "session" /* SESSION */,
726
757
  ttlMs,
727
758
  sessionId: this.sessionId,
728
- grantedBy: options.grantedBy ?? "policy",
759
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
729
760
  reason: options.reason,
730
761
  metadata: options.metadata
731
762
  });
@@ -743,7 +774,7 @@ var ApprovalService = class {
743
774
  scope: "user" /* USER */,
744
775
  ttlMs,
745
776
  userId: this.userId,
746
- grantedBy: options.grantedBy ?? "policy",
777
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
747
778
  reason: options.reason,
748
779
  metadata: options.metadata
749
780
  });
@@ -759,7 +790,7 @@ var ApprovalService = class {
759
790
  ttlMs,
760
791
  sessionId: this.sessionId,
761
792
  userId: this.userId,
762
- grantedBy: options.grantedBy ?? "policy",
793
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
763
794
  reason: options.reason,
764
795
  metadata: options.metadata
765
796
  });
@@ -776,7 +807,7 @@ var ApprovalService = class {
776
807
  context,
777
808
  sessionId: this.sessionId,
778
809
  userId: this.userId,
779
- grantedBy: options.grantedBy ?? "policy",
810
+ grantedBy: options.grantedBy ?? this.defaultGrantor(),
780
811
  reason: options.reason,
781
812
  metadata: options.metadata
782
813
  });
@@ -793,7 +824,7 @@ var ApprovalService = class {
793
824
  toolId,
794
825
  sessionId: this.sessionId,
795
826
  userId: this.userId,
796
- revokedBy: options.revokedBy ?? "policy",
827
+ revokedBy: options.revokedBy ?? this.defaultRevoker(),
797
828
  reason: options.reason
798
829
  });
799
830
  }
@@ -805,10 +836,10 @@ var ApprovalService = class {
805
836
  }
806
837
  };
807
838
  ApprovalService = __decorateClass([
808
- (0, import_sdk2.Provider)({
839
+ (0, import_sdk3.Provider)({
809
840
  name: "provider:approval:service",
810
841
  description: "Service for managing tool approvals",
811
- scope: import_sdk2.ProviderScope.CONTEXT
842
+ scope: import_sdk3.ProviderScope.CONTEXT
812
843
  })
813
844
  ], ApprovalService);
814
845
  function createApprovalService(store, sessionId, userId, requirementOf) {
@@ -816,7 +847,7 @@ function createApprovalService(store, sessionId, userId, requirementOf) {
816
847
  }
817
848
 
818
849
  // plugins/plugin-approval/src/services/challenge.service.ts
819
- var import_sdk3 = require("@frontmcp/sdk");
850
+ var import_sdk4 = require("@frontmcp/sdk");
820
851
  var import_utils2 = require("@frontmcp/utils");
821
852
  var ChallengeService = class {
822
853
  storage;
@@ -950,10 +981,10 @@ var ChallengeService = class {
950
981
  }
951
982
  };
952
983
  ChallengeService = __decorateClass([
953
- (0, import_sdk3.Provider)({
984
+ (0, import_sdk4.Provider)({
954
985
  name: "provider:approval:challenge-service",
955
986
  description: "PKCE challenge service for webhook approval flows",
956
- scope: import_sdk3.ProviderScope.GLOBAL
987
+ scope: import_sdk4.ProviderScope.GLOBAL
957
988
  })
958
989
  ], ChallengeService);
959
990
  function generatePkcePairFromVerifier(codeVerifier) {
@@ -971,14 +1002,17 @@ function createMemoryChallengeService(options = {}) {
971
1002
  }
972
1003
 
973
1004
  // plugins/plugin-approval/src/stores/approval-storage.store.ts
974
- var import_sdk4 = require("@frontmcp/sdk");
1005
+ var import_sdk5 = require("@frontmcp/sdk");
975
1006
  var import_utils3 = require("@frontmcp/utils");
976
1007
  function escapePattern(str) {
977
1008
  return str.replace(/[*?[\]\\]/g, "\\$&");
978
1009
  }
1010
+ var REVOCATION_RETENTION_SECONDS = 24 * 60 * 60;
979
1011
  var TIME_LIMITED_KEY_SEGMENT = `scope:${"time_limited" /* TIME_LIMITED */}`;
980
1012
  var ApprovalStorageStore = class {
981
1013
  storage;
1014
+ /** Revoked approvals live beside the live ones, in a namespace no live-approval query scans. */
1015
+ revocationStorage;
982
1016
  options;
983
1017
  cleanupInterval;
984
1018
  initialized = false;
@@ -1014,6 +1048,13 @@ var ApprovalStorageStore = class {
1014
1048
  }
1015
1049
  this.initialized = true;
1016
1050
  }
1051
+ get revocations() {
1052
+ this.revocationStorage ??= (0, import_utils3.createNamespacedStorage)(
1053
+ this.storage.root,
1054
+ `${this.storage.prefix.replace(/:$/, "")}-revoked`
1055
+ );
1056
+ return this.revocationStorage;
1057
+ }
1017
1058
  ensureInitialized() {
1018
1059
  if (!this.initialized) {
1019
1060
  throw new Error("ApprovalStorageStore not initialized. Call initialize() first.");
@@ -1175,27 +1216,43 @@ var ApprovalStorageStore = class {
1175
1216
  const keys = await this.storage.keys(`${escapePattern(toolId)}:*`);
1176
1217
  const values = await this.storage.mget(keys);
1177
1218
  const keysToDelete = [];
1219
+ const revoked = /* @__PURE__ */ new Map();
1178
1220
  for (let i = 0; i < keys.length; i++) {
1179
1221
  const record = this.parseRecord(values[i]);
1180
1222
  if (!record || record.toolId !== toolId || record.state === "denied" /* DENIED */) continue;
1223
+ const matches = keysToDelete.length;
1181
1224
  if (context) {
1182
1225
  const sameSession = sessionId !== void 0 && record.sessionId === sessionId;
1183
1226
  if (record.context?.type === context.type && record.context.identifier === context.identifier && (!sessionId || sameSession) && // A context approval granted to the session before it had a user applies to that user too.
1184
1227
  (!userId || record.userId === userId || sameSession && record.userId === void 0)) {
1185
1228
  keysToDelete.push(keys[i]);
1186
1229
  }
1187
- continue;
1188
- }
1189
- if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1230
+ } else if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1190
1231
  keysToDelete.push(keys[i]);
1191
1232
  }
1233
+ if (keysToDelete.length > matches) revoked.set(keys[i], record);
1192
1234
  }
1193
1235
  if (keysToDelete.length === 0) {
1194
1236
  return false;
1195
1237
  }
1238
+ const revokedAt = Date.now();
1239
+ const revokedBy = normalizeRevoker(options.revokedBy);
1240
+ for (const [key, record] of revoked) {
1241
+ const entry = { ...record, revokedAt, revokedBy, revocationReason: options.reason };
1242
+ await this.revocations.set(key, JSON.stringify(entry), { ttlSeconds: REVOCATION_RETENTION_SECONDS });
1243
+ }
1196
1244
  await this.storage.mdelete(keysToDelete);
1197
1245
  return true;
1198
1246
  }
1247
+ async getRevocations(toolId, sessionId, userId, context) {
1248
+ this.ensureInitialized();
1249
+ const records = [];
1250
+ for (const key of this.callerKeys(toolId, sessionId, userId, context)) {
1251
+ const record = this.parseRecord(await this.revocations.get(key));
1252
+ if (record && record.toolId === toolId) records.push(record);
1253
+ }
1254
+ return records.sort((a, b) => (a.revokedAt ?? 0) - (b.revokedAt ?? 0));
1255
+ }
1199
1256
  async isApproved(toolId, sessionId, userId, context) {
1200
1257
  const approval = await this.getApproval(toolId, sessionId, userId, context);
1201
1258
  return approval?.state === "approved" /* APPROVED */;
@@ -1271,14 +1328,15 @@ var ApprovalStorageStore = class {
1271
1328
  if (this.ownedStorage && this.storage) {
1272
1329
  await this.storage.root.disconnect();
1273
1330
  }
1331
+ this.revocationStorage = void 0;
1274
1332
  this.initialized = false;
1275
1333
  }
1276
1334
  };
1277
1335
  ApprovalStorageStore = __decorateClass([
1278
- (0, import_sdk4.Provider)({
1336
+ (0, import_sdk5.Provider)({
1279
1337
  name: "provider:approval:store:storage",
1280
1338
  description: "Storage-backed approval store (supports Memory, Redis, Vercel KV, Upstash)",
1281
- scope: import_sdk4.ProviderScope.GLOBAL
1339
+ scope: import_sdk5.ProviderScope.GLOBAL
1282
1340
  })
1283
1341
  ], ApprovalStorageStore);
1284
1342
  function createApprovalMemoryStore(options = {}) {
@@ -1290,7 +1348,7 @@ function createApprovalMemoryStore(options = {}) {
1290
1348
  }
1291
1349
 
1292
1350
  // plugins/plugin-approval/src/approval.plugin.ts
1293
- var ApprovalPlugin = class extends import_sdk5.DynamicPlugin {
1351
+ var ApprovalPlugin = class extends import_sdk6.DynamicPlugin {
1294
1352
  options;
1295
1353
  constructor(options = {}) {
1296
1354
  super();
@@ -1351,8 +1409,8 @@ __publicField(ApprovalPlugin, "dynamicProviders", (options) => {
1351
1409
  providers.push({
1352
1410
  name: "approval:service",
1353
1411
  provide: ApprovalServiceToken,
1354
- scope: import_sdk5.ProviderScope.CONTEXT,
1355
- inject: () => [ApprovalStoreToken, import_sdk5.FRONTMCP_CONTEXT, import_sdk5.ScopeEntry],
1412
+ scope: import_sdk6.ProviderScope.CONTEXT,
1413
+ inject: () => [ApprovalStoreToken, import_sdk6.FRONTMCP_CONTEXT, import_sdk6.ScopeEntry],
1356
1414
  useFactory: (store, ctx, scope) => {
1357
1415
  const { sessionId, userId } = resolveApprovalIdentity(ctx);
1358
1416
  const requirementOf = (toolId) => {
@@ -1367,7 +1425,7 @@ __publicField(ApprovalPlugin, "dynamicProviders", (options) => {
1367
1425
  return providers;
1368
1426
  });
1369
1427
  ApprovalPlugin = __decorateClass([
1370
- (0, import_sdk5.Plugin)({
1428
+ (0, import_sdk6.Plugin)({
1371
1429
  name: "approval",
1372
1430
  description: "Tool authorization workflow with PKCE webhook security",
1373
1431
  plugins: [ApprovalCheckPlugin],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-approval",
3
- "version": "1.8.5",
3
+ "version": "1.8.7",
4
4
  "description": "Approval plugin for FrontMCP - tool authorization workflow with PKCE webhook security",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -49,13 +49,13 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@frontmcp/sdk": "1.8.5",
53
- "@frontmcp/utils": "1.8.5",
52
+ "@frontmcp/sdk": "1.8.7",
53
+ "@frontmcp/utils": "1.8.7",
54
54
  "ioredis": "^5.8.0",
55
55
  "reflect-metadata": "^0.2.2"
56
56
  },
57
57
  "peerDependencies": {
58
- "@frontmcp/lazy-zod": "1.8.5",
58
+ "@frontmcp/lazy-zod": "1.8.7",
59
59
  "@vercel/kv": "^2.0.0 || ^3.0.0"
60
60
  },
61
61
  "peerDependenciesMeta": {
@@ -14,7 +14,7 @@ export type ApprovalRequirementLookup = (toolId: string) => ToolApprovalRequirem
14
14
  * Options for granting approvals via the service.
15
15
  */
16
16
  export interface GrantOptions {
17
- /** Who/what is granting the approval (defaults to 'policy') */
17
+ /** Who/what is granting the approval (defaults to the signed-in user, or `{ source: 'user' }` without one) */
18
18
  grantedBy?: ApprovalGrantor | ApprovalSourceType;
19
19
  /** Optional reason for the approval */
20
20
  reason?: string;
@@ -25,7 +25,7 @@ export interface GrantOptions {
25
25
  * Options for revoking approvals via the service.
26
26
  */
27
27
  export interface RevokeOptions {
28
- /** Who/what is revoking the approval (defaults to 'policy') */
28
+ /** Who/what is revoking the approval (defaults to the signed-in user, or `{ source: 'user' }` without one) */
29
29
  revokedBy?: ApprovalRevoker | RevocationSourceType;
30
30
  /** Optional reason for revocation */
31
31
  reason?: string;
@@ -41,6 +41,19 @@ export declare class ApprovalService {
41
41
  constructor(store: ApprovalStore, sessionId: string, userId?: string | undefined, requirementOf?: ApprovalRequirementLookup);
42
42
  /** Checks a grant against the tool's `allowedScopes` and `maxTtlMs`; returns the ttl to store. */
43
43
  private checkGrant;
44
+ /** The caller's user id, when it names a principal: an anonymous subject (`anon:…`) names no one. */
45
+ private get signedInUserId();
46
+ /**
47
+ * Who a grant is recorded as when the call names no one: the signed-in user whose tool call made it.
48
+ * It used to be `'policy'`, so an audit trail showed every approval a user gave as a policy's.
49
+ * Without a signed-in user it is a user with no identifier.
50
+ *
51
+ * The method is `'implicit'`: a tool that grants through `this.approval` asked no one, so the grant
52
+ * is not an `'interactive'` answer. A tool that did ask passes `grantedBy: userGrantor(id)`.
53
+ */
54
+ private defaultGrantor;
55
+ /** Who a revocation is recorded as when the call names no one, by the same rule as a grant. */
56
+ private defaultRevoker;
44
57
  /**
45
58
  * Check if a tool is approved for current session/user.
46
59
  */
@@ -63,6 +76,11 @@ export declare class ApprovalService {
63
76
  * another caller's records. Read the store directly for administrative queries.
64
77
  */
65
78
  queryApprovals(query: Partial<ApprovalQuery>): Promise<ApprovalRecord[]>;
79
+ /**
80
+ * The caller's recent revocations of a tool, newest last: each is the approval that was revoked,
81
+ * with `revokedBy`, `revokedAt` and `revocationReason`. Empty when the store keeps no revocations.
82
+ */
83
+ getRevocations(toolId: string): Promise<ApprovalRecord[]>;
66
84
  /**
67
85
  * Grant session-scoped approval for a tool.
68
86
  */
@@ -1 +1 @@
1
- {"version":3,"file":"approval.service.d.ts","sourceRoot":"","sources":["../../src/services/approval.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC7B,MAAM,UAAU,CAAC;AAElB;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,uBAAuB,GAAG,SAAS,CAAC;AAEhG;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,SAAS,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAAC;IACjD,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,SAAS,CAAC,EAAE,eAAe,GAAG,oBAAoB,CAAC;IACnD,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,qBAKa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAHb,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,aAAa,GAAE,yBAA2C;IAG7E,kGAAkG;IAClG,OAAO,CAAC,UAAU;IAQlB;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAY7E;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAItE;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAQtD;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAUnD;;;;OAIG;IACG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAW9E;;OAEG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAa/F;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAgB5F;;OAEG;IACG,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAclH;;OAEG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,EACxB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,cAAc,CAAC;IAmB1B;;;OAGG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnF;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,yBAAyB,GACxC,eAAe,CAEjB"}
1
+ {"version":3,"file":"approval.service.d.ts","sourceRoot":"","sources":["../../src/services/approval.service.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,8 @@ export interface ApprovalStorageStoreOptions {
37
37
  */
38
38
  export declare class ApprovalStorageStore implements ApprovalStore {
39
39
  private storage;
40
+ /** Revoked approvals live beside the live ones, in a namespace no live-approval query scans. */
41
+ private revocationStorage?;
40
42
  private readonly options;
41
43
  private cleanupInterval?;
42
44
  private initialized;
@@ -46,6 +48,7 @@ export declare class ApprovalStorageStore implements ApprovalStore {
46
48
  * Initialize the storage connection.
47
49
  */
48
50
  initialize(): Promise<void>;
51
+ private get revocations();
49
52
  private ensureInitialized;
50
53
  private buildKey;
51
54
  /**
@@ -85,6 +88,7 @@ export declare class ApprovalStorageStore implements ApprovalStore {
85
88
  * (session, user, time-limited and context approvals alike). Recorded denials are kept.
86
89
  */
87
90
  revokeApproval(options: RevokeApprovalOptions): Promise<boolean>;
91
+ getRevocations(toolId: string, sessionId: string, userId?: string, context?: ApprovalContext): Promise<ApprovalRecord[]>;
88
92
  isApproved(toolId: string, sessionId: string, userId?: string, context?: ApprovalContext): Promise<boolean>;
89
93
  clearSessionApprovals(sessionId: string): Promise<number>;
90
94
  clearExpiredApprovals(): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"approval-storage.store.d.ts","sourceRoot":"","sources":["../../src/stores/approval-storage.store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACnG,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,4BAA4B,CAAC;AAqBpC;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;OAEG;IACH,eAAe,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;IAElD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAMD;;;GAGG;AACH,qBAKa,oBAAqB,YAAW,aAAa;IACxD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IACF,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,GAAE,2BAAgC;IASrD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBjC,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,QAAQ;IAQhB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAItB,4CAA4C;IAC5C,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,SAAS;IAIjB;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU;IAgBlB;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,EAAE,CAAC;IAa5B;;;OAGG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAKhC,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAwC/D,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAkC3E;;;;OAIG;IACG,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IAuChE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3G,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBzD,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAuBxC,QAAQ,IAAI,OAAO,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;KACxC,CAAC;IAsCI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,IAAI,CAAC,2BAA2B,EAAE,SAAS,GAAG,iBAAiB,CAAM,GAC7E,oBAAoB,CAMtB"}
1
+ {"version":3,"file":"approval-storage.store.d.ts","sourceRoot":"","sources":["../../src/stores/approval-storage.store.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @module @frontmcp/plugin-approval
5
5
  */
6
- import type { ApprovalScope, ApprovalState, ApprovalContext, ApprovalGrantor, ApprovalRevoker, ApprovalRecord, ApprovalSourceType, RevocationSourceType } from '../types';
6
+ import type { ApprovalContext, ApprovalGrantor, ApprovalRecord, ApprovalRevoker, ApprovalScope, ApprovalSourceType, ApprovalState, RevocationSourceType } from '../types';
7
7
  /**
8
8
  * Query options for finding approvals.
9
9
  */
@@ -101,6 +101,11 @@ export interface ApprovalStore {
101
101
  * (only the given context's, when `context` is set). Recorded denials are kept.
102
102
  */
103
103
  revokeApproval(options: RevokeApprovalOptions): Promise<boolean>;
104
+ /**
105
+ * The caller's recent revocations of a tool: each is the approval that was revoked, with `revokedBy`,
106
+ * `revokedAt` and `revocationReason`. Optional: a store that keeps no revocations leaves it out.
107
+ */
108
+ getRevocations?(toolId: string, sessionId: string, userId?: string, context?: ApprovalContext): Promise<ApprovalRecord[]>;
104
109
  /**
105
110
  * Check if a tool is approved.
106
111
  */
@@ -1 +1 @@
1
- {"version":3,"file":"approval-store.interface.d.ts","sourceRoot":"","sources":["../../src/stores/approval-store.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approval-store.interface.d.ts","sourceRoot":"","sources":["../../src/stores/approval-store.interface.ts"],"names":[],"mappings":"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"}