@adtl/gateway 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -3
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +145 -881
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +37 -9
- package/dist/config.js.map +1 -1
- package/dist/elicitation.d.ts +7 -1
- package/dist/elicitation.d.ts.map +1 -1
- package/dist/elicitation.js +21 -14
- package/dist/elicitation.js.map +1 -1
- package/dist/gateway.d.ts +5 -1
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +4 -2
- package/dist/gateway.js.map +1 -1
- package/dist/hooks/claudeCode.d.ts +1 -0
- package/dist/hooks/claudeCode.d.ts.map +1 -1
- package/dist/hooks/claudeCode.js +23 -4
- package/dist/hooks/claudeCode.js.map +1 -1
- package/dist/hooks/run.d.ts.map +1 -1
- package/dist/hooks/run.js +2 -1
- package/dist/hooks/run.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/invoker.d.ts +2 -0
- package/dist/invoker.d.ts.map +1 -1
- package/dist/invoker.js +6 -0
- package/dist/invoker.js.map +1 -1
- package/dist/openfga.d.ts +13 -0
- package/dist/openfga.d.ts.map +1 -0
- package/dist/openfga.js +101 -0
- package/dist/openfga.js.map +1 -0
- package/dist/startup.d.ts +1 -1
- package/dist/startup.d.ts.map +1 -1
- package/dist/startup.js +27 -6
- package/dist/startup.js.map +1 -1
- package/dist/totp.d.ts +42 -0
- package/dist/totp.d.ts.map +1 -0
- package/dist/totp.js +176 -0
- package/dist/totp.js.map +1 -0
- package/dist/totpCli.d.ts +11 -0
- package/dist/totpCli.d.ts.map +1 -0
- package/dist/totpCli.js +46 -0
- package/dist/totpCli.js.map +1 -0
- package/package.json +8 -7
- package/playground/server.mjs +13 -3
- package/src/cli.ts +10 -1
- package/src/config.ts +42 -9
- package/src/elicitation.ts +35 -17
- package/src/gateway.ts +7 -2
- package/src/hooks/claudeCode.ts +25 -5
- package/src/hooks/run.ts +2 -1
- package/src/index.ts +3 -0
- package/src/invoker.ts +7 -0
- package/src/openfga.ts +101 -0
- package/src/startup.ts +27 -6
- package/src/totp.ts +191 -0
- package/src/totpCli.ts +52 -0
- package/src/types/qrcode-terminal.d.ts +4 -0
package/README.md
CHANGED
|
@@ -128,7 +128,27 @@ Labels only get stricter as a session goes on. A session that has read anything
|
|
|
128
128
|
|
|
129
129
|
### Policy
|
|
130
130
|
|
|
131
|
-
Rules match on `session.integrity`, `session.confidentiality`, `tool.egress`, `tool` (`server.tool` globs such as `github.*`), and, for tools that declare [action-metadata](#tools-that-describe-themselves-action-metadata), `tool.outcome` (`benign`, `consequential`, `irreversible`) and `tool.requiresReview`. They decide `allow`, `ask` or `block`. When several rules match, the most restrictive decision wins. A tool that says `requiresReview: true` gets `ask` when no rule blocks it; set `policy.honorRequiresReview: false` to turn that off. `ask` waits for a human when [approvals](#approvals) are configured, and blocks otherwise.
|
|
131
|
+
Rules match on `session.integrity`, `session.confidentiality`, `tool.egress`, `tool` (`server.tool` globs such as `github.*`), [`call.copiesPrivate`](#copied-private-values), and, for tools that declare [action-metadata](#tools-that-describe-themselves-action-metadata), `tool.outcome` (`benign`, `consequential`, `irreversible`) and `tool.requiresReview`. They decide `allow`, `ask` or `block`. When several rules match, the most restrictive decision wins. A tool that says `requiresReview: true` gets `ask` when no rule blocks it; set `policy.honorRequiresReview: false` to turn that off. `ask` waits for a human when [approvals](#approvals) are configured, and blocks otherwise.
|
|
132
|
+
|
|
133
|
+
#### Copied private values
|
|
134
|
+
|
|
135
|
+
`call.copiesPrivate: true` matches a call whose arguments hold a value the session read earlier from a `private` or `secret` result: a token from `.env` pasted into a report, a password written into a script. A session label can't tell that write from a normal one, because nearly every session is already private; copied values can.
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
policy:
|
|
139
|
+
rules:
|
|
140
|
+
- name: ask-before-copying-private-values
|
|
141
|
+
when: { call.copiesPrivate: true, tool.egress: [internal, external, public, unknown] }
|
|
142
|
+
then: ask
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- Only secret-like values count: 16 or more letters, digits, `_`, `-` or `+` in a row, with both letters and digits, not plain hex (so git commit ids, hashes and UUIDs don't count), and not a folder name in a path.
|
|
146
|
+
- The session keeps hashes of those values, never the values (`<session>.values` next to the session's label file). `ADTL_SESSIONS_DIR` and the hooks' self-protection cover it.
|
|
147
|
+
- It works for calls through the gateway and for the Claude Code hooks, which share the session. A sub-agent's calls are checked against its parent's values too.
|
|
148
|
+
- It only sees verbatim copies. A value that was re-encoded, split or paraphrased doesn't match.
|
|
149
|
+
- A session store that can't tell (a custom `SessionStore` without `hasPrivateValue`) counts every call as copying, so the rule fails closed.
|
|
150
|
+
|
|
151
|
+
On [MCPHunt's traces](../../examples/mcphunt-eval/), this rule on top of the example policy stops 78.0% of leaks with 12.7% of clean runs interrupted, against 95.2% and 95.7% for asking before every write once the session is private.
|
|
132
152
|
|
|
133
153
|
### Gateway
|
|
134
154
|
|
|
@@ -145,6 +165,7 @@ Rules match on `session.integrity`, `session.confidentiality`, `tool.egress`, `t
|
|
|
145
165
|
| `gateway.principal` | Who runs this gateway: `{ id, type?, claims? }`. `${VAR}` works in `id`. Default: anonymous. See [Authorization](#authorization). |
|
|
146
166
|
| `gateway.roles` | Who may use which tools, prompts and resources. Deny by default once present. See [Authorization](#authorization). |
|
|
147
167
|
| `gateway.cedar` | Cedar policies for attribute-based rules: `{ policies, entities?, timeZone? }`. See [Cedar policies](#cedar-policies). |
|
|
168
|
+
| `gateway.openfga` | OpenFGA checks for relationship rules: `{ url, storeId, modelId?, token?, relation?, timeoutMs?, tools? }`. See [OpenFGA](#openfga). |
|
|
148
169
|
|
|
149
170
|
#### More interceptor servers
|
|
150
171
|
|
|
@@ -253,6 +274,27 @@ gateway:
|
|
|
253
274
|
- 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.
|
|
254
275
|
- It's never used for rules with named approvers: the client can't say who answered.
|
|
255
276
|
|
|
277
|
+
#### Approving with an authenticator app
|
|
278
|
+
|
|
279
|
+
For a stronger answer than a click, ask for a 6-digit code from an authenticator app (Google Authenticator, 1Password, ...). Codes are made offline on your phone, and a client that accepts prompts by itself can't produce one.
|
|
280
|
+
|
|
281
|
+
```sh
|
|
282
|
+
adtl-gateway totp setup # shows a QR code to scan; --force replaces an existing secret
|
|
283
|
+
adtl-gateway totp check 123456 # does this code match right now? (doesn't use it up)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
gateway:
|
|
288
|
+
approvals:
|
|
289
|
+
totp: true # wins over elicitation: true
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- The prompt appears in the client, as with elicitation, and asks for the code. The model never sees the prompt or the code. Three wrong codes, declining or no answer stops the call.
|
|
293
|
+
- A code works for the one pending call, once, within one 30-second step either way. The last used step is kept next to the secret, so a code can't be replayed after a restart.
|
|
294
|
+
- The secret is kept in the macOS Keychain, or elsewhere in a file only you can read (`ADTL_TOTP_FILE`, default `~/.adtl/totp-secret`). The gateway won't start with `totp: true` and no secret.
|
|
295
|
+
- Clients without elicitation support aren't asked: other configured channels still work, and with none the call is blocked. It's never used for rules with named approvers.
|
|
296
|
+
- An agent with shell access as the same user may still be able to read the secret. The hooks refuse writes to these files and ask before commands that mention them, but that's a speed bump. To rule it out, run the gateway on another machine.
|
|
297
|
+
|
|
256
298
|
#### Who may approve
|
|
257
299
|
|
|
258
300
|
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:
|
|
@@ -492,6 +534,33 @@ Each call becomes a Cedar request:
|
|
|
492
534
|
- 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.
|
|
493
535
|
- 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.
|
|
494
536
|
|
|
537
|
+
#### OpenFGA
|
|
538
|
+
|
|
539
|
+
For relationship rules such as "bob can comment on repos in org acme", point the gateway at an [OpenFGA](https://openfga.dev/) server (or Auth0 FGA). It needs no extra package.
|
|
540
|
+
|
|
541
|
+
```yaml
|
|
542
|
+
gateway:
|
|
543
|
+
principal: { id: "${USER}" }
|
|
544
|
+
openfga:
|
|
545
|
+
url: http://localhost:8080
|
|
546
|
+
storeId: "${FGA_STORE_ID}"
|
|
547
|
+
modelId: "${FGA_MODEL_ID}" # optional: pin an authorization model
|
|
548
|
+
token: "${FGA_TOKEN}" # optional: bearer token
|
|
549
|
+
relation: can_use # optional: the default relation
|
|
550
|
+
tools: # optional: per-resource rules, from the call's arguments
|
|
551
|
+
github.add_issue_comment: { relation: can_comment, object: "repo:{owner}/{repo}" }
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Each call becomes one OpenFGA check:
|
|
555
|
+
|
|
556
|
+
| | Value |
|
|
557
|
+
|---|---|
|
|
558
|
+
| user | `user:<id>`, `service:<id>`, or `user:anonymous` |
|
|
559
|
+
| relation | the tool's rule, else `relation` |
|
|
560
|
+
| object | the tool's rule, else `tool:<server>.<tool>`, `prompt:<server>.<name>` or `resource:<uri>` |
|
|
561
|
+
|
|
562
|
+
Ids are percent-encoded, since OpenFGA ids can't hold `:`, `#`, `@` or spaces, so `{owner}/{repo}` is stored as `repo:acme%2Fwebsite`; write your tuples the same way. A missing or non-scalar `{argument}` denies the call. Tool lists have no arguments, so tools whose object needs them stay listed and are checked when called. If OpenFGA errors or can't be reached within `timeoutMs` (2000 by default), the call is denied. With `roles` or `cedar` as well, every one must allow.
|
|
563
|
+
|
|
495
564
|
#### Your own authorizer
|
|
496
565
|
|
|
497
566
|
Or your own `Authorizer` in code:
|
|
@@ -523,10 +592,12 @@ The gateway fails closed. If an interceptor errors or times out, the call is sto
|
|
|
523
592
|
|
|
524
593
|
- Tools, resources and prompts are proxied. Resource subscriptions, `list_changed` notifications and completions are not passed through yet.
|
|
525
594
|
- 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.
|
|
526
|
-
- Approvals come from ntfy, email notices and,
|
|
527
|
-
- 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
|
|
595
|
+
- Approvals come from ntfy, email notices and, through the MCP client, a prompt (`elicitation: true`) or an authenticator code (`totp: true`).
|
|
596
|
+
- 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, and [sub-agents](#sub-agents) share their parent's label, but the gateway doesn't sign or read [A2A](../../docs/a2a-trust-labels-v1.md) messages itself yet. 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.
|
|
528
597
|
- 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.
|
|
529
598
|
- Labels are set by your config. Servers' own trust claims can only make labels stricter, unless you set `acceptServerClaims: true`.
|
|
599
|
+
- [action-metadata](#tools-that-describe-themselves-action-metadata) needs the tool's annotations from `tools/list`, so it applies to tools behind the gateway. MCP tools that only the Claude Code hooks see are checked without it: `requiresReview` and `tool.outcome` have no effect on them.
|
|
600
|
+
- The playground takes `gateway.interceptorOverrides` from your config but no other `gateway:` setting, and never `interceptorServers`, so a web page can't start commands.
|
|
530
601
|
|
|
531
602
|
## Links
|
|
532
603
|
|
package/dist/cli.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* adtl-gateway receipt list|<session>|verify <file>
|
|
12
12
|
* adtl-gateway key
|
|
13
13
|
* adtl-gateway playground [--port 4317] [--no-open]
|
|
14
|
+
* adtl-gateway totp setup [--force]
|
|
14
15
|
*
|
|
15
16
|
* Point your MCP client (e.g. Claude Code's .mcp.json) at this command.
|
|
16
17
|
* Logs go to stderr; stdout carries MCP JSON-RPC only.
|
|
@@ -21,6 +22,7 @@ import { GATEWAY_VERSION } from "./gateway.js";
|
|
|
21
22
|
import { runAuditCommand } from "./auditCli.js";
|
|
22
23
|
import { runKeyCommand, runReceiptCommand } from "./receiptCli.js";
|
|
23
24
|
import { runPlayground } from "./playgroundCli.js";
|
|
25
|
+
import { runTotpCommand } from "./totpCli.js";
|
|
24
26
|
import { runHook } from "./hooks/run.js";
|
|
25
27
|
import { runLedgerCommand } from "./ledgerCli.js";
|
|
26
28
|
import { runInit } from "./init/run.js";
|
|
@@ -33,6 +35,7 @@ const USAGE = `Usage: adtl-gateway --config <adtl.yaml> [--audit]
|
|
|
33
35
|
adtl-gateway receipt list|<session>|verify <file> (see: adtl-gateway receipt --help)
|
|
34
36
|
adtl-gateway key
|
|
35
37
|
adtl-gateway playground [--port <n>] [--no-open] (a local web UI with fake servers)
|
|
38
|
+
adtl-gateway totp setup [--force] (authenticator-app approvals; see: adtl-gateway totp --help)
|
|
36
39
|
|
|
37
40
|
Runs an MCP server over stdio that forwards tool calls to the upstream
|
|
38
41
|
servers in the config, checking and labeling each call with ADTL.
|
|
@@ -110,6 +113,12 @@ async function main() {
|
|
|
110
113
|
}
|
|
111
114
|
if (process.argv[2] === "playground")
|
|
112
115
|
return runPlayground(process.argv.slice(3));
|
|
116
|
+
if (process.argv[2] === "totp") {
|
|
117
|
+
const r = await runTotpCommand(process.argv.slice(3));
|
|
118
|
+
console.log(r.stdout);
|
|
119
|
+
process.exitCode = r.exitCode;
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
113
122
|
if (process.argv[2] === "receipt" || process.argv[2] === "key") {
|
|
114
123
|
const r = process.argv[2] === "key" ? await runKeyCommand() : await runReceiptCommand(process.argv.slice(3));
|
|
115
124
|
console.log(r.stdout);
|
|
@@ -218,7 +227,7 @@ async function init(path, write, from) {
|
|
|
218
227
|
process.exitCode = 1;
|
|
219
228
|
}
|
|
220
229
|
main().catch((err) => {
|
|
221
|
-
const known = err instanceof GatewayConfigError || err instanceof EnvExpansionError || ["ledger", "audit", "receipt", "key", "playground"].includes(process.argv[2] ?? "");
|
|
230
|
+
const known = err instanceof GatewayConfigError || err instanceof EnvExpansionError || ["ledger", "audit", "receipt", "key", "playground", "totp"].includes(process.argv[2] ?? "");
|
|
222
231
|
console.error(known ? `[adtl-gateway] ${err.message}` : err);
|
|
223
232
|
// For Claude Code hooks only exit code 2 stops the call; any other code lets it run.
|
|
224
233
|
process.exit(process.argv[2] === "hook" ? 2 : 1);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|