@koda-sl/baker-bridge 0.119.0 → 0.121.0-dev.ba3f112da

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 (140) hide show
  1. package/README.md +1 -19
  2. package/dist/hono/agent-session.d.ts +0 -3
  3. package/dist/hono/agent-session.d.ts.map +1 -1
  4. package/dist/hono/agent-session.js +0 -15
  5. package/dist/hono/agent-session.js.map +1 -1
  6. package/dist/hono/agent.d.ts +0 -2
  7. package/dist/hono/agent.d.ts.map +1 -1
  8. package/dist/hono/agent.js +2 -10
  9. package/dist/hono/agent.js.map +1 -1
  10. package/dist/hono/baker-ui-tool-schemas.test.js +0 -6
  11. package/dist/hono/baker-ui-tool-schemas.test.js.map +1 -1
  12. package/dist/hono/bridge-job.d.ts +1 -13
  13. package/dist/hono/bridge-job.d.ts.map +1 -1
  14. package/dist/hono/bridge-job.js +5 -69
  15. package/dist/hono/bridge-job.js.map +1 -1
  16. package/dist/hono/bridge-job.test.js +1 -113
  17. package/dist/hono/bridge-job.test.js.map +1 -1
  18. package/dist/hono/connection-input.d.ts +1 -8
  19. package/dist/hono/connection-input.d.ts.map +1 -1
  20. package/dist/hono/connection-input.js +1 -2
  21. package/dist/hono/connection-input.js.map +1 -1
  22. package/dist/hono/connection-input.test.js +8 -17
  23. package/dist/hono/connection-input.test.js.map +1 -1
  24. package/dist/hono/convex.d.ts +0 -8
  25. package/dist/hono/convex.d.ts.map +1 -1
  26. package/dist/hono/convex.js +0 -8
  27. package/dist/hono/convex.js.map +1 -1
  28. package/dist/hono/latitude-telemetry.d.ts.map +1 -1
  29. package/dist/hono/latitude-telemetry.js +2 -8
  30. package/dist/hono/latitude-telemetry.js.map +1 -1
  31. package/dist/hono/prompt-context.d.ts +1 -8
  32. package/dist/hono/prompt-context.d.ts.map +1 -1
  33. package/dist/hono/prompt-context.js +7 -45
  34. package/dist/hono/prompt-context.js.map +1 -1
  35. package/dist/hono/prompt-context.test.js +1 -35
  36. package/dist/hono/prompt-context.test.js.map +1 -1
  37. package/dist/hono/relay.d.ts +1 -10
  38. package/dist/hono/relay.d.ts.map +1 -1
  39. package/dist/hono/relay.js +0 -6
  40. package/dist/hono/relay.js.map +1 -1
  41. package/dist/hono/server.d.ts.map +1 -1
  42. package/dist/hono/server.js +0 -22
  43. package/dist/hono/server.js.map +1 -1
  44. package/dist/hono/tag-input.d.ts +3 -105
  45. package/dist/hono/tag-input.d.ts.map +1 -1
  46. package/dist/hono/tag-input.js +9 -20
  47. package/dist/hono/tag-input.js.map +1 -1
  48. package/dist/hono/tag-input.test.js +1 -19
  49. package/dist/hono/tag-input.test.js.map +1 -1
  50. package/dist/hono/types.d.ts +0 -8
  51. package/dist/hono/types.d.ts.map +1 -1
  52. package/package.json +2 -5
  53. package/dist/broker/baker-api.d.ts +0 -23
  54. package/dist/broker/baker-api.d.ts.map +0 -1
  55. package/dist/broker/baker-api.js +0 -55
  56. package/dist/broker/baker-api.js.map +0 -1
  57. package/dist/broker/broker-client.d.ts +0 -10
  58. package/dist/broker/broker-client.d.ts.map +0 -1
  59. package/dist/broker/broker-client.js +0 -60
  60. package/dist/broker/broker-client.js.map +0 -1
  61. package/dist/broker/ca.d.ts +0 -38
  62. package/dist/broker/ca.d.ts.map +0 -1
  63. package/dist/broker/ca.js +0 -80
  64. package/dist/broker/ca.js.map +0 -1
  65. package/dist/broker/ca.test.d.ts +0 -2
  66. package/dist/broker/ca.test.d.ts.map +0 -1
  67. package/dist/broker/ca.test.js +0 -58
  68. package/dist/broker/ca.test.js.map +0 -1
  69. package/dist/broker/credential-cache.d.ts +0 -24
  70. package/dist/broker/credential-cache.d.ts.map +0 -1
  71. package/dist/broker/credential-cache.js +0 -69
  72. package/dist/broker/credential-cache.js.map +0 -1
  73. package/dist/broker/credential-cache.test.d.ts +0 -2
  74. package/dist/broker/credential-cache.test.d.ts.map +0 -1
  75. package/dist/broker/credential-cache.test.js +0 -120
  76. package/dist/broker/credential-cache.test.js.map +0 -1
  77. package/dist/broker/credential-text.d.ts +0 -45
  78. package/dist/broker/credential-text.d.ts.map +0 -1
  79. package/dist/broker/credential-text.js +0 -103
  80. package/dist/broker/credential-text.js.map +0 -1
  81. package/dist/broker/credential-text.test.d.ts +0 -2
  82. package/dist/broker/credential-text.test.d.ts.map +0 -1
  83. package/dist/broker/credential-text.test.js +0 -54
  84. package/dist/broker/credential-text.test.js.map +0 -1
  85. package/dist/broker/env.d.ts +0 -19
  86. package/dist/broker/env.d.ts.map +0 -1
  87. package/dist/broker/env.js +0 -16
  88. package/dist/broker/env.js.map +0 -1
  89. package/dist/broker/main.d.ts +0 -3
  90. package/dist/broker/main.d.ts.map +0 -1
  91. package/dist/broker/main.js +0 -51
  92. package/dist/broker/main.js.map +0 -1
  93. package/dist/broker/proxy.d.ts +0 -24
  94. package/dist/broker/proxy.d.ts.map +0 -1
  95. package/dist/broker/proxy.integration.test.d.ts +0 -2
  96. package/dist/broker/proxy.integration.test.d.ts.map +0 -1
  97. package/dist/broker/proxy.integration.test.js +0 -201
  98. package/dist/broker/proxy.integration.test.js.map +0 -1
  99. package/dist/broker/proxy.js +0 -147
  100. package/dist/broker/proxy.js.map +0 -1
  101. package/dist/broker/rewrite.d.ts +0 -44
  102. package/dist/broker/rewrite.d.ts.map +0 -1
  103. package/dist/broker/rewrite.js +0 -291
  104. package/dist/broker/rewrite.js.map +0 -1
  105. package/dist/broker/rewrite.test.d.ts +0 -2
  106. package/dist/broker/rewrite.test.d.ts.map +0 -1
  107. package/dist/broker/rewrite.test.js +0 -171
  108. package/dist/broker/rewrite.test.js.map +0 -1
  109. package/dist/broker/socket-service.d.ts +0 -18
  110. package/dist/broker/socket-service.d.ts.map +0 -1
  111. package/dist/broker/socket-service.js +0 -103
  112. package/dist/broker/socket-service.js.map +0 -1
  113. package/dist/broker/socket-service.test.d.ts +0 -2
  114. package/dist/broker/socket-service.test.d.ts.map +0 -1
  115. package/dist/broker/socket-service.test.js +0 -73
  116. package/dist/broker/socket-service.test.js.map +0 -1
  117. package/dist/broker/token-bucket.d.ts +0 -9
  118. package/dist/broker/token-bucket.d.ts.map +0 -1
  119. package/dist/broker/token-bucket.js +0 -18
  120. package/dist/broker/token-bucket.js.map +0 -1
  121. package/dist/broker/usage-reporter.d.ts +0 -18
  122. package/dist/broker/usage-reporter.d.ts.map +0 -1
  123. package/dist/broker/usage-reporter.js +0 -31
  124. package/dist/broker/usage-reporter.js.map +0 -1
  125. package/dist/broker/usage-reporter.test.d.ts +0 -2
  126. package/dist/broker/usage-reporter.test.d.ts.map +0 -1
  127. package/dist/broker/usage-reporter.test.js +0 -20
  128. package/dist/broker/usage-reporter.test.js.map +0 -1
  129. package/dist/hono/credential-input.d.ts +0 -39
  130. package/dist/hono/credential-input.d.ts.map +0 -1
  131. package/dist/hono/credential-input.js +0 -78
  132. package/dist/hono/credential-input.js.map +0 -1
  133. package/dist/hono/credential-scrub.d.ts +0 -41
  134. package/dist/hono/credential-scrub.d.ts.map +0 -1
  135. package/dist/hono/credential-scrub.js +0 -152
  136. package/dist/hono/credential-scrub.js.map +0 -1
  137. package/dist/hono/credential-scrub.test.d.ts +0 -2
  138. package/dist/hono/credential-scrub.test.d.ts.map +0 -1
  139. package/dist/hono/credential-scrub.test.js +0 -105
  140. package/dist/hono/credential-scrub.test.js.map +0 -1
@@ -1,171 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { rewriteRequest } from "./rewrite.js";
3
- const credentials = [
4
- { name: "meta-token", value: "EAAG-secret/value+1", allowedHosts: ["graph.facebook.com"] },
5
- { name: "shop", value: 'shpat_"quoted"&x=1', allowedHosts: ["acme.myshopify.com"] },
6
- { name: "nowhere", value: "unscoped-secret-1", allowedHosts: [] },
7
- ];
8
- function request(overrides = {}) {
9
- return {
10
- url: "https://graph.facebook.com/v21.0/me",
11
- headers: { accept: "application/json" },
12
- body: null,
13
- ...overrides,
14
- };
15
- }
16
- const text = (value) => new TextEncoder().encode(value);
17
- describe("rewriteRequest", () => {
18
- it("passes a request that carries no placeholder untouched", () => {
19
- expect(rewriteRequest(request({ body: text('{"a":1}') }), credentials)).toEqual({ kind: "pass" });
20
- });
21
- it("swaps a placeholder in a header for the value when the host is allowed", () => {
22
- const decision = rewriteRequest(request({ headers: { authorization: "Bearer {{credential:meta-token}}", accept: "*/*" } }), credentials);
23
- expect(decision).toEqual({
24
- kind: "rewrite",
25
- url: "https://graph.facebook.com/v21.0/me",
26
- headers: { authorization: "Bearer EAAG-secret/value+1", accept: "*/*" },
27
- used: ["meta-token"],
28
- });
29
- });
30
- it("swaps a placeholder in a JSON body, escaped so the body stays valid JSON", () => {
31
- const decision = rewriteRequest(request({
32
- url: "https://acme.myshopify.com/admin/graphql.json",
33
- headers: { "content-type": "application/json; charset=utf-8" },
34
- body: text('{"token":"{{credential:shop}}"}'),
35
- }), credentials);
36
- expect(decision).toMatchObject({ kind: "rewrite", used: ["shop"] });
37
- const body = decision.kind === "rewrite" ? (decision.body ?? "") : "";
38
- expect(JSON.parse(body)).toEqual({ token: 'shpat_"quoted"&x=1' });
39
- });
40
- it("swaps a placeholder in a form body, form-encoded", () => {
41
- const decision = rewriteRequest(request({
42
- url: "https://acme.myshopify.com/oauth",
43
- headers: { "content-type": "application/x-www-form-urlencoded" },
44
- body: text("grant=x&secret=%7B%7Bcredential%3Ashop%7D%7D"),
45
- }), credentials);
46
- expect(decision).toMatchObject({ kind: "rewrite", used: ["shop"] });
47
- const body = decision.kind === "rewrite" ? (decision.body ?? "") : "";
48
- expect(new URLSearchParams(body).get("secret")).toBe('shpat_"quoted"&x=1');
49
- });
50
- it.each([
51
- ["a text body over 10 MB", "text/plain", text(`{{credential:shop}}${"x".repeat(10 * 1024 * 1024)}`)],
52
- ["a binary body", "application/octet-stream", text("\u0000\u0001{{credential:shop}}")],
53
- ])("refuses a placeholder in %s with 413", (_kind, contentType, body) => {
54
- const decision = rewriteRequest(request({ url: "https://acme.myshopify.com/upload", headers: { "content-type": contentType }, body }), credentials);
55
- expect(decision).toMatchObject({ kind: "reject", status: 413 });
56
- });
57
- it("refuses to put a credential on plain http, even to an allowed host", () => {
58
- const decision = rewriteRequest(request({ url: "http://graph.facebook.com/me", headers: { authorization: "Bearer {{credential:meta-token}}" } }), credentials);
59
- expect(decision).toMatchObject({ kind: "reject", status: 403 });
60
- expect(decision.kind === "reject" && decision.message).toContain("only sent over https");
61
- });
62
- it("swaps a placeholder hidden inside Basic auth, re-encoding the pair", () => {
63
- const basic = `Basic ${btoa("admin:{{credential:shop}}")}`;
64
- const decision = rewriteRequest(request({ url: "https://acme.myshopify.com/admin", headers: { authorization: basic } }), credentials);
65
- expect(decision).toMatchObject({
66
- kind: "rewrite",
67
- headers: { authorization: `Basic ${Buffer.from('admin:shpat_"quoted"&x=1').toString("base64")}` },
68
- used: ["shop"],
69
- });
70
- });
71
- it.each([
72
- ["literally", "https://acme.myshopify.com/admin?token={{credential:shop}}"],
73
- ["percent-encoded", "https://acme.myshopify.com/admin?token=%7B%7Bcredential%3Ashop%7D%7D"],
74
- ["percent-encoded in lower case", "https://acme.myshopify.com/admin?token=%7b%7bcredential%3ashop%7d%7d"],
75
- ])("swaps a placeholder written %s in the URL for the URL-encoded value", (_form, url) => {
76
- const decision = rewriteRequest(request({ url }), credentials);
77
- expect(decision).toMatchObject({
78
- kind: "rewrite",
79
- url: `https://acme.myshopify.com/admin?token=${encodeURIComponent('shpat_"quoted"&x=1')}`,
80
- used: ["shop"],
81
- });
82
- });
83
- it("leaves HTTP/2 pseudo-headers as they came, since the proxy refuses a changed :path", () => {
84
- const path = "/admin?token={{credential:shop}}";
85
- const decision = rewriteRequest(request({ url: `https://acme.myshopify.com${path}`, headers: { ":method": "GET", ":path": path } }), credentials);
86
- expect(decision).toMatchObject({
87
- kind: "rewrite",
88
- url: `https://acme.myshopify.com/admin?token=${encodeURIComponent('shpat_"quoted"&x=1')}`,
89
- headers: { ":method": "GET", ":path": path },
90
- });
91
- });
92
- it.each([
93
- ["Host", "host"],
94
- ["HTTP/2 :authority", ":authority"],
95
- ])("refuses a credential when the %s header names a different site than the one checked", (_kind, header) => {
96
- const decision = rewriteRequest(request({ headers: { [header]: "attacker.io", authorization: "Bearer {{credential:meta-token}}" } }), credentials);
97
- expect(decision).toMatchObject({
98
- kind: "reject",
99
- status: 403,
100
- message: expect.stringContaining("Host header names another website"),
101
- });
102
- });
103
- it("accepts a Host header that names the checked site with a port and in any case", () => {
104
- const decision = rewriteRequest(request({ headers: { host: "Graph.Facebook.com:443", authorization: "Bearer {{credential:meta-token}}" } }), credentials);
105
- expect(decision).toMatchObject({ kind: "rewrite", used: ["meta-token"] });
106
- });
107
- it("refuses to send a credential to a host it is not allowed for, and says where it may go", () => {
108
- const decision = rewriteRequest(request({ url: "https://attacker.io/collect", headers: { authorization: "Bearer {{credential:shop}}" } }), credentials);
109
- expect(decision).toEqual({
110
- kind: "reject",
111
- status: 403,
112
- message: 'Baker credential "shop" is not allowed for host "attacker.io". Allowed: acme.myshopify.com. Ask the user to add this website to the credential in Settings → Credentials.',
113
- stale: true,
114
- });
115
- });
116
- it("tells the agent to ask for websites when a credential has none yet", () => {
117
- const decision = rewriteRequest(request({ headers: { "x-key": "{{credential:nowhere}}" } }), credentials);
118
- expect(decision).toEqual({
119
- kind: "reject",
120
- status: 403,
121
- message: 'Baker credential "nowhere" has no websites it may be sent to yet. Ask the user to choose them in Settings → Credentials.',
122
- stale: true,
123
- });
124
- });
125
- it.each([
126
- ["not allowed for the host", "{{credential:shop}}"],
127
- ["naming no stored credential", "{{credential:typo}}"],
128
- ])("passes a body-only placeholder %s through untouched, as text", (_case, placeholder) => {
129
- const decision = rewriteRequest(request({
130
- url: "https://openrouter.ai/api/v1/chat/completions",
131
- headers: { "content-type": "application/json" },
132
- body: text(`{"messages":[{"content":"use ${placeholder}"}]}`),
133
- }), credentials);
134
- expect(decision).toEqual({ kind: "pass" });
135
- });
136
- it("answers 503 for a placeholder in a header when the credentials could not be fetched", () => {
137
- const decision = rewriteRequest(request({ headers: { authorization: "Bearer {{credential:meta-token}}" } }), null);
138
- expect(decision).toEqual({
139
- kind: "reject",
140
- status: 503,
141
- message: "Baker credentials are unavailable right now — try again in a minute.",
142
- });
143
- });
144
- it("passes a body-only placeholder when the credentials could not be fetched", () => {
145
- const decision = rewriteRequest(request({ headers: { "content-type": "text/plain" }, body: text("{{credential:meta-token}}") }), null);
146
- expect(decision).toEqual({ kind: "pass" });
147
- });
148
- it("answers 404 for a placeholder naming no stored credential", () => {
149
- const decision = rewriteRequest(request({ headers: { "x-key": "{{credential:typo}}" } }), credentials);
150
- expect(decision).toEqual({
151
- kind: "reject",
152
- status: 404,
153
- message: 'No Baker credential named "typo". Run `baker credentials list` to see the names you can use.',
154
- stale: true,
155
- });
156
- });
157
- it("refuses a host whose name another URL parser would read differently", () => {
158
- // mockttp re-parses the URL it is handed with url.parse(), which cuts a host at `{`, while the
159
- // check reads the whole name: the credential must never go to a host the check did not see.
160
- const decision = rewriteRequest(request({
161
- url: "https://attacker.io{.acme.myshopify.com/admin",
162
- headers: { authorization: "Bearer {{credential:shop}}" },
163
- }), credentials);
164
- expect(decision).toMatchObject({ kind: "reject", status: 403 });
165
- });
166
- it("refuses to put a credential into the address of the website itself", () => {
167
- const decision = rewriteRequest(request({ url: "https://{{credential:shop}}.myshopify.com/admin" }), credentials);
168
- expect(decision).toMatchObject({ kind: "reject", status: 403 });
169
- });
170
- });
171
- //# sourceMappingURL=rewrite.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rewrite.test.js","sourceRoot":"","sources":["../../src/broker/rewrite.test.ts"],"names":[],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- import type { CredentialCache } from "./credential-cache.ts";
2
- export declare const MAX_SCRUB_REQUEST_BYTES: number;
3
- export type SocketService = {
4
- listen(): Promise<void>;
5
- close(): Promise<void>;
6
- };
7
- export declare function createSocketService(options: {
8
- cache: CredentialCache;
9
- socketPath: string;
10
- ratePerSecond?: number;
11
- /** Bytes of text a caller may have scrubbed: slows using /scrub as an oracle for guessing a value. */
12
- scrubBytes?: {
13
- capacity: number;
14
- perSecond: number;
15
- };
16
- log?: (message: string) => void;
17
- }): SocketService;
18
- //# sourceMappingURL=socket-service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"socket-service.d.ts","sourceRoot":"","sources":["../../src/broker/socket-service.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,uBAAuB,QAAkB,CAAC;AAmBvD,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AA6BhF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,KAAK,EAAE,eAAe,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sGAAsG;IACtG,UAAU,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,aAAa,CAyChB"}
@@ -1,103 +0,0 @@
1
- /**
2
- * The broker's local service for the bridge, over a unix socket the agent user
3
- * can reach: scrub values out of text, and health. It
4
- * never returns a value — `/scrub` only ever turns values into placeholders.
5
- *
6
- * The agent writes the text it asks to have scrubbed, so a scrub is an answer
7
- * to "is any of these my password?". `/scrub` therefore leaves alone a value a
8
- * wordlist could reach (`resistsGuessing`); the proxy still scrubs it from
9
- * what a website sends back, where the agent does not choose the text.
10
- */
11
- import { chmod, mkdir, rm } from "node:fs/promises";
12
- import { createServer } from "node:http";
13
- import { dirname } from "node:path";
14
- import { z } from "zod";
15
- import { scrub } from "./credential-text.js";
16
- import { createTokenBucket } from "./token-bucket.js";
17
- export const MAX_SCRUB_REQUEST_BYTES = 2 * 1024 * 1024;
18
- const DEFAULT_SCRUB_BYTES = { capacity: 8 * 1024 * 1024, perSecond: 256 * 1024 };
19
- const scrubRequestSchema = z.object({ text: z.string() });
20
- /** Bits a value must carry — its length times its per-character entropy — before `/scrub` may confirm it. */
21
- const MIN_SCRUB_BITS = 64;
22
- function resistsGuessing(value) {
23
- const counts = new Map();
24
- for (const char of value)
25
- counts.set(char, (counts.get(char) ?? 0) + 1);
26
- let perChar = 0;
27
- for (const count of counts.values()) {
28
- const p = count / value.length;
29
- perChar -= p * Math.log2(p);
30
- }
31
- return perChar * value.length >= MIN_SCRUB_BITS;
32
- }
33
- class BodyTooLarge extends Error {
34
- }
35
- async function readBody(req, limit) {
36
- const chunks = [];
37
- let size = 0;
38
- for await (const chunk of req) {
39
- const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk));
40
- size += buffer.byteLength;
41
- if (size > limit)
42
- throw new BodyTooLarge();
43
- chunks.push(buffer);
44
- }
45
- return Buffer.concat(chunks).toString("utf8");
46
- }
47
- function parseJson(raw) {
48
- try {
49
- return JSON.parse(raw);
50
- }
51
- catch {
52
- return null;
53
- }
54
- }
55
- function send(res, status, body) {
56
- res.writeHead(status, { "content-type": "application/json" });
57
- res.end(JSON.stringify(body));
58
- }
59
- export function createSocketService(options) {
60
- const bucket = createTokenBucket({ ratePerSecond: options.ratePerSecond ?? 50, burst: options.ratePerSecond ?? 50 });
61
- const scrubBytes = options.scrubBytes ?? DEFAULT_SCRUB_BYTES;
62
- const bytes = createTokenBucket({ ratePerSecond: scrubBytes.perSecond, burst: scrubBytes.capacity });
63
- async function handle(req, res) {
64
- if (req.method === "GET" && req.url === "/health") {
65
- return send(res, 200, { ok: true, credentials: options.cache.size() });
66
- }
67
- if (req.method !== "POST" || req.url !== "/scrub")
68
- return send(res, 404, { error: "not found" });
69
- if (!bucket.take())
70
- return send(res, 429, { error: "too many scrub requests" });
71
- const raw = await readBody(req, MAX_SCRUB_REQUEST_BYTES);
72
- if (!bytes.take(Buffer.byteLength(raw)))
73
- return send(res, 429, { error: "too much text scrubbed, slow down" });
74
- const parsed = scrubRequestSchema.safeParse(parseJson(raw));
75
- if (!parsed.success)
76
- return send(res, 400, { error: "expected {text}" });
77
- const credentials = (await options.cache.scrubbable()).filter((credential) => resistsGuessing(credential.value));
78
- return send(res, 200, { text: scrub(parsed.data.text, credentials) });
79
- }
80
- const server = createServer((req, res) => {
81
- handle(req, res).catch((error) => {
82
- if (error instanceof BodyTooLarge)
83
- return send(res, 413, { error: "text too large to scrub" });
84
- options.log?.(`socket request failed: ${error instanceof Error ? error.name : "unknown"}`);
85
- send(res, 500, { error: "scrub failed" });
86
- });
87
- });
88
- return {
89
- async listen() {
90
- await mkdir(dirname(options.socketPath), { recursive: true });
91
- await rm(options.socketPath, { force: true });
92
- await new Promise((resolve, reject) => {
93
- server.once("error", reject);
94
- server.listen(options.socketPath, () => resolve());
95
- });
96
- await chmod(options.socketPath, 0o666);
97
- },
98
- async close() {
99
- await new Promise((resolve) => server.close(() => resolve()));
100
- },
101
- };
102
- }
103
- //# sourceMappingURL=socket-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"socket-service.js","sourceRoot":"","sources":["../../src/broker/socket-service.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=socket-service.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"socket-service.test.d.ts","sourceRoot":"","sources":["../../src/broker/socket-service.test.ts"],"names":[],"mappings":""}
@@ -1,73 +0,0 @@
1
- import { mkdtempSync } from "node:fs";
2
- import { request } from "node:http";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import { afterEach, describe, expect, it } from "vitest";
6
- import { scrubViaBroker } from "./broker-client.js";
7
- import { createCredentialCache } from "./credential-cache.js";
8
- import { createSocketService } from "./socket-service.js";
9
- const VALUE = "shpat_0a1b2c3d4e5f6a7b";
10
- const WEAK_PASSWORD = ["Hunter", "2024!"].join("");
11
- let service = null;
12
- afterEach(async () => {
13
- await service?.close();
14
- service = null;
15
- });
16
- async function start(limits = {}) {
17
- const socketPath = join(mkdtempSync(join(tmpdir(), "broker-")), "broker.sock");
18
- const cache = createCredentialCache({
19
- fetchCredentials: () => Promise.resolve([
20
- { name: "shop", value: VALUE, allowedHosts: ["acme.myshopify.com"] },
21
- { name: "login", value: WEAK_PASSWORD, allowedHosts: ["app.example.com"] },
22
- ]),
23
- });
24
- service = createSocketService({ cache, socketPath, ...limits });
25
- await service.listen();
26
- return { socketPath };
27
- }
28
- function get(socketPath, path) {
29
- return new Promise((resolve, reject) => {
30
- const req = request({ socketPath, path, method: "GET" }, (res) => {
31
- let body = "";
32
- res.setEncoding("utf8");
33
- res.on("data", (chunk) => {
34
- body += chunk;
35
- });
36
- res.on("end", () => resolve(body));
37
- });
38
- req.on("error", reject);
39
- req.end();
40
- });
41
- }
42
- describe("broker socket service", () => {
43
- it("scrubs a value back to its placeholder for the bridge", async () => {
44
- const { socketPath } = await start();
45
- const out = await scrubViaBroker(`tool said ${VALUE} and ${btoa(VALUE)}`, { socketPath });
46
- expect(out).toBe("tool said {{credential:shop}} and {{credential:shop}}");
47
- });
48
- it("never confirms a guess at a value a wordlist could reach", async () => {
49
- // The agent writes the text it asks to have scrubbed: scrubbing a guessable
50
- // password would tell it which of a million guesses was right.
51
- const { socketPath } = await start();
52
- const out = await scrubViaBroker(`guesses: password1 ${WEAK_PASSWORD} letmein`, { socketPath });
53
- expect(out).toBe(`guesses: password1 ${WEAK_PASSWORD} letmein`);
54
- });
55
- it("reports how many credentials it holds, never what they are", async () => {
56
- const { socketPath } = await start();
57
- await scrubViaBroker("warm the cache", { socketPath });
58
- const health = await get(socketPath, "/health");
59
- expect(JSON.parse(health)).toEqual({ ok: true, credentials: 2 });
60
- expect(health).not.toContain(VALUE);
61
- });
62
- it("answers 429 once a caller has sent more text than its byte budget allows", async () => {
63
- const { socketPath } = await start({ scrubBytes: { capacity: 100, perSecond: 1 } });
64
- const text = "x".repeat(60);
65
- await scrubViaBroker(text, { socketPath });
66
- await expect(scrubViaBroker(text, { socketPath })).rejects.toThrow("429");
67
- });
68
- it("returns the text unchanged when no broker is running", async () => {
69
- const socketPath = join(mkdtempSync(join(tmpdir(), "broker-")), "missing.sock");
70
- expect(await scrubViaBroker(`raw ${VALUE}`, { socketPath })).toBe(`raw ${VALUE}`);
71
- });
72
- });
73
- //# sourceMappingURL=socket-service.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"socket-service.test.js","sourceRoot":"","sources":["../../src/broker/socket-service.test.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- /** A token bucket: up to `burst` tokens at once, refilled at `ratePerSecond`; a take may cost more than one. */
2
- export declare function createTokenBucket(options: {
3
- ratePerSecond: number;
4
- burst: number;
5
- now?: () => number;
6
- }): {
7
- take(cost?: number): boolean;
8
- };
9
- //# sourceMappingURL=token-bucket.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-bucket.d.ts","sourceRoot":"","sources":["../../src/broker/token-bucket.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAE;IAKnG,IAAI,iBAAY,OAAO;EAS1B"}
@@ -1,18 +0,0 @@
1
- /** A token bucket: up to `burst` tokens at once, refilled at `ratePerSecond`; a take may cost more than one. */
2
- export function createTokenBucket(options) {
3
- const now = options.now ?? Date.now;
4
- let tokens = options.burst;
5
- let last = now();
6
- return {
7
- take(cost = 1) {
8
- const at = now();
9
- tokens = Math.min(options.burst, tokens + ((at - last) / 1000) * options.ratePerSecond);
10
- last = at;
11
- if (tokens < cost)
12
- return false;
13
- tokens -= cost;
14
- return true;
15
- },
16
- };
17
- }
18
- //# sourceMappingURL=token-bucket.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-bucket.js","sourceRoot":"","sources":["../../src/broker/token-bucket.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,MAAM,UAAU,iBAAiB,CAAC,OAAqE;IACrG,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,IAAI,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAC3B,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC;IACjB,OAAO;QACL,IAAI,CAAC,IAAI,GAAG,CAAC;YACX,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC;YACjB,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;YACxF,IAAI,GAAG,EAAE,CAAC;YACV,IAAI,MAAM,GAAG,IAAI;gBAAE,OAAO,KAAK,CAAC;YAChC,MAAM,IAAI,IAAI,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,18 +0,0 @@
1
- /**
2
- * Batches "credential X was sent to host Y" so Baker can show when each
3
- * credential was last used, without a call per request: at most one report
4
- * every 30 seconds, each pair once, 100 pairs per call (the contract's cap).
5
- */
6
- import type { CredentialUse } from "./baker-api.ts";
7
- export declare const USAGE_FLUSH_INTERVAL_MS = 30000;
8
- export type UsageReporter = {
9
- record(name: string, host: string): void;
10
- flush(): Promise<void>;
11
- /** Starts the periodic flush; returns a function that stops it. */
12
- start(intervalMs?: number): () => void;
13
- };
14
- export declare function createUsageReporter(options: {
15
- reportUsage: (uses: CredentialUse[]) => Promise<void>;
16
- log?: (message: string) => void;
17
- }): UsageReporter;
18
- //# sourceMappingURL=usage-reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage-reporter.d.ts","sourceRoot":"","sources":["../../src/broker/usage-reporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAG9C,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,mEAAmE;IACnE,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;CACxC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,WAAW,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,aAAa,CA2BhB"}
@@ -1,31 +0,0 @@
1
- export const USAGE_FLUSH_INTERVAL_MS = 30_000;
2
- const MAX_USES_PER_REPORT = 100;
3
- export function createUsageReporter(options) {
4
- const pending = new Map();
5
- async function flush() {
6
- while (pending.size > 0) {
7
- const batch = [...pending.entries()].slice(0, MAX_USES_PER_REPORT);
8
- for (const [key] of batch)
9
- pending.delete(key);
10
- try {
11
- await options.reportUsage(batch.map(([, use]) => use));
12
- }
13
- catch (error) {
14
- options.log?.(`usage report failed, dropping ${batch.length} uses: ${String(error)}`);
15
- return;
16
- }
17
- }
18
- }
19
- return {
20
- record(name, host) {
21
- pending.set(`${name}\u0000${host}`, { name, host });
22
- },
23
- flush,
24
- start(intervalMs = USAGE_FLUSH_INTERVAL_MS) {
25
- const timer = setInterval(() => void flush(), intervalMs);
26
- timer.unref();
27
- return () => clearInterval(timer);
28
- },
29
- };
30
- }
31
- //# sourceMappingURL=usage-reporter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage-reporter.js","sourceRoot":"","sources":["../../src/broker/usage-reporter.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAC9C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAShC,MAAM,UAAU,mBAAmB,CAAC,OAGnC;IACC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,KAAK,UAAU,KAAK;QAClB,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;YACnE,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK;gBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/C,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACzD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,EAAE,CAAC,iCAAiC,KAAK,CAAC,MAAM,UAAU,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtF,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,CAAC,IAAI,EAAE,IAAI;YACf,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,SAAS,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,KAAK;QACL,KAAK,CAAC,UAAU,GAAG,uBAAuB;YACxC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;YAC1D,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=usage-reporter.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage-reporter.test.d.ts","sourceRoot":"","sources":["../../src/broker/usage-reporter.test.ts"],"names":[],"mappings":""}
@@ -1,20 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { createUsageReporter } from "./usage-reporter.js";
3
- describe("createUsageReporter", () => {
4
- it("reports each credential and host once per flush, and nothing when idle", async () => {
5
- const batches = [];
6
- const reporter = createUsageReporter({ reportUsage: async (uses) => void batches.push(uses) });
7
- reporter.record("shop", "acme.myshopify.com");
8
- reporter.record("shop", "acme.myshopify.com");
9
- reporter.record("meta-token", "graph.facebook.com");
10
- await reporter.flush();
11
- await reporter.flush();
12
- expect(batches).toEqual([
13
- [
14
- { name: "shop", host: "acme.myshopify.com" },
15
- { name: "meta-token", host: "graph.facebook.com" },
16
- ],
17
- ]);
18
- });
19
- });
20
- //# sourceMappingURL=usage-reporter.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage-reporter.test.js","sourceRoot":"","sources":["../../src/broker/usage-reporter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE/F,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QAC9C,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QAC9C,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;QACpD,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEvB,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;YACtB;gBACE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE;gBAC5C,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,EAAE;aACnD;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,39 +0,0 @@
1
- import { z } from "zod";
2
- export declare const CREDENTIAL_INPUT_TOOL_NAME = "mcp__baker_ui__request_credential";
3
- declare const credentialRequestShape: z.ZodObject<{
4
- label: z.ZodString;
5
- reason: z.ZodString;
6
- allowedHosts: z.ZodArray<z.ZodString>;
7
- name: z.ZodOptional<z.ZodString>;
8
- }, z.core.$strip>;
9
- export declare const credentialInputToolShape: {
10
- label: z.ZodString;
11
- reason: z.ZodString;
12
- allowedHosts: z.ZodArray<z.ZodString>;
13
- name: z.ZodOptional<z.ZodString>;
14
- resolution: z.ZodOptional<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>;
15
- };
16
- export type CredentialInputRequest = z.infer<typeof credentialRequestShape>;
17
- export declare const credentialInputResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
18
- status: z.ZodLiteral<"stored">;
19
- name: z.ZodString;
20
- placeholder: z.ZodString;
21
- allowedHosts: z.ZodArray<z.ZodString>;
22
- }, z.core.$strip>, z.ZodObject<{
23
- status: z.ZodLiteral<"declined">;
24
- reason: z.ZodOptional<z.ZodString>;
25
- }, z.core.$strip>], "status">;
26
- export type CredentialInputResult = z.infer<typeof credentialInputResultSchema>;
27
- /** Parse-at-boundary for the result posted to `POST /credential-input-decision`. */
28
- export declare function parseCredentialInputResult(value: unknown): CredentialInputResult | null;
29
- /** `canUseTool` sees the raw model input, before MCP validation. */
30
- export declare function normalizeCredentialInputToolInput(input: unknown): CredentialInputRequest | null;
31
- export declare function createCredentialInputTool(): import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition<{
32
- label: z.ZodString;
33
- reason: z.ZodString;
34
- allowedHosts: z.ZodArray<z.ZodString>;
35
- name: z.ZodOptional<z.ZodString>;
36
- resolution: z.ZodOptional<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>;
37
- }>;
38
- export {};
39
- //# sourceMappingURL=credential-input.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"credential-input.d.ts","sourceRoot":"","sources":["../../src/hono/credential-input.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,0BAA0B,sCAAsC,CAAC;AAE9E,QAAA,MAAM,sBAAsB;;;;;iBAwB1B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;CAOpC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E,eAAO,MAAM,2BAA2B;;;;;;;;6BAQtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,oFAAoF;AACpF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,GAAG,IAAI,CAGvF;AAED,oEAAoE;AACpE,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,GAAG,IAAI,CAG/F;AAUD,wBAAgB,yBAAyB;;;;;;GAYxC"}