@adtl/gateway 0.7.0 → 0.8.1

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 (80) hide show
  1. package/README.md +143 -11
  2. package/dist/audit.d.ts +3 -1
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/audit.js.map +1 -1
  5. package/dist/cli.js +10 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config.d.ts +167 -713
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +64 -7
  10. package/dist/config.js.map +1 -1
  11. package/dist/elicitation.d.ts +7 -1
  12. package/dist/elicitation.d.ts.map +1 -1
  13. package/dist/elicitation.js +21 -14
  14. package/dist/elicitation.js.map +1 -1
  15. package/dist/gateway.d.ts +11 -1
  16. package/dist/gateway.d.ts.map +1 -1
  17. package/dist/gateway.js +13 -5
  18. package/dist/gateway.js.map +1 -1
  19. package/dist/hooks/agentLinks.d.ts +18 -0
  20. package/dist/hooks/agentLinks.d.ts.map +1 -0
  21. package/dist/hooks/agentLinks.js +48 -0
  22. package/dist/hooks/agentLinks.js.map +1 -0
  23. package/dist/hooks/claudeCode.d.ts +4 -0
  24. package/dist/hooks/claudeCode.d.ts.map +1 -1
  25. package/dist/hooks/claudeCode.js +35 -8
  26. package/dist/hooks/claudeCode.js.map +1 -1
  27. package/dist/hooks/index.d.ts +1 -0
  28. package/dist/hooks/index.d.ts.map +1 -1
  29. package/dist/hooks/index.js +1 -0
  30. package/dist/hooks/index.js.map +1 -1
  31. package/dist/hooks/run.d.ts.map +1 -1
  32. package/dist/hooks/run.js +5 -2
  33. package/dist/hooks/run.js.map +1 -1
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +3 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/init/suggest.d.ts +3 -1
  39. package/dist/init/suggest.d.ts.map +1 -1
  40. package/dist/init/suggest.js +8 -0
  41. package/dist/init/suggest.js.map +1 -1
  42. package/dist/invoker.d.ts +56 -6
  43. package/dist/invoker.d.ts.map +1 -1
  44. package/dist/invoker.js +121 -19
  45. package/dist/invoker.js.map +1 -1
  46. package/dist/openfga.d.ts +13 -0
  47. package/dist/openfga.d.ts.map +1 -0
  48. package/dist/openfga.js +101 -0
  49. package/dist/openfga.js.map +1 -0
  50. package/dist/startup.d.ts +10 -1
  51. package/dist/startup.d.ts.map +1 -1
  52. package/dist/startup.js +82 -11
  53. package/dist/startup.js.map +1 -1
  54. package/dist/totp.d.ts +42 -0
  55. package/dist/totp.d.ts.map +1 -0
  56. package/dist/totp.js +176 -0
  57. package/dist/totp.js.map +1 -0
  58. package/dist/totpCli.d.ts +11 -0
  59. package/dist/totpCli.d.ts.map +1 -0
  60. package/dist/totpCli.js +46 -0
  61. package/dist/totpCli.js.map +1 -0
  62. package/package.json +8 -7
  63. package/playground/server.mjs +13 -3
  64. package/src/audit.ts +3 -1
  65. package/src/cli.ts +10 -1
  66. package/src/config.ts +71 -7
  67. package/src/elicitation.ts +35 -17
  68. package/src/gateway.ts +18 -5
  69. package/src/hooks/agentLinks.ts +58 -0
  70. package/src/hooks/claudeCode.ts +40 -9
  71. package/src/hooks/index.ts +1 -0
  72. package/src/hooks/run.ts +5 -2
  73. package/src/index.ts +3 -0
  74. package/src/init/suggest.ts +10 -1
  75. package/src/invoker.ts +153 -21
  76. package/src/openfga.ts +101 -0
  77. package/src/startup.ts +79 -11
  78. package/src/totp.ts +191 -0
  79. package/src/totpCli.ts +52 -0
  80. package/src/types/qrcode-terminal.d.ts +4 -0
package/dist/invoker.js CHANGED
@@ -1,38 +1,116 @@
1
1
  import { DECISION_INFO_KEY, INVOKE_METHOD, LIST_METHOD, } from "@adtl/interceptors";
2
2
  import { z } from "zod";
3
3
  const AnyResult = z.object({}).passthrough();
4
- /** Untyped request: interceptor methods are extension methods the SDK does not type. */
4
+ /**
5
+ * Untyped request: interceptor methods are extension methods the SDK does not type.
6
+ * The timeout is enforced here too, so a client that ignores it can't hang a phase.
7
+ */
5
8
  function request(client, method, params, timeout) {
6
9
  const r = client.request;
7
- return r.call(client, { method, params }, AnyResult, { timeout });
10
+ const controller = new AbortController();
11
+ let timer;
12
+ const expired = new Promise((_, reject) => {
13
+ timer = setTimeout(() => {
14
+ controller.abort();
15
+ reject(new Error(`timed out after ${timeout} ms`));
16
+ }, timeout);
17
+ });
18
+ return Promise.race([r.call(client, { method, params }, AnyResult, { timeout, signal: controller.signal }), expired]).finally(() => clearTimeout(timer));
8
19
  }
9
- function priority(def, phase) {
10
- const p = def.priorityHint;
20
+ /** SEP-2624 `resolvePriority`: the override's hint, else the interceptor's. */
21
+ export function resolvePriority(def, overrides, phase) {
22
+ const p = overrides?.priorityHint ?? def.priorityHint;
11
23
  if (p === undefined)
12
24
  return 0;
13
25
  if (typeof p === "number")
14
26
  return p;
15
27
  return p[phase] ?? 0;
16
28
  }
17
- function hooks(def, event, phase) {
18
- return def.hooks.some((h) => h.phase === phase && (h.events.includes(event) || h.events.includes("*")));
29
+ function matches(hooks, event, phase) {
30
+ return hooks.some((h) => h.phase === phase && (h.events.includes(event) || h.events.includes("*")));
31
+ }
32
+ /**
33
+ * Problems with `overrides` for these interceptors: an unknown name, or hooks
34
+ * that widen what the interceptor declares (which SEP-2624 says to reject).
35
+ */
36
+ export function checkOverrides(defs, overrides) {
37
+ const problems = [];
38
+ for (const [name, o] of Object.entries(overrides)) {
39
+ const def = defs.find((d) => d.name === name);
40
+ if (!def) {
41
+ problems.push(`${name}: no such interceptor (offered: ${defs.map((d) => d.name).join(", ")})`);
42
+ continue;
43
+ }
44
+ for (const h of o.hooks ?? []) {
45
+ for (const event of h.events) {
46
+ const declared = def.hooks.some((d) => d.phase === h.phase && (d.events.includes("*") || (event !== "*" && d.events.includes(event))));
47
+ if (!declared)
48
+ problems.push(`${name}: hooks may only narrow the declared hooks, and ${event} (${h.phase}) is not declared`);
49
+ }
50
+ }
51
+ }
52
+ return problems;
53
+ }
54
+ /** Interceptors of a type this invoker doesn't run (e.g. the proposed `sink`). They are never invoked. */
55
+ export function unsupportedInterceptors(bound) {
56
+ return bound
57
+ .filter((b) => b.definition.type !== "validation" && b.definition.type !== "mutation")
58
+ .map((b) => `${b.definition.name} (${String(b.definition.type)})`);
59
+ }
60
+ /** Interceptor names offered by more than one server: each must be invoked on its own server, so names must be unique. */
61
+ export function duplicateInterceptors(bound) {
62
+ const servers = new Map();
63
+ for (const b of bound)
64
+ servers.set(b.definition.name, [...(servers.get(b.definition.name) ?? []), b.server ?? "?"]);
65
+ return [...servers].filter(([, s]) => s.length > 1).map(([name, s]) => `${name} (offered by ${s.join(", ")})`);
66
+ }
67
+ /**
68
+ * Mutators that would run after `name` on a phase both hook, so they see (and
69
+ * could change or drop) what it wrote. Used to warn when another server's
70
+ * mutator runs after adtl.label.
71
+ */
72
+ export function mutatorsAfter(bound, name, overrides = {}) {
73
+ const target = bound.find((b) => b.definition.name === name);
74
+ if (!target)
75
+ return [];
76
+ const hooksOf = (b) => overrides[b.definition.name]?.hooks ?? b.definition.hooks;
77
+ const shares = (b, phase) => hooksOf(b).some((h) => h.phase === phase && hooksOf(target).some((t) => t.phase === phase && (h.events.includes("*") || t.events.includes("*") || h.events.some((e) => t.events.includes(e)))));
78
+ const after = [];
79
+ for (const b of bound) {
80
+ if (b === target || b.definition.type !== "mutation")
81
+ continue;
82
+ const late = ["request", "response"].some((phase) => {
83
+ if (!shares(b, phase))
84
+ return false;
85
+ const p = resolvePriority(b.definition, overrides[b.definition.name], phase);
86
+ const t = resolvePriority(target.definition, overrides[name], phase);
87
+ return p > t || (p === t && b.definition.name.localeCompare(name) > 0);
88
+ });
89
+ if (late)
90
+ after.push(b.definition.name);
91
+ }
92
+ return after;
19
93
  }
20
94
  export class InterceptorInvoker {
21
95
  interceptors;
22
96
  timeoutMs;
23
97
  modeOverride;
98
+ overrides;
24
99
  constructor(interceptors, timeoutMs = 5000,
25
100
  /** Overrides the mode every interceptor declares. */
26
- modeOverride) {
101
+ modeOverride,
102
+ /** Per-interceptor overrides, by name. Check them with `checkOverrides` first. */
103
+ overrides = {}) {
27
104
  this.interceptors = interceptors;
28
105
  this.timeoutMs = timeoutMs;
29
106
  this.modeOverride = modeOverride;
107
+ this.overrides = overrides;
30
108
  }
31
109
  /** Discover the interceptors an interceptor server offers. */
32
- static async discover(client) {
110
+ static async discover(client, opts = {}) {
33
111
  const res = await request(client, LIST_METHOD, {}, 10_000);
34
112
  const defs = (res.interceptors ?? []);
35
- return defs.map((definition) => ({ client, definition }));
113
+ return defs.map((definition) => ({ client, definition, ...opts }));
36
114
  }
37
115
  get definitions() {
38
116
  return this.interceptors.map((i) => i.definition);
@@ -51,33 +129,56 @@ export class InterceptorInvoker {
51
129
  await this.mutate("response", opts, out);
52
130
  return out;
53
131
  }
132
+ override(i) {
133
+ return this.overrides[i.definition.name];
134
+ }
135
+ mode(i) {
136
+ return this.modeOverride ?? this.override(i)?.mode ?? i.definition.mode ?? "active";
137
+ }
54
138
  isAudit(i) {
55
- return (this.modeOverride ?? i.definition.mode) === "audit";
139
+ return this.mode(i) === "audit";
56
140
  }
57
- /** Record that `i` runs in `phase`, with its resolved policy. The gateway has no failOpen overrides. */
141
+ failOpen(i) {
142
+ return (this.override(i)?.failOpen ?? i.definition.failOpen) === true;
143
+ }
144
+ timeout(i) {
145
+ return this.override(i)?.timeoutMs ?? this.timeoutMs;
146
+ }
147
+ /** Record that `i` runs in `phase`, with its resolved policy. */
58
148
  run(i, phase, out) {
149
+ const o = this.override(i);
59
150
  const r = {
60
151
  name: i.definition.name,
61
152
  phase,
62
- mode: this.modeOverride ?? i.definition.mode ?? "active",
63
- modeFrom: this.modeOverride ? "override" : "default",
64
- failOpen: i.definition.failOpen === true,
65
- failOpenFrom: "default",
153
+ mode: this.mode(i),
154
+ modeFrom: this.modeOverride || o?.mode ? "override" : "default",
155
+ failOpen: this.failOpen(i),
156
+ failOpenFrom: o?.failOpen !== undefined ? "override" : "default",
157
+ timeoutMs: this.timeout(i),
66
158
  };
67
159
  out.ran.push(r);
68
160
  return r;
69
161
  }
70
162
  select(type, event, phase) {
71
- return this.interceptors.filter((i) => i.definition.type === type && hooks(i.definition, event, phase));
163
+ return this.interceptors.filter((i) => i.definition.type === type && matches(this.override(i)?.hooks ?? i.definition.hooks, event, phase));
72
164
  }
73
165
  async invoke(i, phase, opts, payload) {
74
- const res = await request(i.client, INVOKE_METHOD, { name: i.definition.name, event: opts.event, phase, payload, config: opts.config, timeoutMs: this.timeoutMs, context: opts.context }, this.timeoutMs);
166
+ const timeoutMs = this.timeout(i);
167
+ const res = await request(i.client, INVOKE_METHOD, {
168
+ name: i.definition.name,
169
+ event: opts.event,
170
+ phase,
171
+ payload,
172
+ ...(i.sendConfig === false ? {} : { config: opts.config }),
173
+ timeoutMs,
174
+ context: opts.context,
175
+ }, timeoutMs);
75
176
  return res;
76
177
  }
77
178
  /** Handle an interceptor failure. Returns false if the phase must stop. */
78
179
  failed(i, err, out) {
79
180
  const msg = `${i.definition.name} failed: ${err instanceof Error ? err.message : String(err)}`;
80
- if (this.isAudit(i) || i.definition.failOpen === true) {
181
+ if (this.isAudit(i) || this.failOpen(i)) {
81
182
  out.warnings.push(msg);
82
183
  return true;
83
184
  }
@@ -86,7 +187,8 @@ export class InterceptorInvoker {
86
187
  }
87
188
  /** Sequential mutations, atomic: on failure the original payload is kept. */
88
189
  async mutate(phase, opts, out) {
89
- const selected = this.select("mutation", opts.event, phase).sort((a, b) => priority(a.definition, phase) - priority(b.definition, phase) || a.definition.name.localeCompare(b.definition.name));
190
+ const selected = this.select("mutation", opts.event, phase).sort((a, b) => resolvePriority(a.definition, this.override(a), phase) - resolvePriority(b.definition, this.override(b), phase) ||
191
+ a.definition.name.localeCompare(b.definition.name));
90
192
  let payload = out.payload;
91
193
  for (const i of selected) {
92
194
  const ran = this.run(i, phase, out);
@@ -1 +1 @@
1
- {"version":3,"file":"invoker.js","sourceRoot":"","sources":["../src/invoker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"invoker.js","sourceRoot":"","sources":["../src/invoker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { AuthorizationDecision, AuthorizationRequest, Authorizer } from "./authorizer.js";
2
+ import type { OpenFgaConfig } from "./config.js";
3
+ export declare class OpenFgaAuthorizer implements Authorizer {
4
+ private readonly cfg;
5
+ private readonly fetchFn;
6
+ readonly name = "openfga";
7
+ constructor(cfg: OpenFgaConfig, fetchFn?: typeof fetch);
8
+ private user;
9
+ /** The object of this call, or a reason it can't be built. "listing" means: decide when called. */
10
+ private object;
11
+ check(req: AuthorizationRequest): Promise<AuthorizationDecision>;
12
+ }
13
+ //# sourceMappingURL=openfga.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfga.d.ts","sourceRoot":"","sources":["../src/openfga.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAYjD,qBAAa,iBAAkB,YAAW,UAAU;IAIhD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,QAAQ,CAAC,IAAI,aAAa;gBAGP,GAAG,EAAE,aAAa,EAClB,OAAO,GAAE,OAAO,KAAa;IAGhD,OAAO,CAAC,IAAI;IAMZ,mGAAmG;IACnG,OAAO,CAAC,MAAM;IAqBR,KAAK,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAuBvE"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Relationship-based authorization with OpenFGA (`gateway.openfga`):
3
+ *
4
+ * openfga:
5
+ * url: http://localhost:8080
6
+ * storeId: "${FGA_STORE_ID}"
7
+ * modelId: "${FGA_MODEL_ID}" # optional: pin an authorization model
8
+ * token: "${FGA_TOKEN}" # optional: bearer token
9
+ * relation: can_use # optional: the default relation
10
+ * timeoutMs: 2000 # optional
11
+ * tools: # optional: per-resource rules, from the call's arguments
12
+ * github.add_issue_comment: { relation: can_comment, object: "repo:{owner}/{repo}" }
13
+ *
14
+ * Every call becomes one OpenFGA check:
15
+ *
16
+ * user user:<id>, service:<id>, or user:anonymous without an id
17
+ * relation the tool's rule, else `relation`
18
+ * object the tool's rule, else tool:<server>.<tool>, prompt:<server>.<name> or resource:<uri>
19
+ *
20
+ * Ids are percent-encoded, because OpenFGA ids can't hold `:`, `#`, `@` or
21
+ * spaces; ids too long for OpenFGA are replaced by their SHA-256. A rule's
22
+ * `{argument}` must be a string or number, or the call is denied. Tool lists
23
+ * have no arguments, so tools whose object needs them stay listed and are
24
+ * checked when called. An unreachable server or an error denies the call.
25
+ *
26
+ * Works with Auth0 FGA too, by pointing `url` at its API and passing a token.
27
+ */
28
+ import { createHash } from "node:crypto";
29
+ /** OpenFGA's limit on the id part of an object or user. */
30
+ const MAX_ID = 254;
31
+ function fgaId(value) {
32
+ const id = encodeURIComponent(value);
33
+ return id.length <= MAX_ID ? id : `sha256-${createHash("sha256").update(value).digest("hex")}`;
34
+ }
35
+ const PLACEHOLDER = /\{([A-Za-z0-9_.-]+)\}/g;
36
+ export class OpenFgaAuthorizer {
37
+ cfg;
38
+ fetchFn;
39
+ name = "openfga";
40
+ constructor(cfg, fetchFn = fetch) {
41
+ this.cfg = cfg;
42
+ this.fetchFn = fetchFn;
43
+ }
44
+ user(req) {
45
+ const p = req.principal;
46
+ if (p.type === "anonymous" || !p.id)
47
+ return "user:anonymous";
48
+ return `${p.type === "service" ? "service" : "user"}:${fgaId(p.id)}`;
49
+ }
50
+ /** The object of this call, or a reason it can't be built. "listing" means: decide when called. */
51
+ object(req, template) {
52
+ if (template !== undefined) {
53
+ if (req.arguments === undefined && template.search(PLACEHOLDER) !== -1)
54
+ return "listing";
55
+ const colon = template.indexOf(":");
56
+ const type = template.slice(0, colon + 1);
57
+ let missing;
58
+ const id = template.slice(colon + 1).replace(PLACEHOLDER, (_, name) => {
59
+ const v = req.arguments?.[name];
60
+ if (typeof v !== "string" && typeof v !== "number") {
61
+ missing ??= name;
62
+ return "";
63
+ }
64
+ return String(v);
65
+ });
66
+ return missing !== undefined ? { missing } : { object: `${type}${fgaId(id)}` };
67
+ }
68
+ if (req.tool !== undefined)
69
+ return { object: `tool:${fgaId(`${req.server}.${req.tool}`)}` };
70
+ if (req.prompt !== undefined)
71
+ return { object: `prompt:${fgaId(`${req.server}.${req.prompt}`)}` };
72
+ return { object: `resource:${fgaId(req.resource ?? "")}` };
73
+ }
74
+ async check(req) {
75
+ const rule = req.tool !== undefined ? this.cfg.tools[`${req.server}.${req.tool}`] : undefined;
76
+ const target = this.object(req, rule?.object);
77
+ if (target === "listing")
78
+ return { allow: true };
79
+ const what = req.tool ?? req.prompt ?? req.resource;
80
+ if ("missing" in target)
81
+ return { allow: false, reason: `openfga: ${what} has no usable argument "${target.missing}"` };
82
+ const user = this.user(req);
83
+ const relation = rule?.relation ?? this.cfg.relation;
84
+ const res = await this.fetchFn(`${this.cfg.url.replace(/\/+$/, "")}/stores/${encodeURIComponent(this.cfg.storeId)}/check`, {
85
+ method: "POST",
86
+ headers: { "content-type": "application/json", ...(this.cfg.token ? { authorization: `Bearer ${this.cfg.token}` } : {}) },
87
+ body: JSON.stringify({
88
+ tuple_key: { user, relation, object: target.object },
89
+ ...(this.cfg.modelId ? { authorization_model_id: this.cfg.modelId } : {}),
90
+ }),
91
+ signal: AbortSignal.timeout(this.cfg.timeoutMs),
92
+ });
93
+ if (!res.ok)
94
+ throw new Error(`OpenFGA answered ${res.status}`);
95
+ const body = (await res.json());
96
+ if (body.allowed === true)
97
+ return { allow: true };
98
+ return { allow: false, reason: `OpenFGA: ${user} has no ${relation} on ${target.object}` };
99
+ }
100
+ }
101
+ //# sourceMappingURL=openfga.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfga.js","sourceRoot":"","sources":["../src/openfga.ts"],"names":[],"mappings":"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"}
package/dist/startup.d.ts CHANGED
@@ -32,16 +32,25 @@ export declare function gatewayPrincipal(cfg: GatewayConfig, env: NodeJS.Process
32
32
  * The configured authorizers, in the order they are asked: roles, then cedar.
33
33
  * Cedar files are read and parsed here, so a bad policy fails startup.
34
34
  */
35
- export declare function gatewayAuthorizers(cfg: GatewayConfig, baseDir: string): Promise<Authorizer[]>;
35
+ export declare function gatewayAuthorizers(cfg: GatewayConfig, baseDir: string, env?: NodeJS.ProcessEnv): Promise<Authorizer[]>;
36
36
  /**
37
37
  * Under Claude Code, which passes `CLAUDE_CODE_SESSION_ID` to stdio MCP
38
38
  * servers, the gateway uses that id and keeps session labels in files, so the
39
39
  * Claude Code hooks (`adtl-gateway hook`) add to the same session label.
40
+ *
41
+ * `ADTL_SESSION_ID` does the same for any agent framework, and wins over
42
+ * Claude Code's: a sub-agent's gateway started with its parent's session id
43
+ * starts from the parent's label, and what it reads taints the parent too.
40
44
  */
41
45
  export declare function sharedSession(env: NodeJS.ProcessEnv): {
42
46
  sessionId: string;
43
47
  dir: string;
44
48
  } | undefined;
49
+ /** `ADTL_AGENT_ID` (and `ADTL_AGENT_TYPE`): which agent this gateway serves, for the audit log. */
50
+ export declare function gatewayAgent(env: NodeJS.ProcessEnv): {
51
+ id: string;
52
+ type?: string;
53
+ } | undefined;
45
54
  export interface StartedGateway {
46
55
  gateway: AdtlGateway;
47
56
  close(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,EAAuC,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGpF,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAML,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAKhF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAS3E;AAED,8GAA8G;AAC9G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAqB/E;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C;AAaD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO/F;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS,CAwB1H;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAqB3F;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,GAAG,SAAS,CAMlG;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAWnG;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGpG;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAO,GAC7D,OAAO,CAAC,cAAc,CAAC,CA2FzB"}
1
+ {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,EAAuC,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGpF,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAML,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAOhF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAS3E;AAED,8GAA8G;AAC9G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAqB/E;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C;AAaD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO/F;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS,CAyB1H;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAqB3F;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,GAAG,SAAS,CAMlG;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAwBzI;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGpG;AAED,mGAAmG;AACnG,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAI9F;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAO,GAC7D,OAAO,CAAC,cAAc,CAAC,CAoIzB"}
package/dist/startup.js CHANGED
@@ -18,7 +18,9 @@ import { CedarAuthorizer } from "./cedar.js";
18
18
  import { GatewayConfigSchema, expandApprovals, expandEnv, expandUpstream, isHttpUpstream, } from "./config.js";
19
19
  import { EmailNotifier } from "./email.js";
20
20
  import { AdtlGateway, GATEWAY_VERSION } from "./gateway.js";
21
- import { InterceptorInvoker } from "./invoker.js";
21
+ import { InterceptorInvoker, checkOverrides, duplicateInterceptors, mutatorsAfter, unsupportedInterceptors } from "./invoker.js";
22
+ import { OpenFgaAuthorizer } from "./openfga.js";
23
+ import { loadTotpVerifier } from "./totp.js";
22
24
  import { NtfyNotifier } from "./ntfy.js";
23
25
  import { RoleAuthorizer } from "./roles.js";
24
26
  export class GatewayConfigError extends Error {
@@ -103,13 +105,14 @@ export function createApprovals(cfg, env, log) {
103
105
  notifiers.push(new EmailNotifier({ smtp: a.email.smtp, from: a.email.from, to: [a.email.to].flat(), on: a.email.on }));
104
106
  }
105
107
  const approverChannels = new Map(Object.entries(a.approvers ?? {}).map(([id, c]) => [id, [new NtfyNotifier({ ...c.ntfy, name: `ntfy:${id}` })]]));
106
- if (notifiers.length === 0 && approverChannels.size === 0 && !a.elicitation)
108
+ if (notifiers.length === 0 && approverChannels.size === 0 && !a.elicitation && !a.totp)
107
109
  return undefined;
108
- if (!notifiers.some((n) => n.listen) && approverChannels.size === 0 && !a.elicitation) {
110
+ if (!notifiers.some((n) => n.listen) && approverChannels.size === 0 && !a.elicitation && !a.totp) {
109
111
  log.warn('no approval channel can carry answers (configure gateway.approvals.ntfy); "ask" still blocks');
110
112
  }
111
113
  const approvers = approverChannels.size ? `; approvers: ${[...approverChannels.keys()].join(", ")}` : "";
112
- const shared = [...notifiers.map((n) => n.name), ...(a.elicitation ? ["elicitation (if the client supports it)"] : [])];
114
+ const inClient = a.totp ? ["authenticator code (if the client supports elicitation)"] : a.elicitation ? ["elicitation (if the client supports it)"] : [];
115
+ const shared = [...notifiers.map((n) => n.name), ...inClient];
113
116
  log.info(`approvals: ${shared.join(", ") || "none shared"}${approvers} (timeout ${a.timeoutSeconds}s)`);
114
117
  return new ApprovalBroker({ notifiers, approverChannels, timeoutMs: a.timeoutSeconds * 1000, log });
115
118
  }
@@ -158,7 +161,7 @@ export function gatewayPrincipal(cfg, env) {
158
161
  * The configured authorizers, in the order they are asked: roles, then cedar.
159
162
  * Cedar files are read and parsed here, so a bad policy fails startup.
160
163
  */
161
- export async function gatewayAuthorizers(cfg, baseDir) {
164
+ export async function gatewayAuthorizers(cfg, baseDir, env = process.env) {
162
165
  const out = [];
163
166
  if (cfg.roles)
164
167
  out.push(new RoleAuthorizer(cfg.roles));
@@ -170,23 +173,44 @@ export async function gatewayAuthorizers(cfg, baseDir) {
170
173
  throw new GatewayConfigError(err.message);
171
174
  }
172
175
  }
176
+ if (cfg.openfga) {
177
+ const f = cfg.openfga;
178
+ const expand = (v, key) => expandEnv(v, env, `gateway.openfga.${key}`);
179
+ out.push(new OpenFgaAuthorizer({
180
+ ...f,
181
+ url: expand(f.url, "url"),
182
+ storeId: expand(f.storeId, "storeId"),
183
+ ...(f.modelId !== undefined ? { modelId: expand(f.modelId, "modelId") } : {}),
184
+ ...(f.token !== undefined ? { token: expand(f.token, "token") } : {}),
185
+ }));
186
+ }
173
187
  return out;
174
188
  }
175
189
  /**
176
190
  * Under Claude Code, which passes `CLAUDE_CODE_SESSION_ID` to stdio MCP
177
191
  * servers, the gateway uses that id and keeps session labels in files, so the
178
192
  * Claude Code hooks (`adtl-gateway hook`) add to the same session label.
193
+ *
194
+ * `ADTL_SESSION_ID` does the same for any agent framework, and wins over
195
+ * Claude Code's: a sub-agent's gateway started with its parent's session id
196
+ * starts from the parent's label, and what it reads taints the parent too.
179
197
  */
180
198
  export function sharedSession(env) {
181
- const sessionId = env.CLAUDE_CODE_SESSION_ID?.trim();
199
+ const sessionId = env.ADTL_SESSION_ID?.trim() || env.CLAUDE_CODE_SESSION_ID?.trim();
182
200
  return sessionId ? { sessionId, dir: defaultSessionsDir(env) } : undefined;
183
201
  }
202
+ /** `ADTL_AGENT_ID` (and `ADTL_AGENT_TYPE`): which agent this gateway serves, for the audit log. */
203
+ export function gatewayAgent(env) {
204
+ const id = env.ADTL_AGENT_ID?.trim();
205
+ const type = env.ADTL_AGENT_TYPE?.trim();
206
+ return id ? { id, ...(type ? { type } : {}) } : undefined;
207
+ }
184
208
  export async function startGateway(loaded, opts = {}) {
185
209
  const env = opts.env ?? process.env;
186
210
  // Config problems that need no process: fail before starting any.
187
211
  const approverMembers = approverRoles(loaded.labels, loaded.gateway);
188
212
  const baseDir = dirname(loaded.path);
189
- const authorizers = await gatewayAuthorizers(loaded.gateway, baseDir);
213
+ const authorizers = await gatewayAuthorizers(loaded.gateway, baseDir, env);
190
214
  const log = opts.logger ?? { info: (m) => console.error(`[adtl-gateway] ${m}`), warn: (m) => console.error(`[adtl-gateway] warning: ${m}`) };
191
215
  const clients = [];
192
216
  const closeAll = () => Promise.allSettled(clients.map((c) => c.close())).then(() => undefined);
@@ -211,15 +235,54 @@ export async function startGateway(loaded, opts = {}) {
211
235
  if (!interceptors.getServerCapabilities()?.extensions?.[INTERCEPTORS_EXTENSION]) {
212
236
  throw new GatewayConfigError(`The interceptor server does not declare the ${INTERCEPTORS_EXTENSION} extension`);
213
237
  }
214
- const bound = await InterceptorInvoker.discover(interceptors);
215
- const names = bound.map((b) => b.definition.name);
238
+ const own = await InterceptorInvoker.discover(interceptors, { server: "interceptors" });
239
+ const ownNames = own.map((b) => b.definition.name);
216
240
  for (const required of [POLICY_INTERCEPTOR, LABEL_INTERCEPTOR]) {
217
- if (!names.includes(required)) {
241
+ if (!ownNames.includes(required)) {
218
242
  throw new GatewayConfigError(`The interceptor server does not offer ${required}; refusing to start without it`);
219
243
  }
220
244
  }
245
+ // More interceptor servers (SEP-2624: interceptors may come from N servers, each invoked where it was advertised).
246
+ // A server that can't be reached stops startup: the owner asked for its interceptors.
247
+ const bound = [...own];
248
+ for (const [id, server] of Object.entries(loaded.gateway.interceptorServers)) {
249
+ const where = `gateway.interceptorServers.${id}`;
250
+ let client;
251
+ try {
252
+ client = await connectUpstream(`interceptors:${id}`, expandUpstream(id, server, env), baseDir);
253
+ }
254
+ catch (err) {
255
+ throw new GatewayConfigError(`${where}: could not connect: ${err instanceof Error ? err.message : String(err)}`);
256
+ }
257
+ clients.push(client);
258
+ if (!client.getServerCapabilities()?.extensions?.[INTERCEPTORS_EXTENSION]) {
259
+ throw new GatewayConfigError(`${where} does not declare the ${INTERCEPTORS_EXTENSION} extension`);
260
+ }
261
+ bound.push(...(await InterceptorInvoker.discover(client, { server: id, sendConfig: false })));
262
+ }
263
+ const duplicates = duplicateInterceptors(bound);
264
+ if (duplicates.length)
265
+ throw new GatewayConfigError(`Interceptor names must be unique across servers: ${duplicates.join("; ")}`);
266
+ const names = bound.map((b) => b.definition.name);
267
+ const overrides = loaded.gateway.interceptorOverrides;
268
+ const problems = checkOverrides(bound.map((b) => b.definition), overrides);
269
+ if (problems.length)
270
+ throw new GatewayConfigError(`gateway.interceptorOverrides: ${problems.join("; ")}`);
271
+ const unsupported = unsupportedInterceptors(bound);
272
+ if (unsupported.length)
273
+ log.warn(`not running interceptors of an unknown type: ${unsupported.join(", ")}`);
274
+ const late = mutatorsAfter(bound, LABEL_INTERCEPTOR, overrides);
275
+ if (late.length) {
276
+ log.warn(`${late.join(", ")} run after ${LABEL_INTERCEPTOR} and could change or drop its label; give them a lower priorityHint`);
277
+ }
278
+ for (const name of [POLICY_INTERCEPTOR, LABEL_INTERCEPTOR]) {
279
+ const o = overrides[name];
280
+ if (o?.mode === "audit" || o?.failOpen === true || o?.hooks) {
281
+ log.warn(`gateway.interceptorOverrides relaxes ${name} (${Object.keys(o).join(", ")}): calls it would stop may get through`);
282
+ }
283
+ }
221
284
  const audit = loaded.gateway.mode === "audit";
222
- const invoker = new InterceptorInvoker(bound, loaded.gateway.interceptorTimeoutMs, audit ? "audit" : undefined);
285
+ const invoker = new InterceptorInvoker(bound, loaded.gateway.interceptorTimeoutMs, audit ? "audit" : undefined, overrides);
223
286
  log.info(`interceptors: ${names.join(", ")}`);
224
287
  if (shared)
225
288
  log.info(`sharing session labels with Claude Code hooks (${shared.dir})`);
@@ -257,8 +320,16 @@ export async function startGateway(loaded, opts = {}) {
257
320
  for (const a of authorizers)
258
321
  if (a.name !== "roles")
259
322
  log.info(`authorizer: ${a.name}`);
323
+ const totp = loaded.gateway.approvals?.totp ? loadTotpVerifier(env) : undefined;
324
+ if (loaded.gateway.approvals?.totp && !totp)
325
+ throw new GatewayConfigError("gateway.approvals.totp is on, but no secret is set up: run adtl-gateway totp setup");
326
+ const agent = gatewayAgent(env);
327
+ if (agent)
328
+ log.info(`agent: ${agent.id}${agent.type ? ` (${agent.type})` : ""}`);
260
329
  const gateway = new AdtlGateway({
261
330
  ...(shared ? { sessionId: shared.sessionId } : {}),
331
+ ...(agent ? { agent } : {}),
332
+ ...(totp ? { totp } : {}),
262
333
  upstreams,
263
334
  invoker,
264
335
  ...(auditLog ? { audit: auditLog } : {}),