@frontmcp/plugin-approval 1.8.6 → 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/esm/index.mjs CHANGED
@@ -615,16 +615,19 @@ var ApprovalService = class {
615
615
  /**
616
616
  * Who a grant is recorded as when the call names no one: the signed-in user whose tool call made it.
617
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 the store's default, a user with no identifier.
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)`.
619
622
  */
620
623
  defaultGrantor() {
621
624
  const userId = this.signedInUserId;
622
- return userId ? userGrantor(userId) : { source: "user" };
625
+ return userId ? userGrantor(userId, void 0, { method: "implicit" }) : { source: "user", method: "implicit" };
623
626
  }
624
627
  /** Who a revocation is recorded as when the call names no one, by the same rule as a grant. */
625
628
  defaultRevoker() {
626
629
  const userId = this.signedInUserId;
627
- return userId ? userRevoker(userId) : { source: "user" };
630
+ return userId ? { source: "user", identifier: userId, method: "implicit" } : { source: "user", method: "implicit" };
628
631
  }
629
632
  // ─────────────────────────────────────────────────────────────────────────────
630
633
  // Query Methods
@@ -681,6 +684,13 @@ var ApprovalService = class {
681
684
  (record) => record.sessionId === this.sessionId || this.userId !== void 0 && record.userId === this.userId
682
685
  );
683
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
+ }
684
694
  // ─────────────────────────────────────────────────────────────────────────────
685
695
  // Grant Methods
686
696
  // ─────────────────────────────────────────────────────────────────────────────
@@ -948,14 +958,18 @@ function createMemoryChallengeService(options = {}) {
948
958
  import { Provider as Provider3, ProviderScope as ProviderScope3 } from "@frontmcp/sdk";
949
959
  import {
950
960
  createMemoryStorage as createMemoryStorage2,
961
+ createNamespacedStorage,
951
962
  createStorage as createStorage2
952
963
  } from "@frontmcp/utils";
953
964
  function escapePattern(str) {
954
965
  return str.replace(/[*?[\]\\]/g, "\\$&");
955
966
  }
967
+ var REVOCATION_RETENTION_SECONDS = 24 * 60 * 60;
956
968
  var TIME_LIMITED_KEY_SEGMENT = `scope:${"time_limited" /* TIME_LIMITED */}`;
957
969
  var ApprovalStorageStore = class {
958
970
  storage;
971
+ /** Revoked approvals live beside the live ones, in a namespace no live-approval query scans. */
972
+ revocationStorage;
959
973
  options;
960
974
  cleanupInterval;
961
975
  initialized = false;
@@ -991,6 +1005,13 @@ var ApprovalStorageStore = class {
991
1005
  }
992
1006
  this.initialized = true;
993
1007
  }
1008
+ get revocations() {
1009
+ this.revocationStorage ??= createNamespacedStorage(
1010
+ this.storage.root,
1011
+ `${this.storage.prefix.replace(/:$/, "")}-revoked`
1012
+ );
1013
+ return this.revocationStorage;
1014
+ }
994
1015
  ensureInitialized() {
995
1016
  if (!this.initialized) {
996
1017
  throw new Error("ApprovalStorageStore not initialized. Call initialize() first.");
@@ -1152,27 +1173,43 @@ var ApprovalStorageStore = class {
1152
1173
  const keys = await this.storage.keys(`${escapePattern(toolId)}:*`);
1153
1174
  const values = await this.storage.mget(keys);
1154
1175
  const keysToDelete = [];
1176
+ const revoked = /* @__PURE__ */ new Map();
1155
1177
  for (let i = 0; i < keys.length; i++) {
1156
1178
  const record = this.parseRecord(values[i]);
1157
1179
  if (!record || record.toolId !== toolId || record.state === "denied" /* DENIED */) continue;
1180
+ const matches = keysToDelete.length;
1158
1181
  if (context) {
1159
1182
  const sameSession = sessionId !== void 0 && record.sessionId === sessionId;
1160
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.
1161
1184
  (!userId || record.userId === userId || sameSession && record.userId === void 0)) {
1162
1185
  keysToDelete.push(keys[i]);
1163
1186
  }
1164
- continue;
1165
- }
1166
- if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1187
+ } else if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1167
1188
  keysToDelete.push(keys[i]);
1168
1189
  }
1190
+ if (keysToDelete.length > matches) revoked.set(keys[i], record);
1169
1191
  }
1170
1192
  if (keysToDelete.length === 0) {
1171
1193
  return false;
1172
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
+ }
1173
1201
  await this.storage.mdelete(keysToDelete);
1174
1202
  return true;
1175
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
+ }
1176
1213
  async isApproved(toolId, sessionId, userId, context) {
1177
1214
  const approval = await this.getApproval(toolId, sessionId, userId, context);
1178
1215
  return approval?.state === "approved" /* APPROVED */;
@@ -1248,6 +1285,7 @@ var ApprovalStorageStore = class {
1248
1285
  if (this.ownedStorage && this.storage) {
1249
1286
  await this.storage.root.disconnect();
1250
1287
  }
1288
+ this.revocationStorage = void 0;
1251
1289
  this.initialized = false;
1252
1290
  }
1253
1291
  };
package/esm/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-approval",
3
- "version": "1.8.6",
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.6",
53
- "@frontmcp/utils": "1.8.6",
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.6",
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
@@ -667,16 +667,19 @@ var ApprovalService = class {
667
667
  /**
668
668
  * Who a grant is recorded as when the call names no one: the signed-in user whose tool call made it.
669
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 the store's default, a user with no identifier.
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)`.
671
674
  */
672
675
  defaultGrantor() {
673
676
  const userId = this.signedInUserId;
674
- return userId ? userGrantor(userId) : { source: "user" };
677
+ return userId ? userGrantor(userId, void 0, { method: "implicit" }) : { source: "user", method: "implicit" };
675
678
  }
676
679
  /** Who a revocation is recorded as when the call names no one, by the same rule as a grant. */
677
680
  defaultRevoker() {
678
681
  const userId = this.signedInUserId;
679
- return userId ? userRevoker(userId) : { source: "user" };
682
+ return userId ? { source: "user", identifier: userId, method: "implicit" } : { source: "user", method: "implicit" };
680
683
  }
681
684
  // ─────────────────────────────────────────────────────────────────────────────
682
685
  // Query Methods
@@ -733,6 +736,13 @@ var ApprovalService = class {
733
736
  (record) => record.sessionId === this.sessionId || this.userId !== void 0 && record.userId === this.userId
734
737
  );
735
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
+ }
736
746
  // ─────────────────────────────────────────────────────────────────────────────
737
747
  // Grant Methods
738
748
  // ─────────────────────────────────────────────────────────────────────────────
@@ -997,9 +1007,12 @@ var import_utils3 = require("@frontmcp/utils");
997
1007
  function escapePattern(str) {
998
1008
  return str.replace(/[*?[\]\\]/g, "\\$&");
999
1009
  }
1010
+ var REVOCATION_RETENTION_SECONDS = 24 * 60 * 60;
1000
1011
  var TIME_LIMITED_KEY_SEGMENT = `scope:${"time_limited" /* TIME_LIMITED */}`;
1001
1012
  var ApprovalStorageStore = class {
1002
1013
  storage;
1014
+ /** Revoked approvals live beside the live ones, in a namespace no live-approval query scans. */
1015
+ revocationStorage;
1003
1016
  options;
1004
1017
  cleanupInterval;
1005
1018
  initialized = false;
@@ -1035,6 +1048,13 @@ var ApprovalStorageStore = class {
1035
1048
  }
1036
1049
  this.initialized = true;
1037
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
+ }
1038
1058
  ensureInitialized() {
1039
1059
  if (!this.initialized) {
1040
1060
  throw new Error("ApprovalStorageStore not initialized. Call initialize() first.");
@@ -1196,27 +1216,43 @@ var ApprovalStorageStore = class {
1196
1216
  const keys = await this.storage.keys(`${escapePattern(toolId)}:*`);
1197
1217
  const values = await this.storage.mget(keys);
1198
1218
  const keysToDelete = [];
1219
+ const revoked = /* @__PURE__ */ new Map();
1199
1220
  for (let i = 0; i < keys.length; i++) {
1200
1221
  const record = this.parseRecord(values[i]);
1201
1222
  if (!record || record.toolId !== toolId || record.state === "denied" /* DENIED */) continue;
1223
+ const matches = keysToDelete.length;
1202
1224
  if (context) {
1203
1225
  const sameSession = sessionId !== void 0 && record.sessionId === sessionId;
1204
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.
1205
1227
  (!userId || record.userId === userId || sameSession && record.userId === void 0)) {
1206
1228
  keysToDelete.push(keys[i]);
1207
1229
  }
1208
- continue;
1209
- }
1210
- if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1230
+ } else if (sessionId && record.sessionId === sessionId || userId && record.userId === userId) {
1211
1231
  keysToDelete.push(keys[i]);
1212
1232
  }
1233
+ if (keysToDelete.length > matches) revoked.set(keys[i], record);
1213
1234
  }
1214
1235
  if (keysToDelete.length === 0) {
1215
1236
  return false;
1216
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
+ }
1217
1244
  await this.storage.mdelete(keysToDelete);
1218
1245
  return true;
1219
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
+ }
1220
1256
  async isApproved(toolId, sessionId, userId, context) {
1221
1257
  const approval = await this.getApproval(toolId, sessionId, userId, context);
1222
1258
  return approval?.state === "approved" /* APPROVED */;
@@ -1292,6 +1328,7 @@ var ApprovalStorageStore = class {
1292
1328
  if (this.ownedStorage && this.storage) {
1293
1329
  await this.storage.root.disconnect();
1294
1330
  }
1331
+ this.revocationStorage = void 0;
1295
1332
  this.initialized = false;
1296
1333
  }
1297
1334
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-approval",
3
- "version": "1.8.6",
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.6",
53
- "@frontmcp/utils": "1.8.6",
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.6",
58
+ "@frontmcp/lazy-zod": "1.8.7",
59
59
  "@vercel/kv": "^2.0.0 || ^3.0.0"
60
60
  },
61
61
  "peerDependenciesMeta": {
@@ -46,7 +46,10 @@ export declare class ApprovalService {
46
46
  /**
47
47
  * Who a grant is recorded as when the call names no one: the signed-in user whose tool call made it.
48
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 the store's default, a user with no identifier.
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)`.
50
53
  */
51
54
  private defaultGrantor;
52
55
  /** Who a revocation is recorded as when the call names no one, by the same rule as a grant. */
@@ -73,6 +76,11 @@ export declare class ApprovalService {
73
76
  * another caller's records. Read the store directly for administrative queries.
74
77
  */
75
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[]>;
76
84
  /**
77
85
  * Grant session-scoped approval for a tool.
78
86
  */
@@ -1 +1 @@
1
- {"version":3,"file":"approval.service.d.ts","sourceRoot":"","sources":["../../src/services/approval.service.ts"],"names":[],"mappings":"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"}
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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"}