@adtl/gateway 0.3.2 → 0.5.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 (53) hide show
  1. package/README.md +86 -2
  2. package/dist/audit.d.ts +23 -0
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/audit.js +137 -2
  5. package/dist/audit.js.map +1 -1
  6. package/dist/auditCli.d.ts +7 -0
  7. package/dist/auditCli.d.ts.map +1 -0
  8. package/dist/auditCli.js +54 -0
  9. package/dist/auditCli.js.map +1 -0
  10. package/dist/authorizer.d.ts +50 -0
  11. package/dist/authorizer.d.ts.map +1 -0
  12. package/dist/authorizer.js +15 -0
  13. package/dist/authorizer.js.map +1 -0
  14. package/dist/cli.js +19 -1
  15. package/dist/cli.js.map +1 -1
  16. package/dist/gateway.d.ts +12 -3
  17. package/dist/gateway.d.ts.map +1 -1
  18. package/dist/gateway.js +89 -15
  19. package/dist/gateway.js.map +1 -1
  20. package/dist/hooks/claudeCode.d.ts +8 -1
  21. package/dist/hooks/claudeCode.d.ts.map +1 -1
  22. package/dist/hooks/claudeCode.js +51 -4
  23. package/dist/hooks/claudeCode.js.map +1 -1
  24. package/dist/hooks/run.d.ts.map +1 -1
  25. package/dist/hooks/run.js +9 -3
  26. package/dist/hooks/run.js.map +1 -1
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/invoker.d.ts +9 -6
  32. package/dist/invoker.d.ts.map +1 -1
  33. package/dist/invoker.js +11 -9
  34. package/dist/invoker.js.map +1 -1
  35. package/dist/ledgerCli.d.ts +7 -0
  36. package/dist/ledgerCli.d.ts.map +1 -0
  37. package/dist/ledgerCli.js +106 -0
  38. package/dist/ledgerCli.js.map +1 -0
  39. package/dist/startup.d.ts.map +1 -1
  40. package/dist/startup.js +4 -2
  41. package/dist/startup.js.map +1 -1
  42. package/package.json +5 -4
  43. package/src/audit.ts +144 -2
  44. package/src/auditCli.ts +53 -0
  45. package/src/authorizer.ts +60 -0
  46. package/src/cli.ts +19 -1
  47. package/src/gateway.ts +96 -17
  48. package/src/hooks/claudeCode.ts +55 -5
  49. package/src/hooks/run.ts +9 -3
  50. package/src/index.ts +3 -0
  51. package/src/invoker.ts +24 -17
  52. package/src/ledgerCli.ts +99 -0
  53. package/src/startup.ts +4 -2
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./config.js";
2
2
  export * from "./invoker.js";
3
3
  export * from "./audit.js";
4
+ export * from "./authorizer.js";
4
5
  export * from "./approvals.js";
5
6
  export * from "./ntfy.js";
6
7
  export * from "./email.js";
@@ -8,4 +9,6 @@ export * from "./gateway.js";
8
9
  export * from "./startup.js";
9
10
  export * from "./init/index.js";
10
11
  export * from "./hooks/index.js";
12
+ export * from "./ledgerCli.js";
13
+ export * from "./auditCli.js";
11
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC"}
package/dist/invoker.d.ts CHANGED
@@ -6,7 +6,8 @@
6
6
  * - Receiving (response phase, upstream → gateway): Validate (parallel) →
7
7
  * Mutate (sequential).
8
8
  *
9
- * Only `severity: "error"` blocks. Audit-mode interceptors never block, and
9
+ * Only `severity: "error"` blocks. A blocking result with a `confirmation`
10
+ * request is an "ask"; the gateway may ask a human and re-validate. Audit-mode interceptors never block, and
10
11
  * their mutations are not applied. An interceptor that fails (error or
11
12
  * timeout) blocks the message unless it declares `failOpen: true`.
12
13
  *
@@ -14,7 +15,7 @@
14
15
  * (e.g. audit in staging, active in production).
15
16
  */
16
17
  import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
17
- import { type InterceptorDefinition, type InterceptorResult, type InvocationContext } from "@adtl/interceptors";
18
+ import { type ConfirmationRequest, type InterceptorDefinition, type InterceptorResult, type InvocationContext } from "@adtl/interceptors";
18
19
  import type { Decision } from "@adtl/labels";
19
20
  export type InterceptorMode = NonNullable<InterceptorDefinition["mode"]>;
20
21
  export interface BoundInterceptor {
@@ -25,8 +26,10 @@ export interface Blocked {
25
26
  interceptor: string;
26
27
  decision: Decision;
27
28
  reason: string;
29
+ /** Set when the validator would accept a human confirmation. */
30
+ confirmation?: ConfirmationRequest;
28
31
  }
29
- export interface ChainOutcome {
32
+ export interface PhaseOutcome {
30
33
  payload: unknown;
31
34
  blocked?: Blocked;
32
35
  results: InterceptorResult[];
@@ -50,12 +53,12 @@ export declare class InterceptorInvoker {
50
53
  /** Discover the interceptors an interceptor server offers. */
51
54
  static discover(client: Client): Promise<BoundInterceptor[]>;
52
55
  get definitions(): InterceptorDefinition[];
53
- runRequest(opts: InvokeOptions): Promise<ChainOutcome>;
54
- runResponse(opts: InvokeOptions): Promise<ChainOutcome>;
56
+ runRequest(opts: InvokeOptions): Promise<PhaseOutcome>;
57
+ runResponse(opts: InvokeOptions): Promise<PhaseOutcome>;
55
58
  private isAudit;
56
59
  private select;
57
60
  private invoke;
58
- /** Handle an interceptor failure. Returns false if the chain must stop. */
61
+ /** Handle an interceptor failure. Returns false if the phase must stop. */
59
62
  private failed;
60
63
  /** Sequential mutations, atomic: on failure the original payload is kept. */
61
64
  private mutate;
@@ -1 +1 @@
1
- {"version":3,"file":"invoker.d.ts","sourceRoot":"","sources":["../src/invoker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAIvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAa7C,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,qBAAqB,CAAC;CACnC;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAaD,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe;gBAHtB,YAAY,EAAE,gBAAgB,EAAE,EAChC,SAAS,SAAO;IACjC,qDAAqD;IAC5C,YAAY,CAAC,EAAE,eAAe,YAAA;IAGzC,8DAA8D;WACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAMlE,IAAI,WAAW,IAAI,qBAAqB,EAAE,CAEzC;IAEK,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAOtD,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAO7D,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;YAIA,MAAM;IAUpB,2EAA2E;IAC3E,OAAO,CAAC,MAAM;IAUd,6EAA6E;YAC/D,MAAM;IAoBpB,0DAA0D;YAC5C,QAAQ;CAuBvB"}
1
+ {"version":3,"file":"invoker.d.ts","sourceRoot":"","sources":["../src/invoker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAIvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAa7C,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,qBAAqB,CAAC;CACnC;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAaD,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe;gBAHtB,YAAY,EAAE,gBAAgB,EAAE,EAChC,SAAS,SAAO;IACjC,qDAAqD;IAC5C,YAAY,CAAC,EAAE,eAAe,YAAA;IAGzC,8DAA8D;WACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAMlE,IAAI,WAAW,IAAI,qBAAqB,EAAE,CAEzC;IAEK,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAOtD,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAO7D,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;YAIA,MAAM;IAUpB,2EAA2E;IAC3E,OAAO,CAAC,MAAM;IAUd,6EAA6E;YAC/D,MAAM;IAoBpB,0DAA0D;YAC5C,QAAQ;CA0BvB"}
package/dist/invoker.js CHANGED
@@ -61,7 +61,7 @@ export class InterceptorInvoker {
61
61
  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);
62
62
  return res;
63
63
  }
64
- /** Handle an interceptor failure. Returns false if the chain must stop. */
64
+ /** Handle an interceptor failure. Returns false if the phase must stop. */
65
65
  failed(i, err, out) {
66
66
  const msg = `${i.definition.name} failed: ${err instanceof Error ? err.message : String(err)}`;
67
67
  if (this.isAudit(i) || i.definition.failOpen === true) {
@@ -73,9 +73,9 @@ export class InterceptorInvoker {
73
73
  }
74
74
  /** Sequential mutations, atomic: on failure the original payload is kept. */
75
75
  async mutate(phase, opts, out) {
76
- const chain = this.select("mutation", opts.event, phase).sort((a, b) => priority(a.definition, phase) - priority(b.definition, phase) || a.definition.name.localeCompare(b.definition.name));
76
+ 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));
77
77
  let payload = out.payload;
78
- for (const i of chain) {
78
+ for (const i of selected) {
79
79
  let r;
80
80
  try {
81
81
  r = (await this.invoke(i, phase, opts, payload));
@@ -94,11 +94,11 @@ export class InterceptorInvoker {
94
94
  }
95
95
  /** Parallel validations. Only severity "error" blocks. */
96
96
  async validate(phase, opts, out) {
97
- const chain = this.select("validation", opts.event, phase);
98
- const settled = await Promise.allSettled(chain.map((i) => this.invoke(i, phase, opts, out.payload)));
97
+ const selected = this.select("validation", opts.event, phase);
98
+ const settled = await Promise.allSettled(selected.map((i) => this.invoke(i, phase, opts, out.payload)));
99
99
  let ok = true;
100
100
  settled.forEach((s, idx) => {
101
- const i = chain[idx];
101
+ const i = selected[idx];
102
102
  if (s.status === "rejected") {
103
103
  if (!this.failed(i, s.reason, out))
104
104
  ok = false;
@@ -110,10 +110,12 @@ export class InterceptorInvoker {
110
110
  return;
111
111
  // Keep the strictest rejection, so an "ask" never hides another validator's "block".
112
112
  if (!out.blocked || out.blocked.decision === "ask") {
113
- const decision = r.info?.[DECISION_INFO_KEY] ?? "block";
113
+ // Older ADTL interceptor servers carry "ask" only in info.
114
+ const decision = r.confirmation ? "ask" : (r.info?.[DECISION_INFO_KEY] ?? "block");
114
115
  const reason = r.messages?.map((m) => m.message).join("; ") || `${i.definition.name} rejected the call`;
115
- if (!out.blocked || decision === "block")
116
- out.blocked = { interceptor: i.definition.name, decision, reason };
116
+ if (!out.blocked || decision === "block") {
117
+ out.blocked = { interceptor: i.definition.name, decision, reason, ...(r.confirmation ? { confirmation: r.confirmation } : {}) };
118
+ }
117
119
  }
118
120
  ok = false;
119
121
  });
@@ -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,7 @@
1
+ export declare const LEDGER_USAGE = "Usage: adtl-gateway ledger stats [-c <adtl.yaml>]\n adtl-gateway ledger verify [-c <adtl.yaml>]\n adtl-gateway ledger declassify <file>... [-c <adtl.yaml>] --reason <text>\n adtl-gateway ledger declassified [-c <adtl.yaml>] [--limit <n>]\n\nThe ledger remembers content written by sessions that had read untrusted or\nprivate data, and re-labels it when it is read back. It lives in\nledger.path from the config, else ADTL_LEDGER, else ~/.adtl/ledger.db.\n\n stats Count entries.\n verify Check that no entry was changed or removed (exit 1 if one was).\n declassify Clear the label of each file's current content. Check the\n files first: after this, ADTL treats that content as clean.\n --reason is required and kept in the ledger.\n declassified List recent declassifications: when, who, what and why.";
2
+ export interface LedgerCommandResult {
3
+ stdout: string;
4
+ exitCode: number;
5
+ }
6
+ export declare function runLedgerCommand(argv: string[], env?: NodeJS.ProcessEnv): Promise<LedgerCommandResult>;
7
+ //# sourceMappingURL=ledgerCli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledgerCli.d.ts","sourceRoot":"","sources":["../src/ledgerCli.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,YAAY,q2BAc+C,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyDzH"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * `adtl-gateway ledger`: look after the label ledger by hand.
3
+ *
4
+ * adtl-gateway ledger stats [-c adtl.yaml]
5
+ * adtl-gateway ledger verify [-c adtl.yaml]
6
+ * adtl-gateway ledger declassify <file>... [-c adtl.yaml] --reason <text>
7
+ * adtl-gateway ledger declassified [-c adtl.yaml] [--limit <n>]
8
+ *
9
+ * `declassify` clears the label of each file's current content, after you've
10
+ * checked it. It is meant to be run by a person; the Claude Code hook asks
11
+ * before letting the agent run it. The reason is required: declassifying is
12
+ * where taint tracking erodes, and the reason is what a later review reads.
13
+ * `declassified` lists recent declassifications for that review.
14
+ */
15
+ import { readFile } from "node:fs/promises";
16
+ import { userInfo } from "node:os";
17
+ import { dirname, resolve } from "node:path";
18
+ import { parseConfigText } from "@adtl/interceptors";
19
+ import { Ledger, chunkHashes, defaultLedgerPath } from "@adtl/ledger";
20
+ export const LEDGER_USAGE = `Usage: adtl-gateway ledger stats [-c <adtl.yaml>]
21
+ adtl-gateway ledger verify [-c <adtl.yaml>]
22
+ adtl-gateway ledger declassify <file>... [-c <adtl.yaml>] --reason <text>
23
+ adtl-gateway ledger declassified [-c <adtl.yaml>] [--limit <n>]
24
+
25
+ The ledger remembers content written by sessions that had read untrusted or
26
+ private data, and re-labels it when it is read back. It lives in
27
+ ledger.path from the config, else ADTL_LEDGER, else ~/.adtl/ledger.db.
28
+
29
+ stats Count entries.
30
+ verify Check that no entry was changed or removed (exit 1 if one was).
31
+ declassify Clear the label of each file's current content. Check the
32
+ files first: after this, ADTL treats that content as clean.
33
+ --reason is required and kept in the ledger.
34
+ declassified List recent declassifications: when, who, what and why.`;
35
+ export async function runLedgerCommand(argv, env = process.env) {
36
+ const [cmd, ...rest] = argv;
37
+ let config;
38
+ let reason;
39
+ let limit;
40
+ const files = [];
41
+ for (let i = 0; i < rest.length; i++) {
42
+ const a = rest[i];
43
+ if (a === "-c" || a === "--config")
44
+ config = rest[++i];
45
+ else if (a === "--reason")
46
+ reason = rest[++i];
47
+ else if (a === "--limit")
48
+ limit = Number(rest[++i]);
49
+ else if (a.startsWith("-"))
50
+ throw new Error(`Unknown argument: ${a}\n\n${LEDGER_USAGE}`);
51
+ else
52
+ files.push(a);
53
+ }
54
+ if (cmd === undefined || cmd === "-h" || cmd === "--help")
55
+ return { stdout: LEDGER_USAGE, exitCode: 0 };
56
+ if (!["stats", "verify", "declassify", "declassified"].includes(cmd))
57
+ throw new Error(`Unknown ledger command: ${cmd}\n\n${LEDGER_USAGE}`);
58
+ if (cmd === "declassify" && files.length === 0)
59
+ throw new Error(`declassify needs at least one file\n\n${LEDGER_USAGE}`);
60
+ if (cmd === "declassify" && !reason?.trim())
61
+ throw new Error(`declassify needs --reason: say why this content is safe\n\n${LEDGER_USAGE}`);
62
+ if (limit !== undefined && !(Number.isInteger(limit) && limit > 0))
63
+ throw new Error(`--limit must be a positive whole number\n\n${LEDGER_USAGE}`);
64
+ if (cmd !== "declassify" && files.length > 0)
65
+ throw new Error(`Unexpected argument: ${files[0]}\n\n${LEDGER_USAGE}`);
66
+ let path = defaultLedgerPath(env);
67
+ let retentionDays;
68
+ if (config) {
69
+ const abs = resolve(config);
70
+ const parsed = parseConfigText(await readFile(abs, "utf8"), abs);
71
+ if (parsed.ledger.path)
72
+ path = resolve(dirname(abs), parsed.ledger.path);
73
+ retentionDays = parsed.ledger.retentionDays;
74
+ }
75
+ const ledger = new Ledger(path, retentionDays ? { retentionDays } : {});
76
+ try {
77
+ if (cmd === "stats") {
78
+ const s = ledger.stats();
79
+ return { stdout: `${path}\n${s.records} records from ${s.writers} sessions, ${s.clears} declassified chunks (${s.entries} entries)`, exitCode: 0 };
80
+ }
81
+ if (cmd === "verify") {
82
+ const v = ledger.verify();
83
+ return v.ok
84
+ ? { stdout: `${path}: ${v.entries} entries, chain intact`, exitCode: 0 }
85
+ : { stdout: `${path}: TAMPERED: ${v.problem}`, exitCode: 1 };
86
+ }
87
+ if (cmd === "declassified") {
88
+ const list = ledger.declassifications(limit);
89
+ if (list.length === 0)
90
+ return { stdout: `${path}: nothing declassified`, exitCode: 0 };
91
+ const rows = list.map((d) => `${d.ts} ${d.by} ${d.subject ?? "-"} ${d.chunks} chunk${d.chunks === 1 ? "" : "s"} ${d.reason ?? "(no reason given)"}`);
92
+ return { stdout: rows.join("\n"), exitCode: 0 };
93
+ }
94
+ const by = `user:${userInfo().username}`;
95
+ const lines = [];
96
+ for (const f of files) {
97
+ const n = ledger.declassify(chunkHashes(await readFile(resolve(f), "utf8")), by, reason.trim(), f);
98
+ lines.push(n ? `${f}: cleared ${n} labeled chunk${n === 1 ? "" : "s"}` : `${f}: nothing labeled`);
99
+ }
100
+ return { stdout: lines.join("\n"), exitCode: 0 };
101
+ }
102
+ finally {
103
+ ledger.close();
104
+ }
105
+ }
106
+ //# sourceMappingURL=ledgerCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledgerCli.js","sourceRoot":"","sources":["../src/ledgerCli.ts"],"names":[],"mappings":"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"}
@@ -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,EAAsB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGnE,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAIhF,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,CAiB1H;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,CAwEzB"}
1
+ {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGnE,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAmB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAIhF,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,CAiB1H;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,CA0EzB"}
package/dist/startup.js CHANGED
@@ -126,12 +126,14 @@ export async function startGateway(loaded, opts = {}) {
126
126
  // 1. Interceptor server (out of process, per the Interceptors WG).
127
127
  const shared = sharedSession(env);
128
128
  const custom = loaded.gateway.interceptors && expandUpstream("interceptors", loaded.gateway.interceptors, env);
129
+ // The interceptor process starts with a minimal environment; pass on where the ledger lives.
130
+ const ledgerEnv = env.ADTL_LEDGER ? { ADTL_LEDGER: env.ADTL_LEDGER } : {};
129
131
  const icfg = custom
130
- ? { ...custom, env: { ...custom.env, ...(shared ? { ADTL_SESSIONS_DIR: shared.dir } : {}) } }
132
+ ? { ...custom, env: { ...ledgerEnv, ...custom.env, ...(shared ? { ADTL_SESSIONS_DIR: shared.dir } : {}) } }
131
133
  : {
132
134
  command: process.execPath,
133
135
  args: [bundledInterceptorsCli(), "--config", loaded.path, ...(shared ? ["--sessions-dir", shared.dir] : [])],
134
- env: {},
136
+ env: ledgerEnv,
135
137
  };
136
138
  const interceptors = await connectUpstream("interceptors", icfg, baseDir);
137
139
  clients.push(interceptors);
@@ -1 +1 @@
1
- {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AACxG,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAmB,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,cAAc,GAIf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAsB,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAQD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,kBAAkB,CAAC,2BAA2B,GAAG,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,IAAY;IAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,kBAAkB,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAA0B,CAAC;IAC7D,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,kBAAkB,CAAC,GAAG,GAAG,8EAA8E,CAAC,CAAC;IACrH,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IAChF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnG,MAAM,IAAI,kBAAkB,CAAC,GAAG,GAAG,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,sBAAsB;IACpC,+FAA+F;IAC/F,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;IACtF,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,cAAc,CAAC,CAAgB,EAAE,OAAe;IACvD,OAAO,IAAI,oBAAoB,CAAC;QAC9B,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,6FAA6F;QAC7F,GAAG,EAAE,EAAE,GAAG,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE;QAC7C,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAU,EAAE,CAAW,EAAE,OAAe;IAC5E,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,IAAI,6BAA6B,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5F,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAAC,GAAkB,EAAE,GAAsB,EAAE,GAAkB;IAC5F,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACX,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/F,GAAG,CAAC,IAAI,CAAC,2IAA2I,CAAC,CAAC;QACxJ,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACZ,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACzH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,8FAA8F,CAAC,CAAC;IAC/I,GAAG,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC;IACjG,OAAO,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,cAAc,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,MAAM,SAAS,GAAG,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAC;IACrD,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAoB,EACpB,OAA4D,EAAE;IAE9D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC;IAC7J,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAE/F,IAAI,CAAC;QACH,mEAAmE;QACnE,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,cAAc,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAC/G,6FAA6F;QAC7F,MAAM,SAAS,GAA2B,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClG,MAAM,IAAI,GAAkB,MAAM;YAChC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3G,CAAC,CAAC;gBACE,OAAO,EAAE,OAAO,CAAC,QAAQ;gBACzB,IAAI,EAAE,CAAC,sBAAsB,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5G,GAAG,EAAE,SAAS;aACf,CAAC;QACN,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,EAAE,UAAU,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,kBAAkB,CAAC,+CAA+C,sBAAsB,YAAY,CAAC,CAAC;QAClH,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAClD,KAAK,MAAM,QAAQ,IAAI,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,kBAAkB,CAAC,yCAAyC,QAAQ,gCAAgC,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChH,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,kDAAkD,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;QACtF,IAAI,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QAEjF,sEAAsE;QACtE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAE,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CACtG,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;YACnB,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACtB,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC/B,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,sFAAsF,CAAC,CAAC;gBAClH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CAAC,kCAAkC,EAAE,MAAO,CAAC,CAAC,MAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,IAAI,kBAAkB,CAAC,uCAAuC,CAAC,CAAC;QAChG,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE3D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9G,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,SAAS;YACT,OAAO;YACP,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,EAAE,GAAG;SACZ,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,QAAQ,EAAE,CAAC;QACjB,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adtl/gateway",
3
- "version": "0.3.2",
3
+ "version": "0.5.0",
4
4
  "description": "Experimental: MCP gateway that labels every tool result and blocks risky tool calls using ADTL trust labels",
5
5
  "keywords": [
6
6
  "mcp",
@@ -46,15 +46,16 @@
46
46
  "url": "https://github.com/probita-ai/adtl/issues"
47
47
  },
48
48
  "dependencies": {
49
- "@adtl/interceptors": "0.3.2",
50
- "@adtl/labels": "0.3.2",
49
+ "@adtl/interceptors": "0.5.0",
50
+ "@adtl/labels": "0.5.0",
51
+ "@adtl/ledger": "0.5.0",
51
52
  "@modelcontextprotocol/sdk": "1.31.0",
52
53
  "nodemailer": "10.0.12",
53
54
  "yaml": "2.9.1",
54
55
  "zod": "3.25.76"
55
56
  },
56
57
  "engines": {
57
- "node": ">=20"
58
+ "node": ">=22.13"
58
59
  },
59
60
  "publishConfig": {
60
61
  "access": "public"
package/src/audit.ts CHANGED
@@ -3,9 +3,21 @@
3
3
  *
4
4
  * Arguments and results are never written; the call is identified by its
5
5
  * hash, so the log can be shared without leaking the data it describes.
6
+ *
7
+ * Lines are hash-chained: each carries `prev` (the hash of the line before)
8
+ * and `hash` (over the canonical form of the line without `hash`), so
9
+ * `adtl-gateway audit verify` detects lines that were edited, removed,
10
+ * reordered or inserted. The gateway and the Claude Code hook (a new process
11
+ * per tool call) write the same file, so appends take a lock file
12
+ * (`<log>.lock`) to keep the chain from forking.
13
+ *
14
+ * The chain has no secret: an agent with shell access could rewrite the whole
15
+ * file consistently, and cutting lines off the end is not detected. Signed
16
+ * session receipts are planned for that.
6
17
  */
7
- import { appendFileSync, mkdirSync } from "node:fs";
18
+ import { closeSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, statSync, unlinkSync, writeSync } from "node:fs";
8
19
  import { dirname } from "node:path";
20
+ import { digest, sha256Hex } from "@adtl/labels";
9
21
 
10
22
  export interface AuditEntry {
11
23
  ts: string;
@@ -24,12 +36,18 @@ export interface AuditEntry {
24
36
  decision?: string;
25
37
  /** Present when the gateway ran in audit mode: nothing was stopped or changed. */
26
38
  mode?: "audit";
39
+ /** Present when the authorizer denied the caller: which one, and why. In audit mode the call still ran. */
40
+ denied?: { by: string; reason: string };
27
41
  /** Present when a human was asked: outcome, channel, approver (if known) and wait time. */
28
42
  approval?: { outcome: string; channel?: string; approver?: string; waitedMs: number };
29
43
  reason?: string;
30
44
  matched?: unknown;
31
45
  callHash?: unknown;
32
46
  label?: unknown;
47
+ /** Present when the label ledger recognized content in the result: how many chunks matched, and which sessions wrote them. */
48
+ ledger?: unknown;
49
+ /** Present when the result carried record label stamps: how many, and which sessions wrote them. */
50
+ records?: unknown;
33
51
  sessionLabel?: unknown;
34
52
  warnings?: string[];
35
53
  durationMs: number;
@@ -39,14 +57,138 @@ export interface AuditSink {
39
57
  write(entry: AuditEntry): void;
40
58
  }
41
59
 
60
+ /** `prev` of the first line of a log. */
61
+ export const AUDIT_GENESIS = `sha256:${"0".repeat(64)}`;
62
+
63
+ const LOCK_TIMEOUT_MS = 5000;
64
+ /** A lock older than this was left by a process that died while holding it. */
65
+ const LOCK_STALE_MS = 10_000;
66
+
67
+ function sleepSync(ms: number): void {
68
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
69
+ }
70
+
71
+ function withLock<T>(lockPath: string, fn: () => T): T {
72
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
73
+ for (;;) {
74
+ try {
75
+ closeSync(openSync(lockPath, "wx"));
76
+ break;
77
+ } catch (err) {
78
+ if ((err as NodeJS.ErrnoException).code !== "EEXIST") throw err;
79
+ try {
80
+ if (Date.now() - statSync(lockPath).mtimeMs > LOCK_STALE_MS) unlinkSync(lockPath);
81
+ } catch {
82
+ // Released meanwhile; try again.
83
+ }
84
+ if (Date.now() > deadline) throw new Error(`Timed out waiting for the audit log lock ${lockPath}`);
85
+ sleepSync(5);
86
+ }
87
+ }
88
+ try {
89
+ return fn();
90
+ } finally {
91
+ try {
92
+ unlinkSync(lockPath);
93
+ } catch {
94
+ // Already gone.
95
+ }
96
+ }
97
+ }
98
+
99
+ /** Last line of the file (without its newline), and whether the file ends with one. */
100
+ function tail(fd: number): { line?: string; endsWithNewline: boolean } {
101
+ const size = fstatSync(fd).size;
102
+ if (size === 0) return { endsWithNewline: true };
103
+ const chunks: Buffer[] = [];
104
+ let pos = size;
105
+ let text = "";
106
+ while (pos > 0) {
107
+ const n = Math.min(65536, pos);
108
+ pos -= n;
109
+ const buf = Buffer.alloc(n);
110
+ readSync(fd, buf, 0, n, pos);
111
+ chunks.unshift(buf);
112
+ text = Buffer.concat(chunks).toString("utf8");
113
+ if (text.slice(0, -1).includes("\n")) break;
114
+ }
115
+ const endsWithNewline = text.endsWith("\n");
116
+ const body = endsWithNewline ? text.slice(0, -1) : text;
117
+ return { line: body.slice(body.lastIndexOf("\n") + 1), endsWithNewline };
118
+ }
119
+
120
+ /** Hash a line links to: its `hash`, or for lines written before the chain, the hash of the raw line. */
121
+ function linkHash(raw: string): string {
122
+ try {
123
+ const v = JSON.parse(raw) as { hash?: unknown };
124
+ if (typeof v.hash === "string") return v.hash;
125
+ } catch {
126
+ // Not JSON: link to the raw text.
127
+ }
128
+ return `sha256:${sha256Hex(raw)}`;
129
+ }
130
+
42
131
  export class JsonlAuditLog implements AuditSink {
43
132
  constructor(readonly path: string) {
44
133
  mkdirSync(dirname(path), { recursive: true });
45
134
  }
46
135
 
47
136
  write(entry: AuditEntry): void {
48
- appendFileSync(this.path, `${JSON.stringify(entry)}\n`, "utf8");
137
+ withLock(`${this.path}.lock`, () => {
138
+ const fd = openSync(this.path, "a+");
139
+ try {
140
+ const t = tail(fd);
141
+ const prev = t.line === undefined ? AUDIT_GENESIS : linkHash(t.line);
142
+ const chained = { ...entry, prev };
143
+ const line = JSON.stringify({ ...chained, hash: digest(chained) });
144
+ writeSync(fd, `${t.endsWithNewline ? "" : "\n"}${line}\n`);
145
+ } finally {
146
+ closeSync(fd);
147
+ }
148
+ });
149
+ }
150
+ }
151
+
152
+ export interface AuditVerifyResult {
153
+ ok: boolean;
154
+ /** Lines checked. */
155
+ lines: number;
156
+ /** Lines at the start written before the chain (ADTL 0.4 and earlier). */
157
+ unchained: number;
158
+ /** Hash of the last line: note it to detect lines cut off the end later. */
159
+ last?: string;
160
+ problem?: string;
161
+ }
162
+
163
+ /** Check every line's hash and its link to the line before. */
164
+ export function verifyAuditLog(path: string): AuditVerifyResult {
165
+ const lines = readFileSync(path, "utf8").split("\n");
166
+ if (lines.at(-1) === "") lines.pop();
167
+ let prev = AUDIT_GENESIS;
168
+ let unchained = 0;
169
+ let chained = false;
170
+ for (const [i, raw] of lines.entries()) {
171
+ const n = i + 1;
172
+ const fail = (problem: string): AuditVerifyResult => ({ ok: false, lines: n, unchained, problem: `line ${n} ${problem}` });
173
+ let v: Record<string, unknown>;
174
+ try {
175
+ v = JSON.parse(raw) as Record<string, unknown>;
176
+ } catch {
177
+ return fail("is not valid JSON");
178
+ }
179
+ const { hash, ...rest } = v;
180
+ if (typeof hash !== "string") {
181
+ if (chained) return fail("has no hash: it was inserted or edited");
182
+ unchained++;
183
+ prev = linkHash(raw);
184
+ continue;
185
+ }
186
+ chained = true;
187
+ if (rest.prev !== prev) return fail(`doesn't follow line ${n - 1 || "(start)"}: a line was removed, reordered or inserted`);
188
+ if (digest(rest) !== hash) return fail("was changed after it was written");
189
+ prev = hash;
49
190
  }
191
+ return { ok: true, lines: lines.length, unchained, ...(lines.length ? { last: prev } : {}) };
50
192
  }
51
193
 
52
194
  export class MemoryAuditLog implements AuditSink {
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `adtl-gateway audit`: check the audit log by hand.
3
+ *
4
+ * adtl-gateway audit verify [<file>] [-c adtl.yaml]
5
+ *
6
+ * Without a file, the log is `gateway.audit` from the config.
7
+ */
8
+ import { readFile } from "node:fs/promises";
9
+ import { dirname, resolve } from "node:path";
10
+ import { parse as parseYaml } from "yaml";
11
+ import { verifyAuditLog } from "./audit.js";
12
+
13
+ export const AUDIT_USAGE = `Usage: adtl-gateway audit verify [<file>] [-c <adtl.yaml>]
14
+
15
+ The audit log is hash-chained. verify checks that no line was edited,
16
+ removed, reordered or inserted (exit 1 if one was), and prints the hash of
17
+ the last line. Lines cut off the end are not detected; note that hash
18
+ somewhere else if you need to check later. Without <file>, the log is
19
+ gateway.audit from the config.`;
20
+
21
+ export interface AuditCommandResult {
22
+ stdout: string;
23
+ exitCode: number;
24
+ }
25
+
26
+ export async function runAuditCommand(argv: string[]): Promise<AuditCommandResult> {
27
+ const [cmd, ...rest] = argv;
28
+ let config: string | undefined;
29
+ const files: string[] = [];
30
+ for (let i = 0; i < rest.length; i++) {
31
+ const a = rest[i]!;
32
+ if (a === "-c" || a === "--config") config = rest[++i];
33
+ else if (a.startsWith("-")) throw new Error(`Unknown argument: ${a}\n\n${AUDIT_USAGE}`);
34
+ else files.push(a);
35
+ }
36
+ if (cmd === undefined || cmd === "-h" || cmd === "--help") return { stdout: AUDIT_USAGE, exitCode: 0 };
37
+ if (cmd !== "verify") throw new Error(`Unknown audit command: ${cmd}\n\n${AUDIT_USAGE}`);
38
+ if (files.length > 1) throw new Error(`Unexpected argument: ${files[1]}\n\n${AUDIT_USAGE}`);
39
+
40
+ let path = files[0] && resolve(files[0]);
41
+ if (!path) {
42
+ if (!config) throw new Error(`Give the audit log file, or -c <adtl.yaml> with gateway.audit set\n\n${AUDIT_USAGE}`);
43
+ const abs = resolve(config);
44
+ const gw = ((parseYaml(await readFile(abs, "utf8")) ?? {}) as { gateway?: { audit?: unknown } }).gateway ?? {};
45
+ if (typeof gw.audit !== "string") throw new Error(`${config} has no gateway.audit`);
46
+ path = resolve(dirname(abs), gw.audit);
47
+ }
48
+
49
+ const v = verifyAuditLog(path);
50
+ if (!v.ok) return { stdout: `${path}: TAMPERED: ${v.problem}`, exitCode: 1 };
51
+ const before = v.unchained ? ` (${v.unchained} written before the chain)` : "";
52
+ return { stdout: `${path}: ${v.lines} lines${before}, chain intact${v.last ? `\nlast: ${v.last}` : ""}`, exitCode: 0 };
53
+ }