@creatornader/agent-bridge 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +222 -1
  2. package/README.md +312 -12
  3. package/ROADMAP.md +88 -7
  4. package/SECURITY.md +78 -5
  5. package/SKILL.md +108 -1
  6. package/dist/archive.d.ts +2 -2
  7. package/dist/archive.js +2 -2
  8. package/dist/{bridge-service-hX1ZQp4W.d.ts → bridge-service-CNBKdYXh.d.ts} +2 -1
  9. package/dist/{bridge-store-DPVSCwfs.d.ts → bridge-store-ByJ6CaJk.d.ts} +3 -0
  10. package/dist/bridge.d.ts +25 -8
  11. package/dist/bridge.js +19 -9
  12. package/dist/{chunk-MBPZXTJA.js → chunk-7VJI2MXI.js} +285 -42
  13. package/dist/chunk-7VJI2MXI.js.map +1 -0
  14. package/dist/{chunk-4VB44KJU.js → chunk-AWE3DFZV.js} +3 -2
  15. package/dist/chunk-AWE3DFZV.js.map +1 -0
  16. package/dist/{chunk-GADH244D.js → chunk-E4OWHGUE.js} +16 -5
  17. package/dist/chunk-E4OWHGUE.js.map +1 -0
  18. package/dist/{chunk-NCO7RLBM.js → chunk-GTK4KOED.js} +108 -8
  19. package/dist/chunk-GTK4KOED.js.map +1 -0
  20. package/dist/{chunk-SPSMZOCJ.js → chunk-HUHG7XTB.js} +6 -5
  21. package/dist/chunk-HUHG7XTB.js.map +1 -0
  22. package/dist/{chunk-5GMB3A77.js → chunk-IVG4XWWS.js} +26 -14
  23. package/dist/chunk-IVG4XWWS.js.map +1 -0
  24. package/dist/{chunk-WAI2IYIQ.js → chunk-P635FAN4.js} +50 -7
  25. package/dist/chunk-P635FAN4.js.map +1 -0
  26. package/dist/{chunk-45BZGB77.js → chunk-QNXHDOJ5.js} +218 -24
  27. package/dist/chunk-QNXHDOJ5.js.map +1 -0
  28. package/dist/{chunk-UAHMP6GC.js → chunk-QPC6JHA3.js} +10 -7
  29. package/dist/chunk-QPC6JHA3.js.map +1 -0
  30. package/dist/{chunk-Q6PPMXJC.js → chunk-SN7PIVDF.js} +377 -21
  31. package/dist/chunk-SN7PIVDF.js.map +1 -0
  32. package/dist/{chunk-A6W4QALF.js → chunk-TC6A7GMF.js} +2 -2
  33. package/dist/{chunk-2DFNOLMO.js → chunk-XDNT6ZNZ.js} +9 -6
  34. package/dist/chunk-XDNT6ZNZ.js.map +1 -0
  35. package/dist/{chunk-CEXBMOI5.js → chunk-Z6JP6MYD.js} +2 -2
  36. package/dist/cli.js +5867 -438
  37. package/dist/cli.js.map +1 -1
  38. package/dist/client-runtime.d.ts +4 -2
  39. package/dist/client-runtime.js +7 -7
  40. package/dist/contracts/generate.js +1 -1
  41. package/dist/dr.d.ts +9 -2
  42. package/dist/dr.js +6 -4
  43. package/dist/{gateway-CggQ8vTC.d.ts → gateway-CW-61lvs.d.ts} +27 -3
  44. package/dist/gateway-main.js +71 -7
  45. package/dist/gateway-main.js.map +1 -1
  46. package/dist/gateway.d.ts +3 -3
  47. package/dist/gateway.js +3 -3
  48. package/dist/index.js +8 -8
  49. package/dist/{postgres-bridge-store-Bfd3hRId.d.ts → postgres-bridge-store-C9KG9Z69.d.ts} +1 -1
  50. package/dist/postgres-production-preflight.d.ts +32 -0
  51. package/dist/postgres-production-preflight.js +249 -0
  52. package/dist/postgres-production-preflight.js.map +1 -0
  53. package/dist/server.js +8 -8
  54. package/dist/sqlite-edge-store-CdMIOrho.d.ts +148 -0
  55. package/dist/sqlite.d.ts +19 -80
  56. package/dist/sqlite.js +11 -3
  57. package/docs/architecture-v2.md +292 -15
  58. package/docs/decisions/0004-client-lifecycle-and-endpoint-migration.md +204 -0
  59. package/docs/deployment.md +349 -0
  60. package/docs/troubleshooting.md +23 -0
  61. package/llms.txt +69 -1
  62. package/openapi/agent-bridge-v2.openapi.json +1151 -124
  63. package/package.json +10 -2
  64. package/schemas/agent-bridge-v2.capabilities.json +26 -1
  65. package/schemas/agent-bridge-v2.mcp.json +11 -1
  66. package/schemas/agent-bridge-v2.schema.json +167 -0
  67. package/sql/migrations/007_runtime_role.sql +8 -4
  68. package/sql/migrations/013_row_isolation.sql +71 -8
  69. package/sql/migrations/014_owner_control_plane.sql +124 -31
  70. package/sql/migrations/015_portable_archives.sql +143 -41
  71. package/sql/migrations/016_native_dr_fence.sql +102 -35
  72. package/sql/migrations/017_gateway_authority_binding.sql +99 -0
  73. package/sql/migrations/018_endpoint_migration_challenges.sql +1054 -0
  74. package/sql/migrations/019_endpoint_migration_same_successor.sql +348 -0
  75. package/sql/migrations/020_managed_authority_compat.sql +698 -0
  76. package/sql/migrations/021_native_backup_reader.sql +421 -0
  77. package/sql/setup.sql +1 -3
  78. package/dist/chunk-2DFNOLMO.js.map +0 -1
  79. package/dist/chunk-45BZGB77.js.map +0 -1
  80. package/dist/chunk-4VB44KJU.js.map +0 -1
  81. package/dist/chunk-5GMB3A77.js.map +0 -1
  82. package/dist/chunk-GADH244D.js.map +0 -1
  83. package/dist/chunk-MBPZXTJA.js.map +0 -1
  84. package/dist/chunk-NCO7RLBM.js.map +0 -1
  85. package/dist/chunk-Q6PPMXJC.js.map +0 -1
  86. package/dist/chunk-SPSMZOCJ.js.map +0 -1
  87. package/dist/chunk-UAHMP6GC.js.map +0 -1
  88. package/dist/chunk-WAI2IYIQ.js.map +0 -1
  89. /package/dist/{chunk-A6W4QALF.js.map → chunk-TC6A7GMF.js.map} +0 -0
  90. /package/dist/{chunk-CEXBMOI5.js.map → chunk-Z6JP6MYD.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BridgeService
4
- } from "./chunk-4VB44KJU.js";
4
+ } from "./chunk-AWE3DFZV.js";
5
5
  import {
6
6
  ContractResponseError,
7
7
  ContractValidationError,
@@ -16,7 +16,7 @@ import {
16
16
  parseResponse,
17
17
  validateRequest,
18
18
  validateRequestForProtocol
19
- } from "./chunk-GADH244D.js";
19
+ } from "./chunk-E4OWHGUE.js";
20
20
  import {
21
21
  BridgePrincipalMismatchError,
22
22
  BridgeValidationError
@@ -385,7 +385,16 @@ function createGateway(options) {
385
385
  rowIsolation = false;
386
386
  }
387
387
  }
388
- sendOperation(response, 200, "capabilities", capabilityDocument({ surface: "http", provider: "gateway", selectedProtocolVersion: String(response.getHeader(PROTOCOL_HEADER)), requestAuthority: Boolean(options.requestAuthority), rowIsolation }), requestId);
388
+ sendOperation(response, 200, "capabilities", {
389
+ ...capabilityDocument({
390
+ surface: "http",
391
+ provider: "gateway",
392
+ selectedProtocolVersion: String(response.getHeader(PROTOCOL_HEADER)),
393
+ requestAuthority: Boolean(options.requestAuthority),
394
+ rowIsolation
395
+ }),
396
+ grantedScopes: [...credential.scopes]
397
+ }, requestId);
389
398
  return;
390
399
  }
391
400
  if (req.method === "GET" && url.pathname === "/v2/status") {
@@ -393,13 +402,47 @@ function createGateway(options) {
393
402
  closedQuery(url, "status", []);
394
403
  validateRequest("status", {});
395
404
  const activeStore = authority?.store ?? options.store;
405
+ const authorityBinding = authority && response.getHeader(PROTOCOL_HEADER) === PROTOCOL_VERSION ? {
406
+ gatewayAuthorityId: authority.gatewayAuthorityId,
407
+ credentialId: authority.credential.id
408
+ } : {};
396
409
  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);
410
+ sendOperation(response, 200, "status", { schemaVersion: "postgres-v2", deliverySupported: false, pending: null, claimed: null, retrying: null, dead: null, ...authorityBinding, principal: credential.principal }, requestId);
398
411
  } else {
399
- sendOperation(response, 200, "status", { ...await activeStore.diagnostics(principal), principal: credential.principal }, requestId);
412
+ sendOperation(response, 200, "status", { ...await activeStore.diagnostics(principal), ...authorityBinding, principal: credential.principal }, requestId);
400
413
  }
401
414
  return;
402
415
  }
416
+ if (req.method === "POST" && url.pathname === "/v2/endpoint-migration-challenges") {
417
+ requireCurrentProtocol(response);
418
+ await authorize("issue_endpoint_migration_challenge");
419
+ const input = validateRequestForProtocol("issue_endpoint_migration_challenge", await requestBody(), selectedProtocol(response));
420
+ if (!authority?.endpointMigrationChallenges) throw Object.assign(new Error("endpoint migration challenges require request authority"), { status: 503, code: "security_unavailable" });
421
+ active(abort.signal);
422
+ await authority.beginDomainWork();
423
+ mutationStarted = true;
424
+ sendOperation(response, 200, "issue_endpoint_migration_challenge", await authority.endpointMigrationChallenges.issue({
425
+ challenge: String(input.challenge),
426
+ expectedGatewayAuthorityId: String(input.expectedGatewayAuthorityId),
427
+ verifierCredentialId: String(input.verifierCredentialId)
428
+ }), requestId);
429
+ return;
430
+ }
431
+ if (req.method === "POST" && url.pathname === "/v2/endpoint-migration-challenges/consume") {
432
+ requireCurrentProtocol(response);
433
+ await authorize("consume_endpoint_migration_challenge");
434
+ const input = validateRequestForProtocol("consume_endpoint_migration_challenge", await requestBody(), selectedProtocol(response));
435
+ if (!authority?.endpointMigrationChallenges) throw Object.assign(new Error("endpoint migration challenges require request authority"), { status: 503, code: "security_unavailable" });
436
+ active(abort.signal);
437
+ await authority.beginDomainWork();
438
+ mutationStarted = true;
439
+ sendOperation(response, 200, "consume_endpoint_migration_challenge", await authority.endpointMigrationChallenges.consume({
440
+ challenge: String(input.challenge),
441
+ expectedGatewayAuthorityId: String(input.expectedGatewayAuthorityId),
442
+ issuerCredentialId: String(input.issuerCredentialId)
443
+ }), requestId);
444
+ return;
445
+ }
403
446
  if (req.method === "POST" && url.pathname === "/v2/messages") {
404
447
  await authorize("publish_message");
405
448
  const input = validateRequestForProtocol("publish_message", await requestBody(), String(response.getHeader(PROTOCOL_HEADER)));
@@ -445,7 +488,7 @@ function createGateway(options) {
445
488
  }
446
489
  if (req.method === "POST" && url.pathname === "/v2/deliveries/claim") {
447
490
  await authorize("claim_delivery");
448
- const input = validateRequest("claim_delivery", await requestBody());
491
+ const input = validateRequestForProtocol("claim_delivery", await requestBody(), selectedProtocol(response));
449
492
  active(abort.signal);
450
493
  await authority?.beginDomainWork();
451
494
  mutationStarted = true;
@@ -551,4 +594,4 @@ export {
551
594
  safeTokenHashEqual,
552
595
  createGateway
553
596
  };
554
- //# sourceMappingURL=chunk-WAI2IYIQ.js.map
597
+ //# sourceMappingURL=chunk-P635FAN4.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\", {\n ...capabilityDocument({\n surface: \"http\",\n provider: \"gateway\",\n selectedProtocolVersion: String(response.getHeader(PROTOCOL_HEADER)),\n requestAuthority: Boolean(options.requestAuthority),\n rowIsolation,\n }),\n grantedScopes: [...credential.scopes],\n }, 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 const authorityBinding = authority && response.getHeader(PROTOCOL_HEADER) === PROTOCOL_VERSION ? {\n gatewayAuthorityId: authority.gatewayAuthorityId,\n credentialId: authority.credential.id,\n } : {};\n if (!activeStore.diagnostics) {\n sendOperation(response, 200, \"status\", { schemaVersion: \"postgres-v2\", deliverySupported: false, pending: null, claimed: null, retrying: null, dead: null, ...authorityBinding, principal: credential.principal }, requestId);\n } else {\n sendOperation(response, 200, \"status\", { ...await activeStore.diagnostics(principal), ...authorityBinding, principal: credential.principal }, requestId);\n }\n return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v2/endpoint-migration-challenges\") {\n requireCurrentProtocol(response);\n await authorize(\"issue_endpoint_migration_challenge\");\n const input = validateRequestForProtocol(\"issue_endpoint_migration_challenge\", await requestBody(), selectedProtocol(response));\n if (!authority?.endpointMigrationChallenges) throw Object.assign(new Error(\"endpoint migration challenges require request authority\"), { status: 503, code: \"security_unavailable\" });\n active(abort.signal);\n await authority.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"issue_endpoint_migration_challenge\", await authority.endpointMigrationChallenges.issue({\n challenge: String(input.challenge),\n expectedGatewayAuthorityId: String(input.expectedGatewayAuthorityId),\n verifierCredentialId: String(input.verifierCredentialId),\n }), requestId); return;\n }\n\n if (req.method === \"POST\" && url.pathname === \"/v2/endpoint-migration-challenges/consume\") {\n requireCurrentProtocol(response);\n await authorize(\"consume_endpoint_migration_challenge\");\n const input = validateRequestForProtocol(\"consume_endpoint_migration_challenge\", await requestBody(), selectedProtocol(response));\n if (!authority?.endpointMigrationChallenges) throw Object.assign(new Error(\"endpoint migration challenges require request authority\"), { status: 503, code: \"security_unavailable\" });\n active(abort.signal);\n await authority.beginDomainWork(); mutationStarted = true;\n sendOperation(response, 200, \"consume_endpoint_migration_challenge\", await authority.endpointMigrationChallenges.consume({\n challenge: String(input.challenge),\n expectedGatewayAuthorityId: String(input.expectedGatewayAuthorityId),\n issuerCredentialId: String(input.issuerCredentialId),\n }), requestId); 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 = validateRequestForProtocol(\"claim_delivery\", await requestBody(), selectedProtocol(response));\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":[]}
@@ -56,6 +56,25 @@ var REQUIRED_COLUMNS = /* @__PURE__ */ new Map([
56
56
  ["request_authorities.principal", "text"],
57
57
  ["request_authorities.scopes", "_text"],
58
58
  ["request_authorities.opened_session_user", "name"],
59
+ ["request_authorities.authorized_endpoint_migration_operation", "text"],
60
+ ["gateway_authority.singleton", "bool"],
61
+ ["gateway_authority.authority_id", "uuid"],
62
+ ["endpoint_migration_challenges.challenge_hash", "bpchar"],
63
+ ["endpoint_migration_challenges.authority_id", "uuid"],
64
+ ["endpoint_migration_challenges.workspace_id", "text"],
65
+ ["endpoint_migration_challenges.principal", "text"],
66
+ ["endpoint_migration_challenges.issuer_credential_id", "uuid"],
67
+ ["endpoint_migration_challenges.verifier_credential_id", "uuid"],
68
+ ["endpoint_migration_challenges.issued_at", "timestamptz"],
69
+ ["endpoint_migration_challenges.expires_at", "timestamptz"],
70
+ ["endpoint_migration_challenges.consumed_at", "timestamptz"],
71
+ ["endpoint_migration_challenge_events.sequence", "int8"],
72
+ ["endpoint_migration_challenge_events.event_id", "uuid"],
73
+ ["endpoint_migration_challenge_events.request_id", "uuid"],
74
+ ["endpoint_migration_challenge_events.event_type", "text"],
75
+ ["endpoint_migration_challenge_events.created_at", "timestamptz"],
76
+ ["endpoint_migration_challenge_attestations.name", "text"],
77
+ ["endpoint_migration_challenge_attestations.catalog_definition", "text"],
59
78
  ["row_isolation_attestations.name", "text"],
60
79
  ["row_isolation_attestations.catalog_definition", "text"],
61
80
  ["row_isolation_attestations.attested_at", "timestamptz"],
@@ -180,6 +199,20 @@ var REQUIRED_COLUMNS = /* @__PURE__ */ new Map([
180
199
  ["agent_instances.instance", "text"],
181
200
  ["agent_instances.capabilities", "jsonb"]
182
201
  ]);
202
+ var RELEASED_MIGRATION_CHECKSUMS = /* @__PURE__ */ new Map([
203
+ ["7_runtime_role", /* @__PURE__ */ new Set(["70cca251f736c5e5a9835d5b80645e8816131767127a11a5daa9281bd38004fc"])],
204
+ ["13_row_isolation", /* @__PURE__ */ new Set(["52ed880fe6df145181f102421be8a757731713a561acfcc98acdbbca12dcf8e4"])],
205
+ ["14_owner_control_plane", /* @__PURE__ */ new Set(["7249901ab5db665fa36d6854202c9db4339f6b989a7c5b8c46b3819c5ab54353"])],
206
+ ["15_portable_archives", /* @__PURE__ */ new Set(["b019bbd9b6cfbdc0501d2cb78541de04001cde47c55fd7e011e1f88bd072460d"])],
207
+ ["16_native_dr_fence", /* @__PURE__ */ new Set(["801edad796813320bfd5d194abf35c108ab51380027af4f160b7a14a4fc79e11"])],
208
+ ["18_endpoint_migration_challenges", /* @__PURE__ */ new Set(["353285c04d8c4287dea75b30779c26f0e38e8572618403c4ed8f8a346eed0c97"])],
209
+ ["19_endpoint_migration_same_successor", /* @__PURE__ */ new Set(["feb805b9ba00f82e303a294ec26e3a7ae0f587438e5138f3ead6ad84f54bee5f"])]
210
+ ]);
211
+ function migrationRecordMatches(recorded, required) {
212
+ if (recorded.version !== required.version || recorded.name !== required.name) return false;
213
+ if (recorded.checksum === required.checksum) return true;
214
+ return RELEASED_MIGRATION_CHECKSUMS.get(`${required.version}_${required.name}`)?.has(recorded.checksum) === true;
215
+ }
183
216
  var REQUIRED_MIGRATIONS = [
184
217
  { version: 1, name: "schema_state" },
185
218
  { version: 2, name: "workspaces_agents_credentials" },
@@ -196,7 +229,12 @@ var REQUIRED_MIGRATIONS = [
196
229
  { version: 13, name: "row_isolation" },
197
230
  { version: 14, name: "owner_control_plane" },
198
231
  { version: 15, name: "portable_archives" },
199
- { version: 16, name: "native_dr_fence" }
232
+ { version: 16, name: "native_dr_fence" },
233
+ { version: 17, name: "gateway_authority_binding" },
234
+ { version: 18, name: "endpoint_migration_challenges" },
235
+ { version: 19, name: "endpoint_migration_same_successor" },
236
+ { version: 20, name: "managed_authority_compat" },
237
+ { version: 21, name: "native_backup_reader" }
200
238
  ];
201
239
  function withNativeDrSharedLock(source) {
202
240
  if (!/^begin;\s/i.test(source)) {
@@ -245,7 +283,7 @@ async function loadMigrationPlan(directory) {
245
283
  async function migrationsReady(db, expected) {
246
284
  const applied = await recordedMigrations(db);
247
285
  return expected.every(
248
- (required, index) => applied[index]?.version === required.version && applied[index]?.name === required.name && applied[index]?.checksum === required.checksum
286
+ (required, index) => applied[index] !== void 0 && migrationRecordMatches(applied[index], required)
249
287
  ) && applied.length === expected.length;
250
288
  }
251
289
  async function rowIsolationReady(db, allowPrivilegedCaller) {
@@ -254,7 +292,8 @@ async function rowIsolationReady(db, allowPrivilegedCaller) {
254
292
  ('agent_bridge_runtime_' || substr(md5(current_database()),1,16))::name AS runtime_role,
255
293
  ('agent_bridge_data_owner_' || substr(md5(current_database()),1,16))::name AS data_owner,
256
294
  ('agent_bridge_context_reader_' || substr(md5(current_database()),1,16))::name AS context_reader,
257
- ('agent_bridge_event_writer_' || substr(md5(current_database()),1,16))::name AS event_writer
295
+ ('agent_bridge_event_writer_' || substr(md5(current_database()),1,16))::name AS event_writer,
296
+ (SELECT nspowner FROM pg_namespace WHERE nspname='agent_bridge') AS schema_owner
258
297
  ), required_roles(role_name) AS (
259
298
  SELECT runtime_role FROM names UNION ALL SELECT data_owner FROM names
260
299
  UNION ALL SELECT context_reader FROM names UNION ALL SELECT event_writer FROM names
@@ -262,6 +301,18 @@ async function rowIsolationReady(db, allowPrivilegedCaller) {
262
301
  VALUES ('messages'),('receipts'),('deliveries'),('delivery_events'),('agent_instances')
263
302
  ), caller_role AS (
264
303
  SELECT * FROM pg_roles WHERE rolname=current_user
304
+ ), runtime_membership AS (
305
+ SELECT count(*)=1 AND bool_and(
306
+ NOT membership.admin_option
307
+ AND coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
308
+ AND coalesce((to_jsonb(membership)->>'set_option')::boolean,true)
309
+ AND membership.grantor=(SELECT schema_owner FROM names)
310
+ ) AS ready
311
+ FROM pg_auth_members membership
312
+ JOIN pg_roles granted ON granted.oid=membership.roleid
313
+ JOIN pg_roles member ON member.oid=membership.member
314
+ WHERE member.rolname=current_user
315
+ AND granted.rolname=(SELECT runtime_role::text FROM names)
265
316
  ), expected_policies(table_name,policy_name,command_name,role_name,needs_workspace,needs_principal) AS (
266
317
  SELECT 'messages','messages_owner_all','*',data_owner::text,false,false FROM names UNION ALL
267
318
  SELECT 'messages','messages_runtime_select','r',runtime_role::text,true,true FROM names UNION ALL
@@ -305,7 +356,7 @@ async function rowIsolationReady(db, allowPrivilegedCaller) {
305
356
  (SELECT rolcanlogin AND rolinherit AND NOT rolsuper AND NOT rolcreatedb
306
357
  AND NOT rolcreaterole AND NOT rolreplication AND NOT rolbypassrls
307
358
  FROM caller_role)
308
- AND pg_has_role(current_user,(SELECT runtime_role FROM names),'MEMBER')
359
+ AND (SELECT ready FROM runtime_membership)
309
360
  AND NOT EXISTS (
310
361
  SELECT 1 FROM pg_roles unexpected
311
362
  WHERE unexpected.oid<>(SELECT oid FROM caller_role)
@@ -525,7 +576,7 @@ async function rowIsolationReady(db, allowPrivilegedCaller) {
525
576
  row?.rolesReady && callerReady && row.ownershipReady && row.policiesReady && row.functionsReady && row.constraintsReady && row.triggersReady && row.grantsReady && row.catalogReady
526
577
  );
527
578
  }
528
- async function runtimeSchemaReady(db, options = {}) {
579
+ async function inspectRuntimeSchemaReady(db, options = {}) {
529
580
  const columns = await db.query(
530
581
  `SELECT relation.relname AS table_name, attribute.attname AS column_name,
531
582
  type.typname AS udt_name
@@ -584,11 +635,70 @@ async function runtimeSchemaReady(db, options = {}) {
584
635
  to_regprocedure('agent_bridge.consume_rate_limit(uuid,text,uuid)') IS NOT NULL AS "rateConsume",
585
636
  to_regprocedure('agent_bridge.security_schema_ready()') IS NOT NULL AS "securityReady",
586
637
  to_regclass('agent_bridge.request_authorities') IS NOT NULL AS "requestAuthorities",
638
+ to_regclass('agent_bridge.gateway_authority') IS NOT NULL AS "gatewayAuthority",
639
+ (
640
+ (SELECT attribute.attnotnull
641
+ FROM pg_attribute attribute
642
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
643
+ AND attribute.attname='singleton' AND attribute.attnum>0 AND NOT attribute.attisdropped)
644
+ AND (SELECT attribute.attnotnull
645
+ FROM pg_attribute attribute
646
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
647
+ AND attribute.attname='authority_id' AND attribute.attnum>0 AND NOT attribute.attisdropped)
648
+ AND EXISTS (
649
+ SELECT 1 FROM pg_constraint table_constraint
650
+ WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')
651
+ AND table_constraint.conname='gateway_authority_singleton'
652
+ AND table_constraint.contype='p'
653
+ AND table_constraint.conkey::smallint[]=ARRAY[(SELECT attribute.attnum FROM pg_attribute attribute
654
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
655
+ AND attribute.attname='singleton' AND attribute.attnum>0 AND NOT attribute.attisdropped)]
656
+ )
657
+ AND EXISTS (
658
+ SELECT 1 FROM pg_constraint table_constraint
659
+ WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')
660
+ AND table_constraint.conname='gateway_authority_singleton_true'
661
+ AND table_constraint.contype='c'
662
+ AND regexp_replace(
663
+ pg_get_expr(table_constraint.conbin,table_constraint.conrelid),'[[:space:]()]','','g'
664
+ )='singleton'
665
+ )
666
+ AND EXISTS (
667
+ SELECT 1 FROM pg_constraint table_constraint
668
+ WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')
669
+ AND table_constraint.conname='gateway_authority_id_unique'
670
+ AND table_constraint.contype='u'
671
+ AND table_constraint.conkey::smallint[]=ARRAY[(SELECT attribute.attnum FROM pg_attribute attribute
672
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
673
+ AND attribute.attname='authority_id' AND attribute.attnum>0 AND NOT attribute.attisdropped)]
674
+ )
675
+ ) AS "gatewayAuthorityShape",
676
+ EXISTS (
677
+ SELECT 1
678
+ FROM pg_trigger trigger
679
+ JOIN pg_proc trigger_function ON trigger_function.oid=trigger.tgfoid
680
+ JOIN pg_namespace trigger_namespace ON trigger_namespace.oid=trigger_function.pronamespace
681
+ WHERE trigger.tgrelid=to_regclass('agent_bridge.gateway_authority')
682
+ AND trigger.tgname='gateway_authority_immutable'
683
+ AND NOT trigger.tgisinternal AND trigger.tgenabled='O'
684
+ AND (trigger.tgtype::integer & 1)=0
685
+ AND (trigger.tgtype::integer & 2)=2
686
+ AND (trigger.tgtype::integer & 56)=56
687
+ AND trigger_function.proname='reject_gateway_authority_mutation'
688
+ AND trigger_namespace.nspname='agent_bridge'
689
+ AND trigger_function.proowner=(SELECT nspowner FROM pg_namespace WHERE nspname='agent_bridge')
690
+ AND NOT trigger_function.prosecdef
691
+ AND coalesce(trigger_function.proconfig @> ARRAY['search_path=""'],false)
692
+ ) AS "gatewayAuthorityImmutable",
587
693
  to_regprocedure('agent_bridge.open_request_authority(uuid,text,uuid)') IS NOT NULL
588
694
  AND to_regprocedure('agent_bridge.resolve_credential_hash(text)') IS NOT NULL AS "authorityOpen",
695
+ to_regprocedure('agent_bridge.open_request_authority_bound(uuid,text,uuid)') IS NOT NULL AS "authorityBoundOpen",
589
696
  to_regprocedure('agent_bridge.close_request_authority()') IS NOT NULL AS "authorityClose",
697
+ to_regprocedure('agent_bridge.gateway_authority_ready()') IS NOT NULL AS "authorityReady",
590
698
  NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.credentials','SELECT') AS "credentialDigestHidden",
591
699
  NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.request_authorities','SELECT') AS "authorityRowsHidden",
700
+ (NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.gateway_authority','SELECT')
701
+ AND NOT has_table_privilege('public','agent_bridge.gateway_authority','SELECT')) AS "gatewayAuthorityRowsHidden",
592
702
  (NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agents','SELECT')
593
703
  AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.workspaces','SELECT')) AS "principalTablesHidden",
594
704
  (
@@ -596,7 +706,8 @@ async function runtimeSchemaReady(db, options = {}) {
596
706
  SELECT 1
597
707
  FROM unnest(ARRAY[
598
708
  'agent_bridge.credentials','agent_bridge.agents',
599
- 'agent_bridge.workspaces','agent_bridge.request_authorities'
709
+ 'agent_bridge.workspaces','agent_bridge.request_authorities',
710
+ 'agent_bridge.gateway_authority'
600
711
  ]) protected_table(value)
601
712
  CROSS JOIN unnest(ARRAY[
602
713
  'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'
@@ -609,7 +720,8 @@ async function runtimeSchemaReady(db, options = {}) {
609
720
  SELECT 1
610
721
  FROM unnest(ARRAY[
611
722
  'agent_bridge.credentials','agent_bridge.agents',
612
- 'agent_bridge.workspaces','agent_bridge.request_authorities'
723
+ 'agent_bridge.workspaces','agent_bridge.request_authorities',
724
+ 'agent_bridge.gateway_authority'
613
725
  ]) protected_table(value)
614
726
  CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)
615
727
  WHERE has_any_column_privilege(
@@ -617,10 +729,26 @@ async function runtimeSchemaReady(db, options = {}) {
617
729
  )
618
730
  )
619
731
  ) AS "authorityTablesLocked",
732
+ NOT EXISTS (
733
+ SELECT 1
734
+ FROM unnest(ARRAY[
735
+ 'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'
736
+ ]) requested_privilege(value)
737
+ WHERE has_table_privilege('public','agent_bridge.gateway_authority',requested_privilege.value)
738
+ )
739
+ AND NOT EXISTS (
740
+ SELECT 1
741
+ FROM unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)
742
+ WHERE has_any_column_privilege(
743
+ 'public','agent_bridge.gateway_authority',requested_privilege.value
744
+ )
745
+ ) AS "gatewayAuthorityPublicLocked",
620
746
  (
621
747
  has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.resolve_credential_hash(text)','EXECUTE')
622
748
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.open_request_authority(uuid,text,uuid)','EXECUTE')
749
+ AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.open_request_authority_bound(uuid,text,uuid)','EXECUTE')
623
750
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.close_request_authority()','EXECUTE')
751
+ AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.gateway_authority_ready()','EXECUTE')
624
752
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.record_scope_denial(uuid,text,uuid)','EXECUTE')
625
753
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.consume_rate_limit(uuid,text,uuid)','EXECUTE')
626
754
  AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.active_request_authority()','EXECUTE')
@@ -629,7 +757,9 @@ async function runtimeSchemaReady(db, options = {}) {
629
757
  AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.consume_rate_limit_unbound_011(uuid,text,uuid)','EXECUTE')
630
758
  AND NOT has_function_privilege('public','agent_bridge.resolve_credential_hash(text)','EXECUTE')
631
759
  AND NOT has_function_privilege('public','agent_bridge.open_request_authority(uuid,text,uuid)','EXECUTE')
760
+ AND NOT has_function_privilege('public','agent_bridge.open_request_authority_bound(uuid,text,uuid)','EXECUTE')
632
761
  AND NOT has_function_privilege('public','agent_bridge.close_request_authority()','EXECUTE')
762
+ AND NOT has_function_privilege('public','agent_bridge.gateway_authority_ready()','EXECUTE')
633
763
  AND NOT has_function_privilege('public','agent_bridge.record_scope_denial(uuid,text,uuid)','EXECUTE')
634
764
  AND NOT has_function_privilege('public','agent_bridge.consume_rate_limit(uuid,text,uuid)','EXECUTE')
635
765
  AND NOT has_function_privilege('public','agent_bridge.record_scope_denial_unbound_011(uuid,text,uuid)','EXECUTE')
@@ -639,7 +769,8 @@ async function runtimeSchemaReady(db, options = {}) {
639
769
  JOIN pg_namespace namespace ON namespace.oid=procedure.pronamespace
640
770
  WHERE namespace.nspname='agent_bridge'
641
771
  AND procedure.proname IN (
642
- 'resolve_credential_hash','open_request_authority','active_request_authority',
772
+ 'resolve_credential_hash','open_request_authority','open_request_authority_bound',
773
+ 'gateway_authority_ready','active_request_authority',
643
774
  'assert_active_request_credential','close_request_authority','record_scope_denial',
644
775
  'consume_rate_limit','record_scope_denial_unbound_011','consume_rate_limit_unbound_011'
645
776
  )
@@ -653,22 +784,84 @@ async function runtimeSchemaReady(db, options = {}) {
653
784
  );
654
785
  const row = objects.rows[0];
655
786
  if (!Boolean(
656
- row?.immutable && row.deliveryAudit && row.idempotency && row.claim && row.publisher && row.terminal && row.source && row.thread && row.created && row.presence && row.project && row.targets && row.scopeSets && row.securityEvents && row.ratePolicies && row.rateBuckets && row.replacement && row.rateCleanup && row.credentialSecurity && row.eventAppendOnly && row.scopeAudit && row.rateConsume && row.securityReady && row.requestAuthorities && row.authorityOpen && row.authorityClose && row.credentialDigestHidden && row.authorityRowsHidden && row.principalTablesHidden && row.authorityTablesLocked && row.authorityCatalog
787
+ row?.immutable && row.deliveryAudit && row.idempotency && row.claim && row.publisher && row.terminal && row.source && row.thread && row.created && row.presence && row.project && row.targets && row.scopeSets && row.securityEvents && row.ratePolicies && row.rateBuckets && row.replacement && row.rateCleanup && row.credentialSecurity && row.eventAppendOnly && row.scopeAudit && row.rateConsume && row.securityReady && row.requestAuthorities && row.gatewayAuthority && row.gatewayAuthorityShape && row.gatewayAuthorityImmutable && row.authorityOpen && row.authorityBoundOpen && row.authorityClose && row.authorityReady && row.credentialDigestHidden && row.authorityRowsHidden && row.gatewayAuthorityRowsHidden && row.principalTablesHidden && row.authorityTablesLocked && row.gatewayAuthorityPublicLocked && row.authorityCatalog
657
788
  )) return false;
789
+ const endpointChallenge = await db.query(`
790
+ WITH names AS (
791
+ SELECT ('agent_bridge_runtime_' || substr(md5(current_database()),1,16))::name AS runtime_role
792
+ ) SELECT
793
+ to_regclass('agent_bridge.endpoint_migration_challenges') IS NOT NULL
794
+ AND to_regclass('agent_bridge.endpoint_migration_challenge_events') IS NOT NULL
795
+ AND to_regclass('agent_bridge.endpoint_migration_challenge_attestations') IS NOT NULL AS tables,
796
+ to_regprocedure('agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)') IS NOT NULL
797
+ AND to_regprocedure('agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)') IS NOT NULL
798
+ AND to_regprocedure('agent_bridge.endpoint_migration_challenge_ready()') IS NOT NULL AS functions,
799
+ NOT EXISTS (
800
+ SELECT 1
801
+ FROM unnest(ARRAY[
802
+ 'agent_bridge.endpoint_migration_challenges',
803
+ 'agent_bridge.endpoint_migration_challenge_events',
804
+ 'agent_bridge.endpoint_migration_challenge_attestations'
805
+ ]) relation_name
806
+ CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER']) privilege
807
+ WHERE has_table_privilege((SELECT runtime_role FROM names),relation_name,privilege)
808
+ OR has_table_privilege('public',relation_name,privilege)
809
+ )
810
+ AND has_function_privilege((SELECT runtime_role FROM names),
811
+ 'agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
812
+ AND has_function_privilege((SELECT runtime_role FROM names),
813
+ 'agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
814
+ AND NOT has_function_privilege('public',
815
+ 'agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
816
+ AND NOT has_function_privilege('public',
817
+ 'agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
818
+ AND NOT EXISTS (
819
+ SELECT 1
820
+ FROM pg_catalog.pg_proc procedure
821
+ JOIN pg_catalog.pg_namespace namespace ON namespace.oid=procedure.pronamespace
822
+ WHERE namespace.nspname='agent_bridge'
823
+ AND procedure.proname IN (
824
+ 'guard_endpoint_migration_challenge',
825
+ 'reject_endpoint_migration_challenge_truncate',
826
+ 'reject_endpoint_migration_challenge_event_mutation',
827
+ 'reject_endpoint_migration_challenge_attestation_mutation',
828
+ 'cleanup_endpoint_migration_challenges',
829
+ 'endpoint_migration_challenge_active_credential',
830
+ 'endpoint_migration_challenge_direct_lineage',
831
+ 'endpoint_migration_challenge_catalog_definition',
832
+ 'endpoint_migration_challenge_ready'
833
+ )
834
+ AND has_function_privilege((SELECT runtime_role FROM names),procedure.oid,'EXECUTE')
835
+ ) AS grants,
836
+ EXISTS (
837
+ SELECT 1 FROM pg_catalog.pg_attribute
838
+ WHERE attrelid='agent_bridge.request_authorities'::regclass
839
+ AND attname='authorized_endpoint_migration_operation'
840
+ AND NOT attnotnull
841
+ ) AS marker
842
+ `);
843
+ const endpoint = endpointChallenge.rows[0];
844
+ if (!endpoint?.tables || !endpoint.functions || !endpoint.grants || !endpoint.marker) return false;
845
+ const security = await db.query(
846
+ "SELECT agent_bridge.security_schema_ready() AS ready"
847
+ );
848
+ const ownerControl = await db.query(
849
+ "SELECT agent_bridge.owner_control_plane_ready() AS ready"
850
+ );
851
+ const portableArchive = await db.query(
852
+ "SELECT agent_bridge.portable_archive_ready() AS ready"
853
+ );
854
+ const gatewayAuthority = await db.query(
855
+ "SELECT agent_bridge.gateway_authority_ready() AS ready"
856
+ );
857
+ return security.rows[0]?.ready === true && ownerControl.rows[0]?.ready === true && portableArchive.rows[0]?.ready === true && gatewayAuthority.rows[0]?.ready === true && await rowIsolationReady(
858
+ db,
859
+ options.allowPrivilegedCaller === true
860
+ );
861
+ }
862
+ async function runtimeSchemaReady(db, options = {}) {
658
863
  try {
659
- const security = await db.query(
660
- "SELECT agent_bridge.security_schema_ready() AS ready"
661
- );
662
- const ownerControl = await db.query(
663
- "SELECT agent_bridge.owner_control_plane_ready() AS ready"
664
- );
665
- const portableArchive = await db.query(
666
- "SELECT agent_bridge.portable_archive_ready() AS ready"
667
- );
668
- return security.rows[0]?.ready === true && ownerControl.rows[0]?.ready === true && portableArchive.rows[0]?.ready === true && await rowIsolationReady(
669
- db,
670
- options.allowPrivilegedCaller === true
671
- );
864
+ return await inspectRuntimeSchemaReady(db, options);
672
865
  } catch {
673
866
  return false;
674
867
  }
@@ -679,7 +872,7 @@ async function runMigrations(db, directory) {
679
872
  const applied = await recordedMigrations(db);
680
873
  const recorded = applied.find((entry) => entry.version === migration.version);
681
874
  if (recorded) {
682
- if (recorded.name !== migration.name || recorded.checksum !== migration.checksum) {
875
+ if (!migrationRecordMatches(recorded, migration)) {
683
876
  throw new Error(`migration ${migration.version}_${migration.name} conflicts with schema state`);
684
877
  }
685
878
  continue;
@@ -699,6 +892,7 @@ async function runMigrations(db, directory) {
699
892
 
700
893
  export {
701
894
  NATIVE_DR_ADVISORY_LOCK_KEY,
895
+ migrationRecordMatches,
702
896
  REQUIRED_MIGRATIONS,
703
897
  loadMigrationPlan,
704
898
  migrationsReady,
@@ -706,4 +900,4 @@ export {
706
900
  runtimeSchemaReady,
707
901
  runMigrations
708
902
  };
709
- //# sourceMappingURL=chunk-45BZGB77.js.map
903
+ //# sourceMappingURL=chunk-QNXHDOJ5.js.map