@adtl/gateway 0.5.1 → 0.7.0

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 (102) hide show
  1. package/README.md +152 -9
  2. package/dist/approvals.d.ts +22 -6
  3. package/dist/approvals.d.ts.map +1 -1
  4. package/dist/approvals.js +56 -26
  5. package/dist/approvals.js.map +1 -1
  6. package/dist/audit.d.ts +8 -0
  7. package/dist/audit.d.ts.map +1 -1
  8. package/dist/audit.js.map +1 -1
  9. package/dist/auditCli.d.ts +2 -0
  10. package/dist/auditCli.d.ts.map +1 -1
  11. package/dist/auditCli.js +13 -10
  12. package/dist/auditCli.js.map +1 -1
  13. package/dist/cedar.d.ts +27 -0
  14. package/dist/cedar.d.ts.map +1 -0
  15. package/dist/cedar.js +134 -0
  16. package/dist/cedar.js.map +1 -0
  17. package/dist/cli.js +17 -1
  18. package/dist/cli.js.map +1 -1
  19. package/dist/config.d.ts +330 -21
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +74 -1
  22. package/dist/config.js.map +1 -1
  23. package/dist/elicitation.d.ts +25 -0
  24. package/dist/elicitation.d.ts.map +1 -0
  25. package/dist/elicitation.js +46 -0
  26. package/dist/elicitation.js.map +1 -0
  27. package/dist/gateway.d.ts +30 -5
  28. package/dist/gateway.d.ts.map +1 -1
  29. package/dist/gateway.js +96 -14
  30. package/dist/gateway.js.map +1 -1
  31. package/dist/hooks/claudeCode.d.ts +4 -0
  32. package/dist/hooks/claudeCode.d.ts.map +1 -1
  33. package/dist/hooks/claudeCode.js +8 -1
  34. package/dist/hooks/claudeCode.js.map +1 -1
  35. package/dist/hooks/run.d.ts.map +1 -1
  36. package/dist/hooks/run.js +6 -3
  37. package/dist/hooks/run.js.map +1 -1
  38. package/dist/index.d.ts +6 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +6 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/init/presets.d.ts.map +1 -1
  43. package/dist/init/presets.js +54 -0
  44. package/dist/init/presets.js.map +1 -1
  45. package/dist/invoker.d.ts +21 -1
  46. package/dist/invoker.d.ts.map +1 -1
  47. package/dist/invoker.js +19 -2
  48. package/dist/invoker.js.map +1 -1
  49. package/dist/ledgerCli.d.ts +1 -1
  50. package/dist/ledgerCli.d.ts.map +1 -1
  51. package/dist/ledgerCli.js +9 -3
  52. package/dist/ledgerCli.js.map +1 -1
  53. package/dist/ntfy.d.ts +3 -1
  54. package/dist/ntfy.d.ts.map +1 -1
  55. package/dist/ntfy.js +2 -1
  56. package/dist/ntfy.js.map +1 -1
  57. package/dist/playgroundCli.d.ts +8 -0
  58. package/dist/playgroundCli.d.ts.map +1 -0
  59. package/dist/playgroundCli.js +57 -0
  60. package/dist/playgroundCli.js.map +1 -0
  61. package/dist/receipt.d.ts +62 -0
  62. package/dist/receipt.d.ts.map +1 -0
  63. package/dist/receipt.js +117 -0
  64. package/dist/receipt.js.map +1 -0
  65. package/dist/receiptCli.d.ts +8 -0
  66. package/dist/receiptCli.d.ts.map +1 -0
  67. package/dist/receiptCli.js +87 -0
  68. package/dist/receiptCli.js.map +1 -0
  69. package/dist/roles.d.ts +9 -0
  70. package/dist/roles.d.ts.map +1 -0
  71. package/dist/roles.js +41 -0
  72. package/dist/roles.js.map +1 -0
  73. package/dist/startup.d.ts +14 -0
  74. package/dist/startup.d.ts.map +1 -1
  75. package/dist/startup.js +92 -7
  76. package/dist/startup.js.map +1 -1
  77. package/package.json +16 -4
  78. package/playground/fake-github.mjs +98 -0
  79. package/playground/fake-memory.mjs +130 -0
  80. package/playground/index.html +411 -0
  81. package/playground/playground.yaml +40 -0
  82. package/playground/server.mjs +290 -0
  83. package/src/approvals.ts +63 -26
  84. package/src/audit.ts +5 -0
  85. package/src/auditCli.ts +11 -8
  86. package/src/cedar.ts +140 -0
  87. package/src/cli.ts +16 -1
  88. package/src/config.ts +80 -1
  89. package/src/elicitation.ts +69 -0
  90. package/src/gateway.ts +108 -17
  91. package/src/hooks/claudeCode.ts +13 -2
  92. package/src/hooks/run.ts +6 -3
  93. package/src/index.ts +6 -0
  94. package/src/init/presets.ts +54 -0
  95. package/src/invoker.ts +39 -2
  96. package/src/ledgerCli.ts +9 -3
  97. package/src/ntfy.ts +4 -1
  98. package/src/playgroundCli.ts +60 -0
  99. package/src/receipt.ts +148 -0
  100. package/src/receiptCli.ts +85 -0
  101. package/src/roles.ts +55 -0
  102. package/src/startup.ts +88 -6
package/README.md CHANGED
@@ -13,6 +13,16 @@ An MCP gateway for AI agents. It sits between your agent (Claude Code, Cursor, a
13
13
 
14
14
  It stops attacks like the 2025 GitHub MCP exfiltration, where a public issue told an agent to post private repository contents in a comment.
15
15
 
16
+ ## Playground
17
+
18
+ Try it without setting anything up:
19
+
20
+ ```sh
21
+ npx -y @adtl/gateway playground # opens http://localhost:4317
22
+ ```
23
+
24
+ It runs the real gateway in front of fake GitHub and memory servers, with a page that walks through three test cases (a prompt injection in an issue, an injection remembered in memory and triggered in a later session, and ordinary work), with ADTL on and off. It shows every call's label and decision, the session label, what reached GitHub, approvals as Allow / Deny buttons, the config (edit it and press Apply) and the audit log. It listens on 127.0.0.1 only and keeps everything in a temporary folder. `--port <n>` picks another port; `--no-open` doesn't open the browser.
25
+
16
26
  ## Quick start
17
27
 
18
28
  1. Describe your tools in `adtl.yaml`:
@@ -76,7 +86,7 @@ adtl-gateway init -c adtl.yaml --write # update the file (original kept as adt
76
86
 
77
87
  `init` connects to each upstream and lists its tools.
78
88
 
79
- - **Presets** cover the GitHub (`github-mcp-server`), filesystem and fetch servers. A preset says what the server's reads and writes mean; the server's `readOnlyHint` decides which tools are reads, so new tools are covered too.
89
+ - **Presets** cover the GitHub (`github-mcp-server`), filesystem and fetch servers, Slack (`@modelcontextprotocol/server-slack` and `slack-mcp-server`) and Gmail (`@gongrzhe/server-gmail-autoauth-mcp`). A preset says what the server's reads and writes mean; the server's `readOnlyHint` decides which tools are reads, so new tools are covered too. For servers without hints, the preset lists their tools by name. Slack messages and email are untrusted and private; posting to Slack is external egress, and so are sending email and Gmail filters, which can forward mail.
80
90
  - **Other servers** get rules from their MCP tool hints. Hints only set egress, because they are the server's own claims: every result stays `untrusted` and `private` until you change it. These lines are marked `review`.
81
91
  - Entries already in the file are never changed, so you can re-run `init` after a server adds tools. Tools the server no longer offers are reported, not removed.
82
92
  - Edits keep your comments, but the YAML may be reformatted slightly (e.g. `[a]` becomes `[ a ]`).
@@ -116,16 +126,37 @@ Rules match on `session.integrity`, `session.confidentiality`, `tool.egress` and
116
126
  | `gateway.approvals` | Ask a human about `ask` decisions. See [Approvals](#approvals). |
117
127
  | `gateway.interceptorTimeoutMs` | Timeout per interceptor call (default 5000) |
118
128
  | `gateway.interceptors` | Custom interceptor server command (default: the bundled `@adtl/interceptors`) |
129
+ | `gateway.principal` | Who runs this gateway: `{ id, type?, claims? }`. `${VAR}` works in `id`. Default: anonymous. See [Authorization](#authorization). |
130
+ | `gateway.roles` | Who may use which tools, prompts and resources. Deny by default once present. See [Authorization](#authorization). |
131
+ | `gateway.cedar` | Cedar policies for attribute-based rules: `{ policies, entities?, timeZone? }`. See [Cedar policies](#cedar-policies). |
119
132
 
120
133
  #### Checking the audit log
121
134
 
135
+ Each entry lists the interceptors that ran for the call, with the execution policy each ran under, as SEP-2624 asks: `interceptors: [{ name, phase, mode, modeFrom, failOpen, failOpenFrom, failed? }]`, where `*From` is `override` (set by the gateway, e.g. `--audit`) or `default` (declared by the interceptor).
136
+
122
137
  Each line carries `prev`, the hash of the line before, and `hash`, over the line itself. Check the chain with:
123
138
 
124
139
  ```sh
125
140
  adtl-gateway audit verify -c adtl.yaml # or: adtl-gateway audit verify ./adtl-audit.jsonl
126
141
  ```
127
142
 
128
- It exits 1 if a line was edited, removed, reordered or inserted, and prints the hash of the last line. Cutting lines off the end is not detected, so note that hash somewhere else if you need to check later. Lines written by 0.4 or earlier are reported as written before the chain. The gateway and the Claude Code hook append through a lock file (`<log>.lock`), so their lines stay in one chain. The hook blocks `Write`/`Edit` on the log and asks before shell commands that mention it. The chain has no secret: an agent with shell access could still rewrite the whole file consistently. Signed session receipts are planned for that ([#26](https://github.com/probita-ai/adtl/issues/26)).
143
+ It exits 1 if a line was edited, removed, reordered or inserted, and prints the hash of the last line. Cutting lines off the end is not detected, so note that hash somewhere else if you need to check later. Lines written by 0.4 or earlier are reported as written before the chain. The gateway and the Claude Code hook append through a lock file (`<log>.lock`), so their lines stay in one chain. The hook blocks `Write`/`Edit` on the log and asks before shell commands that mention it. The chain has no secret: an agent with shell access could still rewrite the whole file consistently. A signed receipt fixes what a session did at the time you take it (see below).
144
+
145
+ #### Session receipts
146
+
147
+ A receipt is a signed summary of every call one session made through the gateway and the Claude Code hooks, taken from the audit log: for each call the tool, outcome, decision, approver, call hash, result label and the hash of its log line, plus counts. Arguments and results are never included.
148
+
149
+ ```sh
150
+ adtl-gateway receipt list -c adtl.yaml # sessions in the log, newest first
151
+ adtl-gateway receipt <session> -c adtl.yaml -o receipt.json
152
+ adtl-gateway receipt verify receipt.json --log adtl-audit.jsonl --key ed25519:...
153
+ adtl-gateway key # this machine's public key
154
+ ```
155
+
156
+ - Receipts are signed with this machine's Ed25519 key, `~/.adtl/signing-key.pem` (or `ADTL_SIGNING_KEY`), created on first use and readable only by you. `adtl-gateway key` prints the public key to give to whoever checks your receipts.
157
+ - `verify` checks the signature; with `--key`, that your key made it; with `--log`, that the log is intact and the receipt lists every line the session wrote between its first and last call, so a call can't be left out.
158
+ - A receipt is refused if the audit log's chain is broken.
159
+ - The same key signs ledger entries and declassifications (see [Label ledger](#label-ledger)). The Claude Code hook blocks `Write`/`Edit` on the key file and asks before shell commands that mention it. A signature shows which key signed and that nothing changed since; it doesn't stop someone who can read the key, such as an agent with shell access as you, from signing records of their own. Keep the key out of the agent's reach if that matters, for example by pointing `ADTL_SIGNING_KEY` at a file the agent's user can't read.
129
160
 
130
161
  `${VAR}` in commands, args, env, URLs and headers is read from the environment, so secrets stay out of the file.
131
162
 
@@ -158,7 +189,49 @@ How it works and what to know:
158
189
  - **Nothing sensitive is sent.** Notifications and emails name the tool, the server and the reason, never the call's arguments or results.
159
190
  - **Email never contains approve links,** because mail security scanners open links automatically and would approve calls by themselves.
160
191
  - **Mind client timeouts.** Many MCP clients give up on a request after 60 seconds, so the default timeout is 50. The gateway sends progress notifications while it waits, which lets clients that reset their timeout on progress wait longer.
161
- - **Every outcome is logged.** The audit log records `approval: { outcome, channel, waitedMs }` for each call that was asked.
192
+ - **Every outcome is logged.** The audit log records `approval: { outcome, channel, waitedMs }` for each call that was asked, and `approver` when the answer came from a named approver.
193
+
194
+ #### Approving in the MCP client
195
+
196
+ Clients that support MCP elicitation (a server asking the user a question in the client) can show the request in place, so you don't need a phone:
197
+
198
+ ```yaml
199
+ gateway:
200
+ approvals:
201
+ elicitation: true # off by default
202
+ ```
203
+
204
+ - The request appears in the client with Allow and Deny. Allow runs that one call; Deny, declining, dismissing or no answer stops it. The answer goes through the same signed token as a push button, so it can only answer the call it was asked about.
205
+ - If ntfy is configured too, both are asked and the first answer wins. Clients without elicitation support are simply not asked.
206
+ - It's off by default because a client that accepts elicitations by itself, without a person, would approve calls. Turn it on only for clients that always show the prompt to you.
207
+ - It's never used for rules with named approvers: the client can't say who answered.
208
+
209
+ #### Who may approve
210
+
211
+ By default, whoever can read the shared topic can approve, and ADTL can't tell who did. A policy rule can name the roles whose members may answer instead. Each member gets their own topic:
212
+
213
+ ```yaml
214
+ policy:
215
+ rules:
216
+ - name: no-public-write-after-untrusted
217
+ when: { session.integrity: untrusted, tool.egress: [public, external, unknown] }
218
+ then: ask
219
+ approvers: [security-leads] # roles from gateway.roles
220
+
221
+ gateway:
222
+ roles:
223
+ security-leads: { members: [alice, bob], tools: ["*.*"] }
224
+ approvals:
225
+ approvers:
226
+ alice: { ntfy: { topic: "${ALICE_NTFY_TOPIC}" } }
227
+ bob: { ntfy: { topic: "${BOB_NTFY_TOPIC}" } }
228
+ ```
229
+
230
+ - The request goes only to the approvers' own topics, never to the shared one. Each person's buttons carry tokens signed for them, and an answer counts only if it comes back on that person's reply topic, so the audit log records who approved (`approver: alice`) and nobody else can. Email notices still go out.
231
+ - If several matching rules name approvers, a person may answer only if they are in one of the roles of every rule.
232
+ - The gateway refuses to start if a rule names a role that isn't under `gateway.roles`, a role with member `"*"`, or a member without a channel under `gateway.approvals.approvers`.
233
+ - Rules without `approvers:` use the shared topic as before. One approval is enough; requiring two, and stopping people from approving their own calls, are not supported yet.
234
+ - Under Claude Code's hooks an "ask" goes to Claude Code's own permission prompt, which doesn't know about approvers.
162
235
 
163
236
  ### Trying a policy safely
164
237
 
@@ -193,7 +266,7 @@ What it does:
193
266
  - **It shares one session label with the gateway.** Claude Code gives the gateway its session id (`CLAUDE_CODE_SESSION_ID`), and both keep the label in `~/.adtl/sessions/<id>.jsonl` (set `ADTL_SESSIONS_DIR` to change the directory). A `WebFetch` taints the session for `github__add_comment`, and a private file read through the gateway counts against a later `Bash` call. Labels last for the whole Claude Code session, including `--resume`.
194
267
  - **It covers MCP servers that skip the gateway**, such as connectors added in claude.ai. Their tools are labeled as their server name (`mcp__<server>__<tool>` → server `<server>`), so you can describe them under `servers:` like any upstream. The gateway's own tools (`mcp__adtl__*`) are skipped; pass `--gateway-server <name>` if you registered the gateway under another name.
195
268
  - **It fails closed.** If the hook can't decide, it exits with code 2, which stops the call.
196
- - **It writes to the same audit log** (`gateway.audit`) with `"via": "claude-code-hook"`, and follows `gateway.mode: audit`. The config needs no `gateway:` section if you only use the hooks.
269
+ - **It writes to the same audit log** (`gateway.audit`) with `"via": "claude-code-hook"`, and follows `gateway.mode: audit`. Calls made inside a subagent (the Task tool) carry `"agent": { id, type }`. Their labels count toward the session id Claude Code gives the hook; if that is the parent's id, as the hook docs suggest, a subagent that reads untrusted content taints the parent too. The config needs no `gateway:` section if you only use the hooks.
197
270
 
198
271
  Built-in labels, which you can override under `servers.claude-code.tools`:
199
272
 
@@ -229,7 +302,7 @@ Look after it with:
229
302
 
230
303
  ```sh
231
304
  adtl-gateway ledger stats
232
- adtl-gateway ledger verify # exit 1 if an entry was changed or removed
305
+ adtl-gateway ledger verify # exit 1 if an entry was changed, removed, or signed by another key
233
306
  adtl-gateway ledger declassify notes.md --reason "checked by hand, no instructions"
234
307
  # after checking it: clear the label of its current content
235
308
  adtl-gateway ledger declassified # recent declassifications: when, who, what and why
@@ -237,7 +310,7 @@ adtl-gateway ledger declassified # recent declassifications: when, wh
237
310
 
238
311
  `--reason` is required. Declassifying is where taint tracking tends to erode, as it turns into a reflex, so each one is kept with who did it, the file and the reason, for review with `declassified`.
239
312
 
240
- Matching is by normalized chunks (whole text, paragraphs, lines of 32+ characters), so text copied into a bigger file still matches, and text the agent rewrote was already recorded with its session's label. Text a person rewrites by hand, binary files, and content an MCP server returns in another encoding (such as base64) are not matched. The Claude Code hook blocks `Write`/`Edit` on the ledger file and asks before shell commands that mention it or `ledger declassify`. Entries are hash-chained, not signed: an agent with shell access could still rebuild the file, which `verify` cannot detect. Signed entries are planned with labels that travel between agents (v0.6).
313
+ Matching is by normalized chunks (whole text, paragraphs, lines of 32+ characters), so text copied into a bigger file still matches, and text the agent rewrote was already recorded with its session's label. Text a person rewrites by hand, binary files, and content an MCP server returns in another encoding (such as base64) are not matched. The Claude Code hook blocks `Write`/`Edit` on the ledger file and asks before shell commands that mention it or `ledger declassify`. Entries are hash-chained and, from 0.6, signed with this machine's key (the same one as [receipts](#session-receipts)), declassifications included, so a reader elsewhere can check who labeled content. `verify` reports entries signed by another key, bad signatures, and unsigned entries after signed ones; entries written before signing are counted, not refused. Someone who can read the key can still sign a rebuilt file.
241
314
 
242
315
  See [the delayed-injection demo](../../examples/delayed-injection-demo) (`npm run demo:ledger`).
243
316
 
@@ -272,7 +345,75 @@ agent ──▶ adtl-gateway ──▶ upstream MCP servers
272
345
 
273
346
  ### Authorization
274
347
 
275
- Labels and the policy decide whether a call may run given what the session has seen. An `Authorizer` decides before that whether the caller may use the tool, resource or prompt at all. It is a library interface for now; role-based rules in the config are planned ([#8](https://github.com/probita-ai/adtl/issues/8)).
348
+ Labels and the policy decide whether a call may run given what the session has seen. Authorization decides before that whether the caller may use the tool, resource or prompt at all.
349
+
350
+ Roles in the config:
351
+
352
+ ```yaml
353
+ gateway:
354
+ principal: { id: "${USER}" } # who runs this gateway
355
+ roles:
356
+ maintainers: { members: [alice, bob], tools: ["github.*"] }
357
+ readers: { members: ["*"], tools: ["github.read_*", "github.get_*"], resources: ["github://acme/website/*"] }
358
+ ```
359
+
360
+ - A call is allowed if a role the caller belongs to grants it. Once `roles:` is present, everything else is denied.
361
+ - `tools` and `prompts` are `server.name` patterns with `*`, as in policy rules; `resources` are URI patterns. Members are principal ids; `"*"` means everyone, including an anonymous caller.
362
+ - Over stdio the caller is whoever started the gateway, set with `gateway.principal`. Without it the caller is anonymous and only roles with `members: ["*"]` apply (the gateway warns at startup).
363
+ - `tools/list`, `prompts/list` and `resources/list` leave out what the caller may not use, so the agent doesn't try it. Hiding is a convenience, not the security boundary: a call to a hidden tool is still checked and denied. Lists are checked without arguments, and nothing is hidden in audit mode. Resource templates are always listed.
364
+
365
+ #### Cedar policies
366
+
367
+ For rules roles can't express (working hours, tool arguments, groups kept in another system), write [Cedar](https://www.cedarpolicy.com/) policies:
368
+
369
+ ```sh
370
+ npm install @cedar-policy/cedar-wasm # optional dependency, only needed for gateway.cedar
371
+ ```
372
+
373
+ ```yaml
374
+ gateway:
375
+ principal: { id: "${USER}" }
376
+ cedar:
377
+ policies: ./adtl.cedar # relative to adtl.yaml
378
+ entities: ./entities.json # optional: groups and attributes, in Cedar's entities JSON
379
+ timeZone: Europe/Berlin # optional: for context.time (default: the gateway's)
380
+ ```
381
+
382
+ ```cedar
383
+ // Everyone may read issues.
384
+ permit (principal, action == Action::"tools/call", resource == Tool::"github.issue_read");
385
+
386
+ // Maintainers may use any GitHub tool, on weekdays during working hours.
387
+ permit (principal in Group::"maintainers", action, resource)
388
+ when { context.server == "github" && context.time.hour >= 9 && context.time.hour < 18
389
+ && !["Sat", "Sun"].contains(context.time.weekday) };
390
+
391
+ // Anyone may comment in the orgs listed on their entity (entities.json: "attrs": { "orgs": ["acme"] }).
392
+ permit (principal, action == Action::"tools/call", resource == Tool::"github.add_issue_comment")
393
+ when { context.listing || (principal has orgs && principal.orgs.contains(context.arguments.owner)) };
394
+
395
+ // Nobody reads secrets files.
396
+ forbid (principal, action, resource == Tool::"github.get_file_contents")
397
+ when { context has arguments && context.arguments has path && context.arguments.path like "*secret*" };
398
+ ```
399
+
400
+ Each call becomes a Cedar request:
401
+
402
+ | | |
403
+ |---|---|
404
+ | principal | `User::"<id>"`, `Service::"<id>"`, or `Anonymous::"anonymous"` without an id |
405
+ | action | `Action::"tools/call"`, `Action::"resources/read"` or `Action::"prompts/get"` |
406
+ | resource | `Tool::"<server>.<tool>"`, `Prompt::"<server>.<prompt>"` or `Resource::"<uri>"` |
407
+ | context | `server`, `principalId`, `listing`, `time: { hour, minute, weekday }`, and `arguments` |
408
+
409
+ - Cedar denies unless a policy permits, and a `forbid` beats any `permit`. The denial names the forbidding policy (`policy0`, `policy1`, … in file order).
410
+ - Lists are checked with `listing: true` and no `arguments`. Start a policy that reads arguments with `context.listing ||`, or the tool is hidden from lists (calls are still checked with arguments).
411
+ - Arguments are passed without nulls, with fractions as strings. Objects with `__entity` or `__extn` are passed as JSON strings, so a tool argument can't name an entity.
412
+ - With `roles` set too, both must allow. A policy file that doesn't parse stops the gateway at startup; an evaluation error denies the call.
413
+
414
+ #### Your own authorizer
415
+
416
+ Or your own `Authorizer` in code:
276
417
 
277
418
  ```ts
278
419
  import { AdtlGateway, type Authorizer } from "@adtl/gateway";
@@ -288,6 +429,8 @@ const readOnly: Authorizer = {
288
429
  new AdtlGateway({ upstreams, invoker, authorizer: readOnly, principal: { type: "user", id: "alice" } });
289
430
  ```
290
431
 
432
+ Pass an array (`authorizer: [roles, readOnly]`) to ask several in turn: the first denial wins.
433
+
291
434
  - It runs on every `tools/call`, `resources/read` and `prompts/get`, before the interceptors. A denial stops the call whatever the policy says; an allow still leaves the call to the policy.
292
435
  - It gets `{ principal, event, server, tool | resource | prompt, arguments }`. The principal is also passed to the interceptors as SEP-2624 `context.principal`. Over stdio it is whoever started the gateway (anonymous unless set).
293
436
  - Denials are audited with `denied: { by, reason }`. An authorizer that throws denies the call. In audit mode denials are logged and the call still runs.
@@ -299,8 +442,8 @@ The gateway fails closed. If an interceptor errors or times out, the call is sto
299
442
 
300
443
  - Tools, resources and prompts are proxied. Resource subscriptions, `list_changed` notifications and completions are not passed through yet.
301
444
  - Resources and prompts are labeled by server defaults (`servers.<id>.defaults`) or the global defaults; there are no per-resource or per-prompt rules yet. A resource URI that two upstreams could serve is refused rather than guessed.
302
- - Approvals come from one push channel (ntfy). Other channels, approvals inside the MCP client, and approver roles are planned.
303
- - Session labels last for one agent session: one gateway process, or under Claude Code one Claude Code session (shared with the hooks). The [label ledger](#label-ledger) carries them into files, memory servers and sub-agents by content, but not across machines or other agents yet (v0.6). Memory servers that extract facts or merge records on write return text the ledger cannot recognize; use [labels on records](#labels-on-records), or a strict rule for servers that don't keep metadata.
445
+ - Approvals come from ntfy, email notices and, with `elicitation: true`, the MCP client. Authenticator-app codes (TOTP) are planned.
446
+ - Session labels last for one agent session: one gateway process, or under Claude Code one Claude Code session (shared with the hooks). The [label ledger](#label-ledger) carries them into files, memory servers and sub-agents by content, but not across machines or other agents yet (v0.8). Memory servers that extract facts or merge records on write return text the ledger cannot recognize; use [labels on records](#labels-on-records), or a strict rule for servers that don't keep metadata.
304
447
  - The Claude Code hooks label tools by name, not by what they touched: a `Read` of a downloaded file is as trusted as a `Read` of your own code.
305
448
  - Labels are set by your config. Servers' own trust claims can only make labels stricter, unless you set `acceptServerClaims: true`.
306
449
 
@@ -10,6 +10,8 @@ export interface ApprovalRequest {
10
10
  matched: string[];
11
11
  /** The session label that triggered the rule (no arguments or results). */
12
12
  sessionLabel?: unknown;
13
+ /** People who may answer, reached on their own channels. Absent: the shared channels. */
14
+ approvers?: string[];
13
15
  createdAt: Date;
14
16
  expiresAt: Date;
15
17
  }
@@ -53,7 +55,8 @@ export declare function errorText(err: unknown): string;
53
55
  export declare class ApprovalTokens {
54
56
  private readonly secret;
55
57
  constructor(secret?: Buffer);
56
- sign(request: Pick<ApprovalRequest, "id" | "callHash" | "expiresAt">, decision: ApprovalDecision): string;
58
+ /** A token answering `request` with `decision`; with `approver`, valid only as that person's answer. */
59
+ sign(request: Pick<ApprovalRequest, "id" | "callHash" | "expiresAt">, decision: ApprovalDecision, approver?: string): string;
57
60
  /** Parse a token without verifying it. */
58
61
  static parse(token: string): {
59
62
  id: string;
@@ -62,11 +65,13 @@ export declare class ApprovalTokens {
62
65
  sig: string;
63
66
  } | undefined;
64
67
  /** Verify a token against the pending request it claims to answer. */
65
- verify(token: string, request: Pick<ApprovalRequest, "id" | "callHash">, now: Date): ApprovalDecision | undefined;
68
+ verify(token: string, request: Pick<ApprovalRequest, "id" | "callHash">, now: Date, approver?: string): ApprovalDecision | undefined;
66
69
  private mac;
67
70
  }
68
71
  export interface ApprovalBrokerOptions {
69
72
  notifiers: Notifier[];
73
+ /** Each approver's own channels, by principal id. */
74
+ approverChannels?: Map<string, Notifier[]>;
70
75
  timeoutMs: number;
71
76
  tokens?: ApprovalTokens;
72
77
  now?: () => Date;
@@ -76,18 +81,29 @@ export interface ApprovalBrokerOptions {
76
81
  }
77
82
  export declare class ApprovalBroker {
78
83
  private readonly notifiers;
84
+ private readonly approverChannels;
79
85
  private readonly timeoutMs;
80
86
  private readonly tokens;
81
87
  private readonly now;
82
88
  private readonly log;
83
89
  private readonly pending;
84
90
  constructor(opts: ApprovalBrokerOptions);
85
- /** True if at least one notifier can carry answers. Without one, "ask" stays a block. */
91
+ /** True if at least one channel can carry answers. Without one, "ask" stays a block. */
86
92
  get canApprove(): boolean;
93
+ /**
94
+ * Where a request goes: the named approvers' own channels plus notice-only
95
+ * ones, or else every shared channel plus `extra` (channels for this request
96
+ * only, such as the client's elicitation).
97
+ */
98
+ private targets;
87
99
  /** Ask for approval and wait for the answer, the timeout, or a failure to reach anyone. */
88
- request(input: Omit<ApprovalRequest, "id" | "createdAt" | "expiresAt">): Promise<ApprovalResult>;
89
- /** Handle an answer token from a channel. Returns true if it settled a pending approval. */
90
- answer(token: string, channel: string, approver?: string): boolean;
100
+ request(input: Omit<ApprovalRequest, "id" | "createdAt" | "expiresAt">, extra?: Notifier[]): Promise<ApprovalResult>;
101
+ /**
102
+ * Handle an answer token from a channel; `approver` is whose own channel it
103
+ * came on, `reportedBy` who a shared channel says answered (recorded, not
104
+ * trusted for anything). Returns true if it settled a pending approval.
105
+ */
106
+ answer(token: string, channel: string, approver?: string, reportedBy?: string): boolean;
91
107
  /** Tell notifiers a call was blocked. Fire and forget. */
92
108
  blocked(event: Omit<Extract<ApprovalEvent, {
93
109
  kind: "blocked";
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
package/dist/approvals.js CHANGED
@@ -10,6 +10,11 @@
10
10
  * decision and an expiry. A token only ever answers the one pending call it
11
11
  * was made for, and only once. Anyone who can read the push channel can still
12
12
  * use the tokens sent on it, so that channel must stay private.
13
+ *
14
+ * A request can name its approvers (policy rule `approvers:`). It then goes
15
+ * only to those people's own channels, each with tokens signed for that
16
+ * person, and an answer counts only if it comes back on the same person's
17
+ * channel. So the result names who approved, and nobody else can.
13
18
  */
14
19
  import { createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
15
20
  const TOKEN_PREFIX = "adtl1";
@@ -26,9 +31,10 @@ export class ApprovalTokens {
26
31
  constructor(secret = randomBytes(32)) {
27
32
  this.secret = secret;
28
33
  }
29
- sign(request, decision) {
34
+ /** A token answering `request` with `decision`; with `approver`, valid only as that person's answer. */
35
+ sign(request, decision, approver) {
30
36
  const exp = Math.floor(request.expiresAt.getTime() / 1000);
31
- return `${TOKEN_PREFIX}.${request.id}.${decision}.${exp}.${this.mac(request.id, request.callHash, decision, exp)}`;
37
+ return `${TOKEN_PREFIX}.${request.id}.${decision}.${exp}.${this.mac(request.id, request.callHash, decision, exp, approver)}`;
32
38
  }
33
39
  /** Parse a token without verifying it. */
34
40
  static parse(token) {
@@ -43,24 +49,26 @@ export class ApprovalTokens {
43
49
  return { id, decision, exp: Number(exp), sig };
44
50
  }
45
51
  /** Verify a token against the pending request it claims to answer. */
46
- verify(token, request, now) {
52
+ verify(token, request, now, approver) {
47
53
  const t = ApprovalTokens.parse(token);
48
54
  if (!t || t.id !== request.id)
49
55
  return undefined;
50
56
  if (now.getTime() > t.exp * 1000)
51
57
  return undefined;
52
- const expected = Buffer.from(this.mac(t.id, request.callHash, t.decision, t.exp));
58
+ const expected = Buffer.from(this.mac(t.id, request.callHash, t.decision, t.exp, approver));
53
59
  const given = Buffer.from(t.sig);
54
60
  if (given.length !== expected.length || !timingSafeEqual(given, expected))
55
61
  return undefined;
56
62
  return t.decision;
57
63
  }
58
- mac(id, callHash, decision, exp) {
59
- return createHmac("sha256", this.secret).update(`${id}\n${callHash}\n${decision}\n${exp}`).digest("base64url");
64
+ mac(id, callHash, decision, exp, approver) {
65
+ const signed = `${id}\n${callHash}\n${decision}\n${exp}${approver === undefined ? "" : `\napprover:${approver}`}`;
66
+ return createHmac("sha256", this.secret).update(signed).digest("base64url");
60
67
  }
61
68
  }
62
69
  export class ApprovalBroker {
63
70
  notifiers;
71
+ approverChannels;
64
72
  timeoutMs;
65
73
  tokens;
66
74
  now;
@@ -68,17 +76,30 @@ export class ApprovalBroker {
68
76
  pending = new Map();
69
77
  constructor(opts) {
70
78
  this.notifiers = opts.notifiers;
79
+ this.approverChannels = opts.approverChannels ?? new Map();
71
80
  this.timeoutMs = opts.timeoutMs;
72
81
  this.tokens = opts.tokens ?? new ApprovalTokens();
73
82
  this.now = opts.now ?? (() => new Date());
74
83
  this.log = opts.log ?? { warn: () => { } };
75
84
  }
76
- /** True if at least one notifier can carry answers. Without one, "ask" stays a block. */
85
+ /** True if at least one channel can carry answers. Without one, "ask" stays a block. */
77
86
  get canApprove() {
78
- return this.notifiers.some((n) => n.listen);
87
+ return this.notifiers.some((n) => n.listen) || [...this.approverChannels.values()].some((ns) => ns.some((n) => n.listen));
88
+ }
89
+ /**
90
+ * Where a request goes: the named approvers' own channels plus notice-only
91
+ * ones, or else every shared channel plus `extra` (channels for this request
92
+ * only, such as the client's elicitation).
93
+ */
94
+ targets(request, extra) {
95
+ if (!request.approvers)
96
+ return [...this.notifiers, ...extra].map((notifier) => ({ notifier }));
97
+ const own = request.approvers.flatMap((approver) => (this.approverChannels.get(approver) ?? []).map((notifier) => ({ notifier, approver })));
98
+ // Shared channels that can answer would let anyone who reads them approve; notice-only ones (email) are fine.
99
+ return [...own, ...this.notifiers.filter((n) => !n.listen).map((notifier) => ({ notifier }))];
79
100
  }
80
101
  /** Ask for approval and wait for the answer, the timeout, or a failure to reach anyone. */
81
- async request(input) {
102
+ async request(input, extra = []) {
82
103
  const createdAt = this.now();
83
104
  const request = {
84
105
  ...input,
@@ -104,46 +125,55 @@ export class ApprovalBroker {
104
125
  request,
105
126
  settle: (decision, channel, approver) => finish({ outcome: decision === "allow" ? "approved" : "denied", channel, ...(approver ? { approver } : {}), waitedMs: waited() }),
106
127
  });
107
- // Start listening before anyone can answer, then send the request everywhere.
108
- const listeners = this.notifiers.filter((n) => n.listen);
109
- for (const n of listeners) {
110
- n.listen(request, (token, approver) => this.answer(token, n.name, approver), abort.signal).catch((err) => this.log.warn(`${n.name}: stopped listening for approvals: ${errorText(err)}`));
128
+ // Start listening before anyone can answer, then send the request to every target.
129
+ const targets = this.targets(request, extra);
130
+ for (const { notifier: n, approver } of targets.filter((t) => t.notifier.listen)) {
131
+ n.listen(request, (token, reportedBy) => this.answer(token, n.name, approver, reportedBy), abort.signal).catch((err) => this.log.warn(`${n.name}: stopped listening for approvals: ${errorText(err)}`));
111
132
  }
112
- const tokens = { allow: this.tokens.sign(request, "allow"), deny: this.tokens.sign(request, "deny") };
113
- const sent = this.notifiers.map((n) => n.notify({ kind: "pending", request, tokens }).then(() => true, (err) => {
114
- this.log.warn(`${n.name}: could not send approval request: ${errorText(err)}`);
115
- return false;
116
- }));
133
+ const sent = targets.map(({ notifier: n, approver }) => {
134
+ const tokens = { allow: this.tokens.sign(request, "allow", approver), deny: this.tokens.sign(request, "deny", approver) };
135
+ return n.notify({ kind: "pending", request, tokens }).then(() => true, (err) => {
136
+ this.log.warn(`${n.name}: could not send approval request: ${errorText(err)}`);
137
+ return false;
138
+ });
139
+ });
117
140
  // Nobody who could answer was reached: deny now rather than wait out the timeout.
118
141
  // Notify-only channels (email) are not waited for.
119
- void Promise.all(sent.filter((_, i) => this.notifiers[i].listen)).then((ok) => {
142
+ void Promise.all(sent.filter((_, i) => targets[i].notifier.listen)).then((ok) => {
120
143
  if (!ok.includes(true))
121
144
  finish({ outcome: "undeliverable", waitedMs: waited() });
122
145
  });
123
146
  const r = await result;
124
- this.broadcast({ kind: "resolved", request, result: r });
147
+ this.broadcast({ kind: "resolved", request, result: r }, [...new Set(targets.map((t) => t.notifier))]);
125
148
  return r;
126
149
  }
127
- /** Handle an answer token from a channel. Returns true if it settled a pending approval. */
128
- answer(token, channel, approver) {
150
+ /**
151
+ * Handle an answer token from a channel; `approver` is whose own channel it
152
+ * came on, `reportedBy` who a shared channel says answered (recorded, not
153
+ * trusted for anything). Returns true if it settled a pending approval.
154
+ */
155
+ answer(token, channel, approver, reportedBy) {
129
156
  const parsed = ApprovalTokens.parse(token);
130
157
  const p = parsed && this.pending.get(parsed.id);
131
158
  if (!p)
132
159
  return false; // not ours, already answered, or garbage
133
- const decision = this.tokens.verify(token, p.request, this.now());
160
+ // A request with approvers takes answers only on their own channels.
161
+ if (p.request.approvers && (approver === undefined || !p.request.approvers.includes(approver)))
162
+ return false;
163
+ const decision = this.tokens.verify(token, p.request, this.now(), approver);
134
164
  if (!decision) {
135
165
  this.log.warn(`${channel}: ignored an approval answer with a bad or expired signature`);
136
166
  return false;
137
167
  }
138
- p.settle(decision, channel, approver);
168
+ p.settle(decision, channel, approver ?? reportedBy);
139
169
  return true;
140
170
  }
141
171
  /** Tell notifiers a call was blocked. Fire and forget. */
142
172
  blocked(event) {
143
173
  this.broadcast({ kind: "blocked", ...event });
144
174
  }
145
- broadcast(event) {
146
- for (const n of this.notifiers) {
175
+ broadcast(event, notifiers = this.notifiers) {
176
+ for (const n of notifiers) {
147
177
  n.notify(event).catch((err) => this.log.warn(`${n.name}: could not send ${event.kind} notice: ${errorText(err)}`));
148
178
  }
149
179
  }
@@ -1 +1 @@
1
- {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA8CnF,MAAM,YAAY,GAAG,OAAO,CAAC;AAE7B,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAwD,CAAC;IAC3E,MAAM,MAAM,GAAG,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,OAAO,CAAC;IAC7C,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9F,CAAC;AAED,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,SAAiB,WAAW,CAAC,EAAE,CAAC;QAAhC,WAAM,GAAN,MAAM,CAA0B;IAAG,CAAC;IAEjE,IAAI,CAAC,OAA+D,EAAE,QAA0B;QAC9F,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3D,OAAO,GAAG,YAAY,IAAI,OAAO,CAAC,EAAE,IAAI,QAAQ,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;IACrH,CAAC;IAED,0CAA0C;IAC1C,MAAM,CAAC,KAAK,CAAC,KAAa;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,YAAY;YAAE,OAAO,SAAS,CAAC;QACtE,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,KAAiD,CAAC;QACrF,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACjD,CAAC;IAED,sEAAsE;IACtE,MAAM,CAAC,KAAa,EAAE,OAAiD,EAAE,GAAS;QAChF,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QAChD,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI;YAAE,OAAO,SAAS,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5F,OAAO,CAAC,CAAC,QAAQ,CAAC;IACpB,CAAC;IAEO,GAAG,CAAC,EAAU,EAAE,QAAgB,EAAE,QAA0B,EAAE,GAAW;QAC/E,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,QAAQ,KAAK,QAAQ,KAAK,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACjH,CAAC;CACF;AAeD,MAAM,OAAO,cAAc;IACR,SAAS,CAAa;IACtB,SAAS,CAAS;IAClB,MAAM,CAAiB;IACvB,GAAG,CAAa;IAChB,GAAG,CAA8B;IACjC,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEtD,YAAY,IAA2B;QACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,yFAAyF;IACzF,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,OAAO,CAAC,KAA8D;QAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAoB;YAC/B,GAAG,KAAK;YACR,EAAE,EAAE,UAAU,EAAE;YAChB,SAAS;YACT,SAAS,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;SAC1D,CAAC;QACF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QAEpC,IAAI,MAAoC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,EAAE;YACrD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACnG,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE;gBACb,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBAAE,OAAO,CAAC,kBAAkB;gBAChE,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,OAAO,CAAC,CAAC,CAAC,CAAC;YACb,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;YAC3B,OAAO;YACP,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CACtC,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;SACpI,CAAC,CAAC;QAEH,8EAA8E;QAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,CAAC,CAAC,MAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CACjH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,sCAAsC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAC/E,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;QACtG,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CACjD,GAAG,EAAE,CAAC,IAAI,EACV,CAAC,GAAY,EAAE,EAAE;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,sCAAsC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/E,OAAO,KAAK,CAAC;QACf,CAAC,CACF,CACF,CAAC;QACF,kFAAkF;QAClF,mDAAmD;QACnD,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;YAC7E,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC;QACvB,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,4FAA4F;IAC5F,MAAM,CAAC,KAAa,EAAE,OAAe,EAAE,QAAiB;QACtD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,yCAAyC;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,8DAA8D,CAAC,CAAC;YACxF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0DAA0D;IAC1D,OAAO,CAAC,KAAgE;QACtE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAEO,SAAS,CAAC,KAAoB;QACpC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,oBAAoB,KAAK,CAAC,IAAI,YAAY,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9H,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
package/dist/audit.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { InterceptorRun } from "./invoker.js";
1
2
  export interface AuditEntry {
2
3
  ts: string;
3
4
  sessionId: string;
@@ -11,6 +12,11 @@ export interface AuditEntry {
11
12
  outcome: "forwarded" | "blocked" | "asked" | "upstream_error";
12
13
  /** Present when the entry was written by the Claude Code hook rather than the gateway. */
13
14
  via?: "claude-code-hook";
15
+ /** Present when a Claude Code subagent made the call: its id and type (e.g. "Explore"). */
16
+ agent?: {
17
+ id: string;
18
+ type?: string;
19
+ };
14
20
  /** The policy's decision. In audit mode a call can be forwarded with decision "ask" or "block". */
15
21
  decision?: string;
16
22
  /** Present when the gateway ran in audit mode: nothing was stopped or changed. */
@@ -36,6 +42,8 @@ export interface AuditEntry {
36
42
  /** Present when the result carried record label stamps: how many, and which sessions wrote them. */
37
43
  records?: unknown;
38
44
  sessionLabel?: unknown;
45
+ /** Every interceptor invocation for this call, with its resolved mode and failOpen and where each came from (SEP-2624). */
46
+ interceptors?: InterceptorRun[];
39
47
  warnings?: string[];
40
48
  durationMs: number;
41
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,gBAAgB,CAAC;IAC9D,0FAA0F;IAC1F,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2GAA2G;IAC3G,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,2FAA2F;IAC3F,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8HAA8H;IAC9H,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oGAAoG;IACpG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAChC;AAED,yCAAyC;AACzC,eAAO,MAAM,aAAa,QAA6B,CAAC;AAsExD,qBAAa,aAAc,YAAW,SAAS;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAIjC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAc/B;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CA4B9D;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAM;IACpC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,gBAAgB,CAAC;IAC9D,0FAA0F;IAC1F,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,2FAA2F;IAC3F,KAAK,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2GAA2G;IAC3G,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,2FAA2F;IAC3F,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8HAA8H;IAC9H,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oGAAoG;IACpG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2HAA2H;IAC3H,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAChC;AAED,yCAAyC;AACzC,eAAO,MAAM,aAAa,QAA6B,CAAC;AAsExD,qBAAa,aAAc,YAAW,SAAS;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAIjC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAc/B;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CA4B9D;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAM;IACpC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAG/B"}
package/dist/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,7 @@ export interface AuditCommandResult {
3
3
  stdout: string;
4
4
  exitCode: number;
5
5
  }
6
+ /** The audit log: `file` if given, else `gateway.audit` from `config`. */
7
+ export declare function resolveAuditPath(file: string | undefined, config: string | undefined, usage: string): Promise<string>;
6
8
  export declare function runAuditCommand(argv: string[]): Promise<AuditCommandResult>;
7
9
  //# sourceMappingURL=auditCli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auditCli.d.ts","sourceRoot":"","sources":["../src/auditCli.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW,kYAMO,CAAC;AAEhC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA2BjF"}
1
+ {"version":3,"file":"auditCli.d.ts","sourceRoot":"","sources":["../src/auditCli.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW,kYAMO,CAAC;AAEhC,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0EAA0E;AAC1E,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3H;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoBjF"}