@creatornader/agent-bridge 0.2.0 → 0.3.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.
- package/CHANGELOG.md +86 -4
- package/README.md +567 -55
- package/ROADMAP.md +114 -0
- package/SECURITY.md +90 -0
- package/SKILL.md +68 -2
- package/bin/agent-bridge +2 -2
- package/clients/claude-desktop.json +3 -1
- package/dist/archive.d.ts +163 -0
- package/dist/archive.js +50 -0
- package/dist/archive.js.map +1 -0
- package/dist/bridge-domain-CBX3IVqC.d.ts +153 -0
- package/dist/{bridge-service-CfqMcMAn.d.ts → bridge-service-hX1ZQp4W.d.ts} +15 -5
- package/dist/bridge-store-DPVSCwfs.d.ts +102 -0
- package/dist/bridge.d.ts +76 -17
- package/dist/bridge.js +52 -24
- package/dist/chunk-2DFNOLMO.js +618 -0
- package/dist/chunk-2DFNOLMO.js.map +1 -0
- package/dist/{chunk-KVR4JBRF.js → chunk-2EVLG3YA.js} +2 -2
- package/dist/{chunk-KVR4JBRF.js.map → chunk-2EVLG3YA.js.map} +1 -1
- package/dist/chunk-45BZGB77.js +709 -0
- package/dist/chunk-45BZGB77.js.map +1 -0
- package/dist/chunk-4VB44KJU.js +230 -0
- package/dist/chunk-4VB44KJU.js.map +1 -0
- package/dist/chunk-5GMB3A77.js +1013 -0
- package/dist/chunk-5GMB3A77.js.map +1 -0
- package/dist/chunk-A6W4QALF.js +1258 -0
- package/dist/chunk-A6W4QALF.js.map +1 -0
- package/dist/chunk-BZLMF5O5.js +328 -0
- package/dist/chunk-BZLMF5O5.js.map +1 -0
- package/dist/{chunk-AXL2I7FH.js → chunk-CEXBMOI5.js} +240 -79
- package/dist/chunk-CEXBMOI5.js.map +1 -0
- package/dist/chunk-GADH244D.js +527 -0
- package/dist/chunk-GADH244D.js.map +1 -0
- package/dist/chunk-MBPZXTJA.js +2428 -0
- package/dist/chunk-MBPZXTJA.js.map +1 -0
- package/dist/chunk-NCO7RLBM.js +146 -0
- package/dist/chunk-NCO7RLBM.js.map +1 -0
- package/dist/chunk-Q6PPMXJC.js +1050 -0
- package/dist/chunk-Q6PPMXJC.js.map +1 -0
- package/dist/{chunk-4KAOBC5X.js → chunk-SPSMZOCJ.js} +190 -165
- package/dist/chunk-SPSMZOCJ.js.map +1 -0
- package/dist/chunk-UAHMP6GC.js +54 -0
- package/dist/chunk-UAHMP6GC.js.map +1 -0
- package/dist/{chunk-YD6YJATN.js → chunk-VOQIDTCJ.js} +4 -2
- package/dist/chunk-VOQIDTCJ.js.map +1 -0
- package/dist/chunk-WAI2IYIQ.js +554 -0
- package/dist/chunk-WAI2IYIQ.js.map +1 -0
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +3555 -214
- package/dist/cli.js.map +1 -1
- package/dist/client-config.d.ts +1 -1
- package/dist/client-config.js +1 -1
- package/dist/client-runtime.d.ts +10 -6
- package/dist/client-runtime.js +9 -6
- package/dist/contracts/generate.d.ts +2 -0
- package/dist/contracts/generate.js +247 -0
- package/dist/contracts/generate.js.map +1 -0
- package/dist/dr.d.ts +324 -0
- package/dist/dr.js +124 -0
- package/dist/dr.js.map +1 -0
- package/dist/gateway-CggQ8vTC.d.ts +78 -0
- package/dist/gateway-main.js +190 -8
- package/dist/gateway-main.js.map +1 -1
- package/dist/gateway.d.ts +4 -3
- package/dist/gateway.js +4 -3
- package/dist/index.js +11 -8
- package/dist/index.js.map +1 -1
- package/dist/postgres-bridge-store-Bfd3hRId.d.ts +49 -0
- package/dist/server.d.ts +3 -2
- package/dist/server.js +13 -8
- package/dist/sqlite.d.ts +94 -12
- package/dist/sqlite.js +7 -4
- package/docs/architecture-v2.md +394 -0
- package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +85 -0
- package/docs/decisions/0002-canonical-operation-contract-registry.md +46 -0
- package/docs/decisions/0003-host-adapters-and-consumer-instance-keys.md +88 -0
- package/docs/ecosystem.md +86 -0
- package/docs/postmortems/2026-07-08-wrapper-source-drift.md +82 -0
- package/docs/troubleshooting.md +89 -0
- package/llms.txt +107 -6
- package/openapi/agent-bridge-v2.openapi.json +9610 -0
- package/package.json +24 -4
- package/schemas/agent-bridge-v2.capabilities.json +1829 -0
- package/schemas/agent-bridge-v2.mcp.json +2074 -0
- package/schemas/agent-bridge-v2.schema.json +4560 -0
- package/sql/migrations/008_message_projects.sql +36 -0
- package/sql/migrations/009_mailbox_query_indexes.sql +28 -0
- package/sql/migrations/010_publisher_delivery_policy.sql +210 -0
- package/sql/migrations/011_credential_security.sql +875 -0
- package/sql/migrations/012_request_authority.sql +177 -0
- package/sql/migrations/013_row_isolation.sql +495 -0
- package/sql/migrations/014_owner_control_plane.sql +1641 -0
- package/sql/migrations/015_portable_archives.sql +1813 -0
- package/sql/migrations/016_native_dr_fence.sql +1005 -0
- package/bin/CLAUDE.md +0 -11
- package/dist/bridge-domain-BcnBeHOn.d.ts +0 -97
- package/dist/bridge-store-BuGjxTn4.d.ts +0 -61
- package/dist/chunk-4KAOBC5X.js.map +0 -1
- package/dist/chunk-6MAZ6YLZ.js +0 -146
- package/dist/chunk-6MAZ6YLZ.js.map +0 -1
- package/dist/chunk-AXL2I7FH.js.map +0 -1
- package/dist/chunk-BV6W4AJK.js +0 -211
- package/dist/chunk-BV6W4AJK.js.map +0 -1
- package/dist/chunk-CKSKUBDQ.js +0 -153
- package/dist/chunk-CKSKUBDQ.js.map +0 -1
- package/dist/chunk-JOUBDRYX.js +0 -272
- package/dist/chunk-JOUBDRYX.js.map +0 -1
- package/dist/chunk-JTC5YURG.js +0 -49
- package/dist/chunk-JTC5YURG.js.map +0 -1
- package/dist/chunk-O26W5QHS.js +0 -409
- package/dist/chunk-O26W5QHS.js.map +0 -1
- package/dist/chunk-WEULPMUY.js +0 -988
- package/dist/chunk-WEULPMUY.js.map +0 -1
- package/dist/chunk-YD6YJATN.js.map +0 -1
- package/dist/gateway-BULozv3K.d.ts +0 -54
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
BridgeService
|
|
4
|
+
} from "./chunk-4VB44KJU.js";
|
|
5
|
+
import {
|
|
6
|
+
ContractResponseError,
|
|
7
|
+
ContractValidationError,
|
|
8
|
+
LEGACY_PROTOCOL_VERSION,
|
|
9
|
+
PROTOCOL_HEADER,
|
|
10
|
+
PROTOCOL_VERSION,
|
|
11
|
+
SUPPORTED_PROTOCOL_HEADER,
|
|
12
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
13
|
+
capabilityDocument,
|
|
14
|
+
negotiateProtocolVersion,
|
|
15
|
+
operationContract,
|
|
16
|
+
parseResponse,
|
|
17
|
+
validateRequest,
|
|
18
|
+
validateRequestForProtocol
|
|
19
|
+
} from "./chunk-GADH244D.js";
|
|
20
|
+
import {
|
|
21
|
+
BridgePrincipalMismatchError,
|
|
22
|
+
BridgeValidationError
|
|
23
|
+
} from "./chunk-BZLMF5O5.js";
|
|
24
|
+
|
|
25
|
+
// src/gateway.ts
|
|
26
|
+
import { randomUUID } from "crypto";
|
|
27
|
+
import { createServer } from "http";
|
|
28
|
+
|
|
29
|
+
// src/gateway-auth.ts
|
|
30
|
+
import { createHash, timingSafeEqual } from "crypto";
|
|
31
|
+
function hashCredential(token) {
|
|
32
|
+
return createHash("sha256").update(token, "utf8").digest("hex");
|
|
33
|
+
}
|
|
34
|
+
var PostgresCredentialResolver = class {
|
|
35
|
+
constructor(db) {
|
|
36
|
+
this.db = db;
|
|
37
|
+
}
|
|
38
|
+
async resolve(token, signal) {
|
|
39
|
+
if (signal?.aborted) throw signal.reason;
|
|
40
|
+
const result = await this.db.query(
|
|
41
|
+
`SELECT credential_id,workspace_id,principal,scopes
|
|
42
|
+
FROM agent_bridge.resolve_credential_hash($1::text)`,
|
|
43
|
+
[hashCredential(token)]
|
|
44
|
+
);
|
|
45
|
+
const row = result.rows[0];
|
|
46
|
+
if (signal?.aborted) throw signal.reason;
|
|
47
|
+
return row ? {
|
|
48
|
+
id: row.credential_id,
|
|
49
|
+
principal: { workspace: row.workspace_id, agent: row.principal },
|
|
50
|
+
scopes: row.scopes
|
|
51
|
+
} : null;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function bearerToken(value) {
|
|
55
|
+
if (!value?.startsWith("Bearer ")) return null;
|
|
56
|
+
const token = value.slice(7);
|
|
57
|
+
if (!token || token.length > 4096 || /\s/.test(token)) return null;
|
|
58
|
+
return token;
|
|
59
|
+
}
|
|
60
|
+
function safeTokenHashEqual(token, expectedHash) {
|
|
61
|
+
const actual = Buffer.from(hashCredential(token));
|
|
62
|
+
const expected = Buffer.from(expectedHash);
|
|
63
|
+
return actual.length === expected.length && timingSafeEqual(actual, expected);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/gateway.ts
|
|
67
|
+
var jsonHeaders = { "content-type": "application/json; charset=utf-8", "cache-control": "no-store" };
|
|
68
|
+
var BufferedResponse = class {
|
|
69
|
+
constructor(target) {
|
|
70
|
+
this.target = target;
|
|
71
|
+
this.headers = /* @__PURE__ */ new Map();
|
|
72
|
+
}
|
|
73
|
+
get writableEnded() {
|
|
74
|
+
return this.body !== void 0;
|
|
75
|
+
}
|
|
76
|
+
getHeader(name) {
|
|
77
|
+
return this.headers.get(name.toLowerCase()) ?? this.target.getHeader(name);
|
|
78
|
+
}
|
|
79
|
+
setHeader(name, value) {
|
|
80
|
+
this.headers.set(name.toLowerCase(), value);
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
writeHead(status, headers) {
|
|
84
|
+
this.status = status;
|
|
85
|
+
this.headHeaders = headers;
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
end(chunk) {
|
|
89
|
+
this.body = chunk ?? null;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
flush() {
|
|
93
|
+
if (this.target.writableEnded) return;
|
|
94
|
+
for (const [name, value] of this.headers) this.target.setHeader(name, value);
|
|
95
|
+
if (this.status !== void 0) this.target.writeHead(this.status, this.headHeaders);
|
|
96
|
+
if (this.body !== void 0) this.target.end(this.body);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
function send(res, status, value, requestId) {
|
|
100
|
+
if (res.writableEnded) return;
|
|
101
|
+
res.writeHead(status, {
|
|
102
|
+
...jsonHeaders,
|
|
103
|
+
"x-request-id": requestId
|
|
104
|
+
});
|
|
105
|
+
res.end(JSON.stringify(value));
|
|
106
|
+
}
|
|
107
|
+
function sendOperation(res, status, operation, value, requestId) {
|
|
108
|
+
const canonical = parseResponse(operation, value);
|
|
109
|
+
const protocolVersion = String(res.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);
|
|
110
|
+
if (protocolVersion !== LEGACY_PROTOCOL_VERSION) {
|
|
111
|
+
send(res, status, canonical, requestId);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (operation === "claim_delivery") {
|
|
115
|
+
send(res, status, canonical.delivery === null ? null : canonical, requestId);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (["cancel_delivery", "requeue_delivery", "extend_delivery", "acknowledge_delivery", "negative_acknowledge_delivery"].includes(operation)) {
|
|
119
|
+
send(res, status, canonical.delivery, requestId);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
send(res, status, canonical, requestId);
|
|
123
|
+
}
|
|
124
|
+
function failure(res, status, code, requestId, details = {}) {
|
|
125
|
+
send(res, status, { error: { code, requestId, ...details } }, requestId);
|
|
126
|
+
}
|
|
127
|
+
async function body(req, limit, signal) {
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
const chunks = [];
|
|
130
|
+
let size = 0;
|
|
131
|
+
const cleanup = () => {
|
|
132
|
+
req.off("data", onData);
|
|
133
|
+
req.off("end", onEnd);
|
|
134
|
+
req.off("error", onError);
|
|
135
|
+
signal.removeEventListener("abort", onAbort);
|
|
136
|
+
};
|
|
137
|
+
const finish = (callback) => {
|
|
138
|
+
cleanup();
|
|
139
|
+
callback();
|
|
140
|
+
};
|
|
141
|
+
const onData = (chunk) => {
|
|
142
|
+
const buffer = Buffer.from(chunk);
|
|
143
|
+
size += buffer.length;
|
|
144
|
+
if (size > limit) {
|
|
145
|
+
finish(() => reject(Object.assign(new Error("body too large"), {
|
|
146
|
+
status: 413,
|
|
147
|
+
code: "body_too_large"
|
|
148
|
+
})));
|
|
149
|
+
req.resume();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
chunks.push(buffer);
|
|
153
|
+
};
|
|
154
|
+
const onEnd = () => finish(() => {
|
|
155
|
+
if (!size) {
|
|
156
|
+
resolve({});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
161
|
+
if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") throw new Error();
|
|
162
|
+
resolve(parsed);
|
|
163
|
+
} catch {
|
|
164
|
+
reject(Object.assign(new Error("invalid JSON"), { status: 400, code: "malformed_json" }));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
const onError = (error) => finish(() => reject(error));
|
|
168
|
+
const onAbort = () => {
|
|
169
|
+
finish(() => reject(signal.reason));
|
|
170
|
+
req.resume();
|
|
171
|
+
};
|
|
172
|
+
req.on("data", onData);
|
|
173
|
+
req.on("end", onEnd);
|
|
174
|
+
req.on("error", onError);
|
|
175
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
176
|
+
if (signal.aborted) onAbort();
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function jsonBody(req, limit, signal) {
|
|
180
|
+
if (hasRequestBody(req) && req.headers["content-type"]?.split(";", 1)[0] !== "application/json") {
|
|
181
|
+
throw Object.assign(new Error("unsupported media type"), {
|
|
182
|
+
status: 415,
|
|
183
|
+
code: "unsupported_media_type"
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return body(req, limit, signal);
|
|
187
|
+
}
|
|
188
|
+
function numberParam(value, name) {
|
|
189
|
+
if (value === null) return void 0;
|
|
190
|
+
const result = Number(value);
|
|
191
|
+
if (!Number.isSafeInteger(result)) throw new BridgeValidationError(`${name} is invalid`);
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
function booleanParam(value, name) {
|
|
195
|
+
if (value === null) return void 0;
|
|
196
|
+
if (value === "true") return true;
|
|
197
|
+
if (value === "false") return false;
|
|
198
|
+
throw new BridgeValidationError(`${name} must be true or false`);
|
|
199
|
+
}
|
|
200
|
+
function hasRequestBody(req) {
|
|
201
|
+
const length = req.headers["content-length"];
|
|
202
|
+
return req.headers["transfer-encoding"] !== void 0 || length !== void 0 && length !== "0";
|
|
203
|
+
}
|
|
204
|
+
function pathBoundInput(operation, deliveryId, rawInput, protocolVersion) {
|
|
205
|
+
if (Object.prototype.hasOwnProperty.call(rawInput, "deliveryId")) {
|
|
206
|
+
throw new ContractValidationError(operation, [{ path: "/deliveryId", message: "deliveryId is supplied by the request path" }]);
|
|
207
|
+
}
|
|
208
|
+
const value = { ...rawInput, deliveryId };
|
|
209
|
+
return protocolVersion ? validateRequestForProtocol(operation, value, protocolVersion) : validateRequest(operation, value);
|
|
210
|
+
}
|
|
211
|
+
function active(signal) {
|
|
212
|
+
if (signal.aborted) throw signal.reason;
|
|
213
|
+
}
|
|
214
|
+
function closedQuery(url, operation, allowed) {
|
|
215
|
+
const unknown = [...url.searchParams.keys()].find((key) => !allowed.includes(key));
|
|
216
|
+
if (unknown) throw new ContractValidationError(operation, [{ path: `/${unknown}`, message: "Unexpected query parameter" }]);
|
|
217
|
+
}
|
|
218
|
+
function selectedProtocol(res) {
|
|
219
|
+
return String(res.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);
|
|
220
|
+
}
|
|
221
|
+
function requireCurrentProtocol(res) {
|
|
222
|
+
if (selectedProtocol(res) === LEGACY_PROTOCOL_VERSION) {
|
|
223
|
+
const error = new Error("Operation is not available in protocol 2.0");
|
|
224
|
+
error.status = 404;
|
|
225
|
+
error.code = "not_found";
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function createGateway(options) {
|
|
230
|
+
const metrics = { requests: 0, errors: 0, timeouts: 0, authFailures: 0 };
|
|
231
|
+
const limit = options.bodyLimitBytes ?? 128 * 1024;
|
|
232
|
+
const deadline = options.requestDeadlineMs ?? 1e4;
|
|
233
|
+
const origins = new Set(options.allowedOrigins ?? []);
|
|
234
|
+
return createServer((req, res) => {
|
|
235
|
+
const requestId = randomUUID();
|
|
236
|
+
const abort = new AbortController();
|
|
237
|
+
let mutationStarted = false;
|
|
238
|
+
metrics.requests += 1;
|
|
239
|
+
const requestedProtocol = req.headers[PROTOCOL_HEADER];
|
|
240
|
+
const rawRequestedProtocol = Array.isArray(requestedProtocol) ? requestedProtocol[0] : requestedProtocol;
|
|
241
|
+
const initialProtocol = rawRequestedProtocol === void 0 || rawRequestedProtocol.trim() === "" ? LEGACY_PROTOCOL_VERSION : SUPPORTED_PROTOCOL_VERSIONS.includes(rawRequestedProtocol.trim()) ? rawRequestedProtocol.trim() : PROTOCOL_VERSION;
|
|
242
|
+
res.setHeader(PROTOCOL_HEADER, initialProtocol);
|
|
243
|
+
res.setHeader(SUPPORTED_PROTOCOL_HEADER, SUPPORTED_PROTOCOL_VERSIONS.join(","));
|
|
244
|
+
const timer = setTimeout(() => {
|
|
245
|
+
abort.abort(new Error("request deadline exceeded"));
|
|
246
|
+
metrics.timeouts += 1;
|
|
247
|
+
metrics.errors += 1;
|
|
248
|
+
res.once("finish", () => {
|
|
249
|
+
if (!req.complete) req.destroy();
|
|
250
|
+
});
|
|
251
|
+
failure(
|
|
252
|
+
res,
|
|
253
|
+
504,
|
|
254
|
+
mutationStarted ? "mutation_outcome_unknown" : "request_timeout",
|
|
255
|
+
requestId
|
|
256
|
+
);
|
|
257
|
+
}, deadline);
|
|
258
|
+
let parsedBody;
|
|
259
|
+
const requestBody = () => parsedBody ?? (parsedBody = jsonBody(req, limit, abort.signal));
|
|
260
|
+
const dispatch = async (authority, response = res) => {
|
|
261
|
+
const url = new URL(req.url ?? "/", "http://gateway.invalid");
|
|
262
|
+
if (req.method === "GET" && url.pathname === "/readyz") {
|
|
263
|
+
let ready = false;
|
|
264
|
+
try {
|
|
265
|
+
ready = await (options.ready?.() ?? options.store.initialize().then(() => true));
|
|
266
|
+
} catch {
|
|
267
|
+
ready = false;
|
|
268
|
+
}
|
|
269
|
+
send(response, ready ? 200 : 503, { status: ready ? "ready" : "not_ready" }, requestId);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const origin = req.headers.origin;
|
|
273
|
+
if (origin && !origins.has(origin)) {
|
|
274
|
+
failure(response, 403, "origin_forbidden", requestId);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const token = bearerToken(req.headers.authorization);
|
|
278
|
+
if (options.requestAuthority && !authority) {
|
|
279
|
+
if (!token) {
|
|
280
|
+
metrics.authFailures += 1;
|
|
281
|
+
failure(response, 401, "unauthorized", requestId);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const preflight = await options.credentials.resolve(token, abort.signal);
|
|
285
|
+
active(abort.signal);
|
|
286
|
+
if (!preflight) {
|
|
287
|
+
metrics.authFailures += 1;
|
|
288
|
+
failure(response, 401, "unauthorized", requestId);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (hasRequestBody(req)) await requestBody();
|
|
292
|
+
active(abort.signal);
|
|
293
|
+
const buffered = new BufferedResponse(res);
|
|
294
|
+
await options.requestAuthority.run(
|
|
295
|
+
preflight.id,
|
|
296
|
+
hashCredential(token),
|
|
297
|
+
requestId,
|
|
298
|
+
abort.signal,
|
|
299
|
+
(context) => dispatch(context, buffered)
|
|
300
|
+
);
|
|
301
|
+
active(abort.signal);
|
|
302
|
+
buffered.flush();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const credential = authority?.credential ?? (token ? await options.credentials.resolve(token, abort.signal) : null);
|
|
306
|
+
active(abort.signal);
|
|
307
|
+
if (!credential) {
|
|
308
|
+
metrics.authFailures += 1;
|
|
309
|
+
failure(response, 401, "unauthorized", requestId);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (!Array.isArray(credential.scopes)) {
|
|
313
|
+
failure(response, 503, "security_unavailable", requestId);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const service = new BridgeService(authority?.store ?? options.store);
|
|
317
|
+
const security = authority?.security ?? options.security;
|
|
318
|
+
if (url.pathname.startsWith("/v2/") || url.pathname === "/metrics") {
|
|
319
|
+
response.setHeader(PROTOCOL_HEADER, negotiateProtocolVersion(req.headers[PROTOCOL_HEADER]));
|
|
320
|
+
}
|
|
321
|
+
const authorize = async (operationId) => {
|
|
322
|
+
const requiredScopes = operationContract(operationId).scopes;
|
|
323
|
+
if (requiredScopes.some((scope) => !credential.scopes.includes(scope))) {
|
|
324
|
+
try {
|
|
325
|
+
await security.recordScopeDenial(credential.id, operationId, requestId, abort.signal);
|
|
326
|
+
} catch {
|
|
327
|
+
throw Object.assign(new Error("Scope denial could not be audited"), {
|
|
328
|
+
status: 503,
|
|
329
|
+
code: "security_unavailable"
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
throw Object.assign(new Error("Credential lacks a required scope"), {
|
|
333
|
+
status: 403,
|
|
334
|
+
code: "insufficient_scope",
|
|
335
|
+
requiredScopes
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
let decision;
|
|
339
|
+
try {
|
|
340
|
+
decision = await security.consume(credential.id, operationId, requestId, abort.signal);
|
|
341
|
+
} catch {
|
|
342
|
+
throw Object.assign(new Error("Rate limit state is unavailable"), {
|
|
343
|
+
status: 503,
|
|
344
|
+
code: "security_unavailable"
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
if (!decision.allowed) {
|
|
348
|
+
const retryAfter = Math.max(1, Math.ceil(decision.retryAfterSeconds));
|
|
349
|
+
response.setHeader("retry-after", String(retryAfter));
|
|
350
|
+
throw Object.assign(new Error("Credential rate limit exceeded"), {
|
|
351
|
+
status: 429,
|
|
352
|
+
code: "rate_limited",
|
|
353
|
+
retryAfterSeconds: retryAfter
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
if (req.method === "GET" && url.pathname === "/metrics") {
|
|
358
|
+
await authorize("gateway_metrics");
|
|
359
|
+
validateRequest("gateway_metrics", {});
|
|
360
|
+
const result = Object.entries(metrics).map(([key, value]) => `agent_bridge_gateway_${key}_total ${value}`).join("\n") + "\n";
|
|
361
|
+
parseResponse("gateway_metrics", result);
|
|
362
|
+
response.writeHead(200, {
|
|
363
|
+
...jsonHeaders,
|
|
364
|
+
"content-type": "text/plain; version=0.0.4",
|
|
365
|
+
"x-request-id": requestId
|
|
366
|
+
});
|
|
367
|
+
response.end(result);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const instanceHeader = req.headers["x-agent-bridge-instance"];
|
|
371
|
+
const principal = {
|
|
372
|
+
...credential.principal,
|
|
373
|
+
instance: Array.isArray(instanceHeader) ? instanceHeader[0] : instanceHeader
|
|
374
|
+
};
|
|
375
|
+
if (req.method === "GET" && url.pathname === "/v2/capabilities") {
|
|
376
|
+
requireCurrentProtocol(response);
|
|
377
|
+
await authorize("capabilities");
|
|
378
|
+
closedQuery(url, "capabilities", []);
|
|
379
|
+
validateRequest("capabilities", {});
|
|
380
|
+
let rowIsolation = false;
|
|
381
|
+
if (options.requestAuthority && options.rowIsolationReady) {
|
|
382
|
+
try {
|
|
383
|
+
rowIsolation = await options.rowIsolationReady();
|
|
384
|
+
} catch {
|
|
385
|
+
rowIsolation = false;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
sendOperation(response, 200, "capabilities", capabilityDocument({ surface: "http", provider: "gateway", selectedProtocolVersion: String(response.getHeader(PROTOCOL_HEADER)), requestAuthority: Boolean(options.requestAuthority), rowIsolation }), requestId);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (req.method === "GET" && url.pathname === "/v2/status") {
|
|
392
|
+
await authorize("status");
|
|
393
|
+
closedQuery(url, "status", []);
|
|
394
|
+
validateRequest("status", {});
|
|
395
|
+
const activeStore = authority?.store ?? options.store;
|
|
396
|
+
if (!activeStore.diagnostics) {
|
|
397
|
+
sendOperation(response, 200, "status", { schemaVersion: "postgres-v2", deliverySupported: false, pending: null, claimed: null, retrying: null, dead: null, principal: credential.principal }, requestId);
|
|
398
|
+
} else {
|
|
399
|
+
sendOperation(response, 200, "status", { ...await activeStore.diagnostics(principal), principal: credential.principal }, requestId);
|
|
400
|
+
}
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (req.method === "POST" && url.pathname === "/v2/messages") {
|
|
404
|
+
await authorize("publish_message");
|
|
405
|
+
const input = validateRequestForProtocol("publish_message", await requestBody(), String(response.getHeader(PROTOCOL_HEADER)));
|
|
406
|
+
if (input.source !== void 0 && input.source !== principal.agent) {
|
|
407
|
+
throw new BridgePrincipalMismatchError("source must match the authenticated principal");
|
|
408
|
+
}
|
|
409
|
+
const { source: _source, ...draft } = input;
|
|
410
|
+
active(abort.signal);
|
|
411
|
+
await authority?.beginDomainWork();
|
|
412
|
+
mutationStarted = true;
|
|
413
|
+
sendOperation(response, 201, "publish_message", await service.publish(principal, draft), requestId);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (req.method === "GET" && url.pathname === "/v2/history") {
|
|
417
|
+
await authorize("history");
|
|
418
|
+
closedQuery(url, "history", ["cursor", "mailbox", "receiptState", "limit", "type", "includeExpired", "source", "project", "since", "unacknowledgedBy", "unacked_by", "threadId", "latest"]);
|
|
419
|
+
const types = url.searchParams.getAll("type");
|
|
420
|
+
const input = validateRequestForProtocol("history", {
|
|
421
|
+
cursor: url.searchParams.get("cursor") ?? void 0,
|
|
422
|
+
mailbox: url.searchParams.get("mailbox") ?? void 0,
|
|
423
|
+
receiptState: url.searchParams.get("receiptState") ?? void 0,
|
|
424
|
+
limit: numberParam(url.searchParams.get("limit"), "limit"),
|
|
425
|
+
types: types.length ? types : void 0,
|
|
426
|
+
includeExpired: booleanParam(url.searchParams.get("includeExpired"), "includeExpired"),
|
|
427
|
+
source: url.searchParams.get("source") ?? void 0,
|
|
428
|
+
project: url.searchParams.get("project") ?? void 0,
|
|
429
|
+
since: url.searchParams.get("since") ?? void 0,
|
|
430
|
+
unacknowledgedBy: url.searchParams.get("unacknowledgedBy") ?? url.searchParams.get("unacked_by") ?? void 0,
|
|
431
|
+
threadId: url.searchParams.get("threadId") ?? void 0,
|
|
432
|
+
latest: booleanParam(url.searchParams.get("latest"), "latest")
|
|
433
|
+
}, String(response.getHeader(PROTOCOL_HEADER)));
|
|
434
|
+
sendOperation(response, 200, "history", await service.history(principal, input), requestId);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (req.method === "POST" && url.pathname === "/v2/receipts") {
|
|
438
|
+
await authorize("record_receipt");
|
|
439
|
+
const input = validateRequest("record_receipt", await requestBody());
|
|
440
|
+
active(abort.signal);
|
|
441
|
+
await authority?.beginDomainWork();
|
|
442
|
+
mutationStarted = true;
|
|
443
|
+
sendOperation(response, 200, "record_receipt", { recorded: await service.acknowledge(principal, input.messageIds) }, requestId);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (req.method === "POST" && url.pathname === "/v2/deliveries/claim") {
|
|
447
|
+
await authorize("claim_delivery");
|
|
448
|
+
const input = validateRequest("claim_delivery", await requestBody());
|
|
449
|
+
active(abort.signal);
|
|
450
|
+
await authority?.beginDomainWork();
|
|
451
|
+
mutationStarted = true;
|
|
452
|
+
sendOperation(response, 200, "claim_delivery", await service.claim(principal, input) ?? { delivery: null }, requestId);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
if (req.method === "GET" && url.pathname === "/v2/deliveries") {
|
|
456
|
+
requireCurrentProtocol(response);
|
|
457
|
+
await authorize("list_deliveries");
|
|
458
|
+
closedQuery(url, "list_deliveries", ["cursor", "limit", "role", "messageId", "recipient", "state"]);
|
|
459
|
+
const input = validateRequest("list_deliveries", { cursor: url.searchParams.get("cursor") ?? void 0, limit: numberParam(url.searchParams.get("limit"), "limit"), role: url.searchParams.get("role") ?? void 0, messageId: url.searchParams.get("messageId") ?? void 0, recipient: url.searchParams.get("recipient") ?? void 0, states: url.searchParams.getAll("state") });
|
|
460
|
+
sendOperation(response, 200, "list_deliveries", await service.deliveries(principal, input), requestId);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const eventsMatch = url.pathname.match(/^\/v2\/deliveries\/([^/]+)\/events$/);
|
|
464
|
+
if (req.method === "GET" && eventsMatch) {
|
|
465
|
+
requireCurrentProtocol(response);
|
|
466
|
+
await authorize("list_delivery_events");
|
|
467
|
+
closedQuery(url, "list_delivery_events", ["cursor", "limit"]);
|
|
468
|
+
const input = validateRequest("list_delivery_events", { deliveryId: eventsMatch[1], cursor: url.searchParams.get("cursor") ?? void 0, limit: numberParam(url.searchParams.get("limit"), "limit") });
|
|
469
|
+
sendOperation(response, 200, "list_delivery_events", await service.deliveryEvents(principal, eventsMatch[1], input), requestId);
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const controlMatch = url.pathname.match(/^\/v2\/deliveries\/([^/]+)\/(cancel|requeue)$/);
|
|
473
|
+
if (req.method === "POST" && controlMatch) {
|
|
474
|
+
requireCurrentProtocol(response);
|
|
475
|
+
const operation = controlMatch[2] === "cancel" ? "cancel_delivery" : "requeue_delivery";
|
|
476
|
+
await authorize(operation);
|
|
477
|
+
pathBoundInput(operation, controlMatch[1], await requestBody());
|
|
478
|
+
await authority?.beginDomainWork();
|
|
479
|
+
mutationStarted = true;
|
|
480
|
+
const result = controlMatch[2] === "cancel" ? await service.cancel(principal, controlMatch[1]) : await service.requeue(principal, controlMatch[1]);
|
|
481
|
+
if (!result) failure(response, 404, "not_found", requestId);
|
|
482
|
+
else sendOperation(response, 200, operation, { delivery: result }, requestId);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if (req.method === "POST" && url.pathname === "/v2/presence/heartbeat") {
|
|
486
|
+
await authorize("heartbeat");
|
|
487
|
+
const input = validateRequest("heartbeat", await requestBody());
|
|
488
|
+
active(abort.signal);
|
|
489
|
+
await authority?.beginDomainWork();
|
|
490
|
+
mutationStarted = true;
|
|
491
|
+
sendOperation(response, 200, "heartbeat", await service.heartbeat(principal, input), requestId);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
if (req.method === "GET" && url.pathname === "/v2/presence") {
|
|
495
|
+
await authorize("presence");
|
|
496
|
+
closedQuery(url, "presence", []);
|
|
497
|
+
validateRequest("presence", {});
|
|
498
|
+
sendOperation(response, 200, "presence", { agents: await service.presence(principal) }, requestId);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
const match = url.pathname.match(/^\/v2\/deliveries\/([^/]+)\/(extend|ack|nack)$/);
|
|
502
|
+
if (req.method === "POST" && match) {
|
|
503
|
+
const operationId = match[2] === "extend" ? "extend_delivery" : match[2] === "ack" ? "acknowledge_delivery" : "negative_acknowledge_delivery";
|
|
504
|
+
await authorize(operationId);
|
|
505
|
+
const rawInput = await requestBody();
|
|
506
|
+
const protocolVersion = String(response.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);
|
|
507
|
+
const input = pathBoundInput(operationId, match[1], rawInput, protocolVersion);
|
|
508
|
+
active(abort.signal);
|
|
509
|
+
await authority?.beginDomainWork();
|
|
510
|
+
mutationStarted = true;
|
|
511
|
+
const [, id, action] = match;
|
|
512
|
+
const result = action === "extend" ? await service.extend(principal, id, input.leaseToken, input.leaseMs) : action === "ack" ? await service.ack(principal, id, input.leaseToken) : await service.nack(
|
|
513
|
+
principal,
|
|
514
|
+
id,
|
|
515
|
+
input.leaseToken,
|
|
516
|
+
input.error ?? "negative acknowledgment",
|
|
517
|
+
input.disposition ?? input.dead ?? "retry",
|
|
518
|
+
input.retryPolicy
|
|
519
|
+
);
|
|
520
|
+
if (!result) failure(response, 409, "lease_conflict", requestId);
|
|
521
|
+
else sendOperation(response, 200, operationId, { delivery: result }, requestId);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
failure(response, 404, "not_found", requestId);
|
|
525
|
+
};
|
|
526
|
+
void dispatch().catch((error) => {
|
|
527
|
+
if (res.writableEnded) return;
|
|
528
|
+
metrics.errors += 1;
|
|
529
|
+
if (error instanceof ContractValidationError || error instanceof ContractResponseError) {
|
|
530
|
+
failure(res, error.status, error.code, requestId, { operation: error.operation, issues: error.issues });
|
|
531
|
+
} else if (error?.status === 426) {
|
|
532
|
+
failure(res, 426, error.code, requestId, { supportedProtocolVersions: [...SUPPORTED_PROTOCOL_VERSIONS] });
|
|
533
|
+
} else if (error?.code === "insufficient_scope") {
|
|
534
|
+
failure(res, 403, error.code, requestId, { details: { requiredScopes: [...error.requiredScopes] } });
|
|
535
|
+
} else if (error?.code === "rate_limited") {
|
|
536
|
+
res.setHeader("retry-after", String(error.retryAfterSeconds));
|
|
537
|
+
failure(res, 429, error.code, requestId, { details: { retryAfterSeconds: error.retryAfterSeconds } });
|
|
538
|
+
} else if (error instanceof BridgeValidationError || error instanceof BridgePrincipalMismatchError) {
|
|
539
|
+
failure(res, "status" in error ? error.status : 400, error.code, requestId, { message: error.message });
|
|
540
|
+
} else {
|
|
541
|
+
failure(res, error?.status ?? 500, error?.code ?? "internal_error", requestId);
|
|
542
|
+
}
|
|
543
|
+
}).finally(() => clearTimeout(timer));
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export {
|
|
548
|
+
hashCredential,
|
|
549
|
+
PostgresCredentialResolver,
|
|
550
|
+
bearerToken,
|
|
551
|
+
safeTokenHashEqual,
|
|
552
|
+
createGateway
|
|
553
|
+
};
|
|
554
|
+
//# sourceMappingURL=chunk-WAI2IYIQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/gateway.ts","../src/gateway-auth.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { BridgePrincipalMismatchError, BridgeValidationError, type MessageDraft } from \"./bridge-domain.js\";\nimport { BridgeService } from \"./bridge-service.js\";\nimport type { BridgeStore } from \"./bridge-store.js\";\nimport { bearerToken, hashCredential, type CredentialResolver } from \"./gateway-auth.js\";\nimport type { GatewaySecurity } from \"./gateway-security.js\";\nimport type { RequestAuthority, RequestAuthorityContext } from \"./postgres-request-authority.js\";\nimport {\n capabilityDocument,\n ContractResponseError,\n ContractValidationError,\n LEGACY_PROTOCOL_VERSION,\n negotiateProtocolVersion,\n operationContract,\n parseResponse,\n PROTOCOL_HEADER,\n PROTOCOL_VERSION,\n SUPPORTED_PROTOCOL_HEADER,\n SUPPORTED_PROTOCOL_VERSIONS,\n type OperationId,\n validateRequest,\n validateRequestForProtocol,\n} from \"./contracts/registry.js\";\n\nexport interface GatewayOptions {\n store: BridgeStore;\n credentials: CredentialResolver;\n security: GatewaySecurity;\n allowedOrigins?: string[];\n bodyLimitBytes?: number;\n requestDeadlineMs?: number;\n ready?: () => Promise<boolean>;\n /** Reports whether the configured database has verified row isolation. */\n rowIsolationReady?: () => Promise<boolean>;\n /** Production PostgreSQL request authority. Other providers omit this. */\n requestAuthority?: RequestAuthority;\n}\n\ntype Metrics = { requests: number; errors: number; timeouts: number; authFailures: number };\nconst jsonHeaders = { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\" };\n\ninterface ResponseWriter {\n readonly writableEnded: boolean;\n getHeader(name: string): string | number | readonly string[] | undefined;\n setHeader(name: string, value: string | number | readonly string[]): unknown;\n writeHead(status: number, headers?: any): unknown;\n end(chunk?: any): unknown;\n}\n\nclass BufferedResponse implements ResponseWriter {\n private readonly headers = new Map<string, string | number | readonly string[]>();\n private status: number | undefined;\n private headHeaders: any;\n private body: any;\n\n constructor(private readonly target: ServerResponse) {}\n get writableEnded(): boolean { return this.body !== undefined; }\n getHeader(name: string) { return this.headers.get(name.toLowerCase()) ?? this.target.getHeader(name); }\n setHeader(name: string, value: string | number | readonly string[]) { this.headers.set(name.toLowerCase(), value); return this; }\n writeHead(status: number, headers?: any) {\n this.status = status;\n this.headHeaders = headers;\n return this;\n }\n end(chunk?: any) { this.body = chunk ?? null; return this; }\n flush(): void {\n if (this.target.writableEnded) return;\n for (const [name, value] of this.headers) this.target.setHeader(name, value);\n if (this.status !== undefined) this.target.writeHead(this.status, this.headHeaders);\n if (this.body !== undefined) this.target.end(this.body);\n }\n}\n\nfunction send(res: ResponseWriter, status: number, value: unknown, requestId: string): void {\n if (res.writableEnded) return;\n res.writeHead(status, {\n ...jsonHeaders,\n \"x-request-id\": requestId,\n });\n res.end(JSON.stringify(value));\n}\n\nfunction sendOperation(res: ResponseWriter, status: number, operation: string, value: unknown, requestId: string): void {\n const canonical = parseResponse(operation, value) as Record<string, unknown>;\n const protocolVersion = String(res.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);\n if (protocolVersion !== LEGACY_PROTOCOL_VERSION) {\n send(res, status, canonical, requestId);\n return;\n }\n if (operation === \"claim_delivery\") {\n send(res, status, canonical.delivery === null ? null : canonical, requestId);\n return;\n }\n if ([\"cancel_delivery\", \"requeue_delivery\", \"extend_delivery\", \"acknowledge_delivery\", \"negative_acknowledge_delivery\"].includes(operation)) {\n send(res, status, canonical.delivery, requestId);\n return;\n }\n send(res, status, canonical, requestId);\n}\n\nfunction failure(\n res: ResponseWriter,\n status: number,\n code: string,\n requestId: string,\n details: Record<string, unknown> = {},\n): void {\n send(res, status, { error: { code, requestId, ...details } }, requestId);\n}\n\nasync function body(\n req: IncomingMessage,\n limit: number,\n signal: AbortSignal,\n): Promise<Record<string, any>> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n const cleanup = () => {\n req.off(\"data\", onData);\n req.off(\"end\", onEnd);\n req.off(\"error\", onError);\n signal.removeEventListener(\"abort\", onAbort);\n };\n const finish = (callback: () => void) => {\n cleanup();\n callback();\n };\n const onData = (chunk: Buffer | string) => {\n const buffer = Buffer.from(chunk);\n size += buffer.length;\n if (size > limit) {\n finish(() => reject(Object.assign(new Error(\"body too large\"), {\n status: 413,\n code: \"body_too_large\",\n })));\n req.resume();\n return;\n }\n chunks.push(buffer);\n };\n const onEnd = () => finish(() => {\n if (!size) {\n resolve({});\n return;\n }\n try {\n const parsed = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n if (!parsed || Array.isArray(parsed) || typeof parsed !== \"object\") throw new Error();\n resolve(parsed);\n } catch {\n reject(Object.assign(new Error(\"invalid JSON\"), { status: 400, code: \"malformed_json\" }));\n }\n });\n const onError = (error: Error) => finish(() => reject(error));\n const onAbort = () => {\n finish(() => reject(signal.reason));\n req.resume();\n };\n req.on(\"data\", onData);\n req.on(\"end\", onEnd);\n req.on(\"error\", onError);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n if (signal.aborted) onAbort();\n });\n}\n\nasync function jsonBody(\n req: IncomingMessage,\n limit: number,\n signal: AbortSignal,\n): Promise<Record<string, any>> {\n if (hasRequestBody(req) && req.headers[\"content-type\"]?.split(\";\", 1)[0] !== \"application/json\") {\n throw Object.assign(new Error(\"unsupported media type\"), {\n status: 415,\n code: \"unsupported_media_type\",\n });\n }\n return body(req, limit, signal);\n}\n\nfunction numberParam(value: string | null, name: string): number | undefined {\n if (value === null) return undefined;\n const result = Number(value);\n if (!Number.isSafeInteger(result)) throw new BridgeValidationError(`${name} is invalid`);\n return result;\n}\n\nfunction booleanParam(value: string | null, name: string): boolean | undefined {\n if (value === null) return undefined;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n throw new BridgeValidationError(`${name} must be true or false`);\n}\n\nfunction hasRequestBody(req: IncomingMessage): boolean {\n const length = req.headers[\"content-length\"];\n return req.headers[\"transfer-encoding\"] !== undefined || (length !== undefined && length !== \"0\");\n}\n\nfunction pathBoundInput(\n operation: string,\n deliveryId: string,\n rawInput: Record<string, unknown>,\n protocolVersion?: string,\n): Record<string, unknown> {\n if (Object.prototype.hasOwnProperty.call(rawInput, \"deliveryId\")) {\n throw new ContractValidationError(operation, [{ path: \"/deliveryId\", message: \"deliveryId is supplied by the request path\" }]);\n }\n const value = { ...rawInput, deliveryId };\n return protocolVersion\n ? validateRequestForProtocol(operation, value, protocolVersion)\n : validateRequest(operation, value);\n}\n\nfunction active(signal: AbortSignal): void {\n if (signal.aborted) throw signal.reason;\n}\n\nfunction closedQuery(url: URL, operation: string, allowed: readonly string[]): void {\n const unknown = [...url.searchParams.keys()].find((key) => !allowed.includes(key));\n if (unknown) throw new ContractValidationError(operation, [{ path: `/${unknown}`, message: \"Unexpected query parameter\" }]);\n}\n\nfunction selectedProtocol(res: ResponseWriter): string {\n return String(res.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);\n}\n\nfunction requireCurrentProtocol(res: ResponseWriter): void {\n if (selectedProtocol(res) === LEGACY_PROTOCOL_VERSION) {\n const error = new Error(\"Operation is not available in protocol 2.0\") as Error & { status: number; code: string };\n error.status = 404;\n error.code = \"not_found\";\n throw error;\n }\n}\n\nexport function createGateway(options: GatewayOptions) {\n const metrics: Metrics = { requests: 0, errors: 0, timeouts: 0, authFailures: 0 };\n const limit = options.bodyLimitBytes ?? 128 * 1024;\n const deadline = options.requestDeadlineMs ?? 10_000;\n const origins = new Set(options.allowedOrigins ?? []);\n\n return createServer((req, res) => {\n const requestId = randomUUID();\n const abort = new AbortController();\n let mutationStarted = false;\n metrics.requests += 1;\n const requestedProtocol = req.headers[PROTOCOL_HEADER];\n const rawRequestedProtocol = Array.isArray(requestedProtocol) ? requestedProtocol[0] : requestedProtocol;\n const initialProtocol = rawRequestedProtocol === undefined || rawRequestedProtocol.trim() === \"\"\n ? LEGACY_PROTOCOL_VERSION\n : (SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(rawRequestedProtocol.trim())\n ? rawRequestedProtocol.trim()\n : PROTOCOL_VERSION;\n res.setHeader(PROTOCOL_HEADER, initialProtocol);\n res.setHeader(SUPPORTED_PROTOCOL_HEADER, SUPPORTED_PROTOCOL_VERSIONS.join(\",\"));\n const timer = setTimeout(() => {\n abort.abort(new Error(\"request deadline exceeded\"));\n metrics.timeouts += 1; metrics.errors += 1;\n res.once(\"finish\", () => {\n if (!req.complete) req.destroy();\n });\n failure(\n res,\n 504,\n mutationStarted ? \"mutation_outcome_unknown\" : \"request_timeout\",\n requestId,\n );\n }, deadline);\n let parsedBody: Promise<Record<string, any>> | undefined;\n const requestBody = () => parsedBody ??= jsonBody(req, limit, abort.signal);\n\n const dispatch = async (authority?: RequestAuthorityContext, response: ResponseWriter = res): Promise<void> => {\n const url = new URL(req.url ?? \"/\", \"http://gateway.invalid\");\n if (req.method === \"GET\" && url.pathname === \"/readyz\") {\n let ready = false;\n try {\n ready = await (options.ready?.() ?? options.store.initialize().then(() => true));\n } catch {\n ready = false;\n }\n send(response, ready ? 200 : 503, { status: ready ? \"ready\" : \"not_ready\" }, requestId);\n return;\n }\n const origin = req.headers.origin;\n if (origin && !origins.has(origin)) {\n failure(response, 403, \"origin_forbidden\", requestId); return;\n }\n const token = bearerToken(req.headers.authorization);\n if (options.requestAuthority && !authority) {\n if (!token) {\n metrics.authFailures += 1;\n failure(response, 401, \"unauthorized\", requestId); return;\n }\n const preflight = await options.credentials.resolve(token, abort.signal);\n active(abort.signal);\n if (!preflight) {\n metrics.authFailures += 1;\n failure(response, 401, \"unauthorized\", requestId); return;\n }\n if (hasRequestBody(req)) await requestBody();\n active(abort.signal);\n const buffered = new BufferedResponse(res);\n await options.requestAuthority!.run(\n preflight.id,\n hashCredential(token),\n requestId,\n abort.signal,\n (context) => dispatch(context, buffered),\n );\n active(abort.signal);\n buffered.flush();\n return;\n }\n const credential = authority?.credential ?? (token ? await options.credentials.resolve(token, abort.signal) : null);\n active(abort.signal);\n if (!credential) {\n metrics.authFailures += 1;\n failure(response, 401, \"unauthorized\", requestId); return;\n }\n if (!Array.isArray(credential.scopes)) {\n failure(response, 503, \"security_unavailable\", requestId); return;\n }\n const service = new BridgeService(authority?.store ?? options.store);\n const security = authority?.security ?? options.security;\n if (url.pathname.startsWith(\"/v2/\") || url.pathname === \"/metrics\") {\n response.setHeader(PROTOCOL_HEADER, negotiateProtocolVersion(req.headers[PROTOCOL_HEADER]));\n }\n const authorize = async (operationId: OperationId): Promise<void> => {\n const requiredScopes = operationContract(operationId).scopes;\n if (requiredScopes.some((scope) => !credential.scopes.includes(scope))) {\n try {\n await security.recordScopeDenial(credential.id, operationId, requestId, abort.signal);\n } catch {\n throw Object.assign(new Error(\"Scope denial could not be audited\"), {\n status: 503,\n code: \"security_unavailable\",\n });\n }\n throw Object.assign(new Error(\"Credential lacks a required scope\"), {\n status: 403, code: \"insufficient_scope\", requiredScopes,\n });\n }\n let decision;\n try {\n decision = await security.consume(credential.id, operationId, requestId, abort.signal);\n } catch {\n throw Object.assign(new Error(\"Rate limit state is unavailable\"), {\n status: 503,\n code: \"security_unavailable\",\n });\n }\n if (!decision.allowed) {\n const retryAfter = Math.max(1, Math.ceil(decision.retryAfterSeconds));\n response.setHeader(\"retry-after\", String(retryAfter));\n throw Object.assign(new Error(\"Credential rate limit exceeded\"), {\n status: 429, code: \"rate_limited\", retryAfterSeconds: retryAfter,\n });\n }\n };\n if (req.method === \"GET\" && url.pathname === \"/metrics\") {\n await authorize(\"gateway_metrics\");\n validateRequest(\"gateway_metrics\", {});\n const result = Object.entries(metrics).map(([key, value]) => `agent_bridge_gateway_${key}_total ${value}`).join(\"\\n\") + \"\\n\";\n parseResponse(\"gateway_metrics\", result);\n response.writeHead(200, {\n ...jsonHeaders,\n \"content-type\": \"text/plain; version=0.0.4\",\n \"x-request-id\": requestId,\n });\n response.end(result);\n return;\n }\n const instanceHeader = req.headers[\"x-agent-bridge-instance\"];\n const principal = {\n ...credential.principal,\n instance: Array.isArray(instanceHeader) ? instanceHeader[0] : instanceHeader,\n };\n\n if (req.method === \"GET\" && url.pathname === \"/v2/capabilities\") {\n requireCurrentProtocol(response);\n await authorize(\"capabilities\");\n closedQuery(url, \"capabilities\", []);\n validateRequest(\"capabilities\", {});\n let rowIsolation = false;\n if (options.requestAuthority && options.rowIsolationReady) {\n try {\n rowIsolation = await options.rowIsolationReady();\n } catch {\n rowIsolation = false;\n }\n }\n sendOperation(response, 200, \"capabilities\", capabilityDocument({ surface: \"http\", provider: \"gateway\", selectedProtocolVersion: String(response.getHeader(PROTOCOL_HEADER)), requestAuthority: Boolean(options.requestAuthority), rowIsolation }), requestId); return;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/v2/status\") {\n await authorize(\"status\");\n closedQuery(url, \"status\", []);\n validateRequest(\"status\", {});\n const activeStore = authority?.store ?? options.store;\n if (!activeStore.diagnostics) {\n sendOperation(response, 200, \"status\", { schemaVersion: \"postgres-v2\", deliverySupported: false, pending: null, claimed: null, retrying: null, dead: null, principal: credential.principal }, requestId);\n } else {\n sendOperation(response, 200, \"status\", { ...await activeStore.diagnostics(principal), principal: credential.principal }, requestId);\n }\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v2/messages\") {\n await authorize(\"publish_message\");\n const input = validateRequestForProtocol(\"publish_message\", await requestBody(), String(response.getHeader(PROTOCOL_HEADER)));\n if (input.source !== undefined && input.source !== principal.agent) {\n throw new BridgePrincipalMismatchError(\"source must match the authenticated principal\");\n }\n const { source: _source, ...draft } = input;\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 201, \"publish_message\", await service.publish(principal, draft as unknown as MessageDraft), requestId); return;\n }\n if (req.method === \"GET\" && url.pathname === \"/v2/history\") {\n await authorize(\"history\");\n closedQuery(url, \"history\", [\"cursor\", \"mailbox\", \"receiptState\", \"limit\", \"type\", \"includeExpired\", \"source\", \"project\", \"since\", \"unacknowledgedBy\", \"unacked_by\", \"threadId\", \"latest\"]);\n const types = url.searchParams.getAll(\"type\");\n const input = validateRequestForProtocol(\"history\", {\n cursor: url.searchParams.get(\"cursor\") ?? undefined,\n mailbox: url.searchParams.get(\"mailbox\") ?? undefined as any,\n receiptState: url.searchParams.get(\"receiptState\") ?? undefined as any,\n limit: numberParam(url.searchParams.get(\"limit\"), \"limit\"),\n types: types.length ? types : undefined,\n includeExpired: booleanParam(url.searchParams.get(\"includeExpired\"), \"includeExpired\"),\n source: url.searchParams.get(\"source\") ?? undefined,\n project: url.searchParams.get(\"project\") ?? undefined,\n since: url.searchParams.get(\"since\") ?? undefined,\n unacknowledgedBy: url.searchParams.get(\"unacknowledgedBy\") ?? url.searchParams.get(\"unacked_by\") ?? undefined,\n threadId: url.searchParams.get(\"threadId\") ?? undefined,\n latest: booleanParam(url.searchParams.get(\"latest\"), \"latest\"),\n }, String(response.getHeader(PROTOCOL_HEADER)));\n sendOperation(response, 200, \"history\", await service.history(principal, input), requestId); return;\n }\n if (req.method === \"POST\" && url.pathname === \"/v2/receipts\") {\n await authorize(\"record_receipt\");\n const input = validateRequest(\"record_receipt\", await requestBody());\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"record_receipt\", { recorded: await service.acknowledge(principal, input.messageIds as string[]) }, requestId); return;\n }\n if (req.method === \"POST\" && url.pathname === \"/v2/deliveries/claim\") {\n await authorize(\"claim_delivery\");\n const input = validateRequest(\"claim_delivery\", await requestBody());\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"claim_delivery\", await service.claim(principal, input) ?? { delivery: null }, requestId); return;\n }\n if (req.method === \"GET\" && url.pathname === \"/v2/deliveries\") {\n requireCurrentProtocol(response);\n await authorize(\"list_deliveries\");\n closedQuery(url, \"list_deliveries\", [\"cursor\", \"limit\", \"role\", \"messageId\", \"recipient\", \"state\"]);\n const input = validateRequest(\"list_deliveries\", {cursor:url.searchParams.get(\"cursor\")??undefined,limit:numberParam(url.searchParams.get(\"limit\"),\"limit\"),role:url.searchParams.get(\"role\")??undefined,messageId:url.searchParams.get(\"messageId\")??undefined,recipient:url.searchParams.get(\"recipient\")??undefined,states:url.searchParams.getAll(\"state\")});\n sendOperation(response,200,\"list_deliveries\",await service.deliveries(principal,input as any),requestId);return;\n }\n const eventsMatch=url.pathname.match(/^\\/v2\\/deliveries\\/([^/]+)\\/events$/);\n if(req.method===\"GET\"&&eventsMatch){requireCurrentProtocol(response);await authorize(\"list_delivery_events\");closedQuery(url,\"list_delivery_events\",[\"cursor\",\"limit\"]);const input=validateRequest(\"list_delivery_events\",{deliveryId:eventsMatch[1],cursor:url.searchParams.get(\"cursor\")??undefined,limit:numberParam(url.searchParams.get(\"limit\"),\"limit\")});sendOperation(response,200,\"list_delivery_events\",await service.deliveryEvents(principal,eventsMatch[1]!,input as any),requestId);return;}\n const controlMatch=url.pathname.match(/^\\/v2\\/deliveries\\/([^/]+)\\/(cancel|requeue)$/);\n if(req.method===\"POST\"&&controlMatch){requireCurrentProtocol(response);const operation=controlMatch[2]===\"cancel\"?\"cancel_delivery\":\"requeue_delivery\";await authorize(operation);pathBoundInput(operation,controlMatch[1]!,await requestBody());await authority?.beginDomainWork();mutationStarted=true;const result=controlMatch[2]===\"cancel\"?await service.cancel(principal,controlMatch[1]!):await service.requeue(principal,controlMatch[1]!);if(!result)failure(response,404,\"not_found\",requestId);else sendOperation(response,200,operation,{delivery:result},requestId);return;}\n if (req.method === \"POST\" && url.pathname === \"/v2/presence/heartbeat\") {\n await authorize(\"heartbeat\");\n const input = validateRequest(\"heartbeat\", await requestBody());\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"heartbeat\", await service.heartbeat(principal, input), requestId); return;\n }\n if (req.method === \"GET\" && url.pathname === \"/v2/presence\") {\n await authorize(\"presence\");\n closedQuery(url, \"presence\", []);\n validateRequest(\"presence\", {});\n sendOperation(response, 200, \"presence\", { agents: await service.presence(principal) }, requestId); return;\n }\n const match = url.pathname.match(/^\\/v2\\/deliveries\\/([^/]+)\\/(extend|ack|nack)$/);\n if (req.method === \"POST\" && match) {\n const operationId = match[2] === \"extend\" ? \"extend_delivery\" : match[2] === \"ack\" ? \"acknowledge_delivery\" : \"negative_acknowledge_delivery\";\n await authorize(operationId);\n const rawInput = await requestBody();\n const protocolVersion = String(response.getHeader(PROTOCOL_HEADER) ?? PROTOCOL_VERSION);\n const input = pathBoundInput(operationId, match[1]!, rawInput, protocolVersion);\n active(abort.signal);\n await authority?.beginDomainWork(); mutationStarted = true;\n const [, id, action] = match;\n const result = action === \"extend\"\n ? await service.extend(principal, id, input.leaseToken as string, input.leaseMs as number)\n : action === \"ack\"\n ? await service.ack(principal, id, input.leaseToken as string)\n : await service.nack(\n principal,\n id,\n input.leaseToken as string,\n (input.error as string | undefined) ?? \"negative acknowledgment\",\n (input.disposition ?? input.dead ?? \"retry\") as \"retry\" | \"dead\" | boolean,\n input.retryPolicy,\n );\n if (!result) failure(response, 409, \"lease_conflict\", requestId);\n else sendOperation(response, 200, operationId, { delivery: result }, requestId);\n return;\n }\n failure(response, 404, \"not_found\", requestId);\n };\n void dispatch().catch((error: any) => {\n if (res.writableEnded) return;\n metrics.errors += 1;\n if (error instanceof ContractValidationError || error instanceof ContractResponseError) {\n failure(res, error.status, error.code, requestId, { operation: error.operation, issues: error.issues });\n } else if (error?.status === 426) {\n failure(res, 426, error.code, requestId, { supportedProtocolVersions: [...SUPPORTED_PROTOCOL_VERSIONS] });\n } else if (error?.code === \"insufficient_scope\") {\n failure(res, 403, error.code, requestId, { details: { requiredScopes: [...error.requiredScopes] } });\n } else if (error?.code === \"rate_limited\") {\n res.setHeader(\"retry-after\", String(error.retryAfterSeconds));\n failure(res, 429, error.code, requestId, { details: { retryAfterSeconds: error.retryAfterSeconds } });\n } else if (error instanceof BridgeValidationError || error instanceof BridgePrincipalMismatchError) {\n failure(res, \"status\" in error ? error.status : 400, error.code, requestId, { message: error.message });\n } else {\n failure(res, error?.status ?? 500, error?.code ?? \"internal_error\", requestId);\n }\n }).finally(() => clearTimeout(timer));\n });\n}\n","import { createHash, timingSafeEqual } from \"node:crypto\";\nimport type { BridgePrincipal } from \"./bridge-domain.js\";\nimport type { AuthorizationScope } from \"./contracts/registry.js\";\nimport type { PgQueryable } from \"./postgres-bridge-store.js\";\n\nexport interface AuthenticatedCredential {\n id: string;\n principal: BridgePrincipal;\n /** Canonical authorization scopes granted to this credential. */\n scopes: readonly AuthorizationScope[];\n}\n\nexport interface CredentialResolver {\n resolve(token: string, signal?: AbortSignal): Promise<AuthenticatedCredential | null>;\n}\n\nexport function hashCredential(token: string): string {\n return createHash(\"sha256\").update(token, \"utf8\").digest(\"hex\");\n}\n\nexport class PostgresCredentialResolver implements CredentialResolver {\n constructor(private readonly db: PgQueryable) {}\n\n async resolve(token: string, signal?: AbortSignal): Promise<AuthenticatedCredential | null> {\n if (signal?.aborted) throw signal.reason;\n const result = await this.db.query<{\n credential_id: string; workspace_id: string; principal: string; scopes: AuthorizationScope[];\n }>(\n `SELECT credential_id,workspace_id,principal,scopes\n FROM agent_bridge.resolve_credential_hash($1::text)`,\n [hashCredential(token)],\n );\n const row = result.rows[0];\n if (signal?.aborted) throw signal.reason;\n return row ? {\n id: row.credential_id,\n principal: { workspace: row.workspace_id, agent: row.principal },\n scopes: row.scopes,\n } : null;\n }\n}\n\nexport function bearerToken(value: string | undefined): string | null {\n if (!value?.startsWith(\"Bearer \")) return null;\n const token = value.slice(7);\n if (!token || token.length > 4096 || /\\s/.test(token)) return null;\n return token;\n}\n\nexport function safeTokenHashEqual(token: string, expectedHash: string): boolean {\n const actual = Buffer.from(hashCredential(token));\n const expected = Buffer.from(expectedHash);\n return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.d.ts
CHANGED