@kb-labs/gateway-app 2.103.0 → 2.105.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/auth/tokens.ts","../src/auth/middleware.ts","../src/auth/user-cookies.ts","../src/auth/routes.ts","../src/auth/user-auth-middleware.ts","../src/auth/oauth-return-to.ts","../src/auth/oauth-routes.ts","../src/auth/user-routes.ts","../src/execute/execution-registry.ts","../src/clients/subscription-registry.ts","../src/execute/errors.ts","../src/execute/retry-executor.ts","../src/execute/routes.ts","../src/llm/routes.ts","../src/telemetry/routes.ts","../src/platform/routes.ts","../src/docs/routes.ts","../src/hosts/registry.ts","../src/hosts/ws-handler.ts","../src/clients/ws-handler.ts","../src/ws/pump.ts","../src/ws/gateway-ws.ts","../src/observability/collector.ts","../src/internal/routes.ts","../src/pressure/resolve.ts","../src/pressure/register-limits.ts","../src/pressure/hooks.ts","../src/webhook/secret-store.ts","../src/webhook/provision.ts","../src/webhook/admin-routes.ts","../src/webhook/idempotency-store.ts","../src/webhook/auth.ts","../src/webhook/router.ts","../src/server.ts","../src/bootstrap.ts","../src/index.ts"],"names":["PERMISSIONS","getCookies","accessTtl","refreshTtl","AuthError","result","response","platform","cacheKey","randomUUID","logDiagnosticEvent","HELLO_TIMEOUT_MS","send","randomBytes","AuthService","createCorrelatedLogger"],"mappings":"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","file":"index.js","sourcesContent":["import { loadEffectiveConfig } from '@kb-labs/core-config';\nimport { GatewayConfigSchema, type GatewayConfig } from '@kb-labs/gateway-contracts';\n\n/**\n * Gateway config resolution.\n *\n * Delegates the entire layering (platform baseline ← project layer ←\n * `.kb/overlays/*.jsonc` from `kb-dev ensure --scenario`) to\n * `@kb-labs/core-config :: loadEffectiveConfig`. This file does one job:\n * pluck the `gateway` section out of the merged result and validate it.\n */\nexport async function loadGatewayConfig(repoRoot: string, platformRoot?: string): Promise<GatewayConfig> {\n const merged = await loadEffectiveConfig(repoRoot, { platformRoot });\n const gateway = (merged?.data as { gateway?: unknown } | undefined)?.gateway;\n if (gateway && typeof gateway === 'object' && !Array.isArray(gateway)) {\n return GatewayConfigSchema.parse(gateway);\n }\n return GatewayConfigSchema.parse({});\n}\n","import type { ICache } from '@kb-labs/core-platform';\nimport type { AuthContext } from '@kb-labs/gateway-contracts';\nimport { AuthService, type JwtConfig } from '@kb-labs/gateway-auth';\n\n/**\n * Resolve a Bearer token to an AuthContext.\n *\n * Priority:\n * 1. JWT verification (machine tokens issued via /auth/token).\n * 2. Host-registry opaque token (issued by /hosts/register, stored in cache\n * as host:token:{uuid}). These are runtime-issued tokens for WebSocket agents,\n * distinct from the removed static pre-seeded config tokens.\n */\nexport async function resolveToken(\n token: string,\n cache: ICache,\n jwtConfig: JwtConfig,\n): Promise<AuthContext | null> {\n const authService = new AuthService(cache, jwtConfig);\n\n // Try JWT first (tokens issued via /auth/token).\n const jwtContext = await authService.verify(token);\n if (jwtContext) {return jwtContext;}\n\n // Fallback: host-registry opaque token (issued by /hosts/register).\n // Permissions default to ['host:connect'] for backward compatibility.\n const hostEntry = await cache.get<{ hostId: string; namespaceId: string; permissions?: string[] }>(\n `host:token:${token}`,\n );\n if (hostEntry) {\n return {\n type: 'machine',\n userId: hostEntry.hostId,\n namespaceId: hostEntry.namespaceId,\n tier: 'free',\n permissions: hostEntry.permissions ?? ['host:connect'],\n };\n }\n\n return null;\n}\n\nexport function extractBearerToken(authHeader: string | undefined): string | null {\n if (!authHeader) {return null;}\n const match = authHeader.match(/^Bearer\\s+(.+)$/i);\n return match ? (match[1] ?? null) : null;\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { ICache } from '@kb-labs/core-platform';\nimport type { AuthContext } from '@kb-labs/gateway-contracts';\nimport type { JwtConfig } from '@kb-labs/gateway-auth';\nimport { PERMISSIONS } from '@kb-labs/core-contracts';\nimport { resolveToken, extractBearerToken } from './tokens.js';\n\n/**\n * Deterministic identity used when auth is disabled (solo/local mode). All\n * requests run as this single local admin so namespaced data and audit logs\n * stay coherent, and enabling auth later does not invalidate existing data.\n */\nexport const LOCAL_ADMIN_CONTEXT: AuthContext = {\n type: 'machine',\n userId: 'local-admin',\n namespaceId: 'local',\n tier: 'enterprise',\n permissions: Object.values(PERMISSIONS),\n};\n\n// Routes that don't require auth (handle their own auth internally)\nconst PUBLIC_ROUTES = new Set([\n '/health',\n '/health/adapters',\n '/ready',\n // Studio SPA shell (index.html) — the login page itself. There is no\n // session yet when a browser first hits this, so it can't be gated.\n // Exact match only (not a prefix) so it doesn't swallow unrelated routes.\n '/',\n // Module Federation manifest — static, non-sensitive metadata describing\n // available Studio remotes. The Studio SPA shell must be able to fetch\n // this before a user has logged in (there is no session yet to gate on).\n '/mf-manifest.json',\n '/hosts/register',\n // /hosts/connect and /clients/connect are handled at the HTTP upgrade level\n // by gateway-ws.ts (raw ws) — they never reach Fastify routing.\n // NOTE: /auth/register is NOT public — it requires MACHINE_REGISTER permission\n // (cookie-auth admin or Bearer machine with that permission).\n '/auth/token',\n '/auth/refresh',\n // User-auth public endpoints (ADR-0020, Phase 1.16).\n '/auth/login',\n '/auth/activate',\n '/auth/providers',\n '/internal/dispatch', // has its own x-internal-secret auth\n '/internal/resolve-host', // has its own x-internal-secret auth\n]);\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n authContext?: AuthContext;\n }\n}\n\nexport function createAuthMiddleware(\n cache: ICache,\n jwtConfig: JwtConfig,\n options: { authEnabled?: boolean } = {},\n) {\n const authEnabled = options.authEnabled !== false; // default: enabled\n return async function authMiddleware(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void> {\n // Auth disabled (solo/local mode): every request runs as the local admin.\n // The startup guardrail (bootstrap) guarantees this only happens on a\n // loopback bind, so it never exposes an open platform on the network.\n if (!authEnabled) {\n request.authContext = LOCAL_ADMIN_CONTEXT;\n return;\n }\n\n const rawPath = new URL(request.url, 'http://localhost').pathname;\n const routePath = rawPath.replace(/\\/+/g, '/').replace(/\\/+$/, '') || '/';\n if (PUBLIC_ROUTES.has(routePath)) {return;}\n // Redirect/OAuth endpoints (ADR-0020, Step 4) are public — they carry no\n // Bearer token (the IdP→callback hop is a top-level browser navigation) and\n // enforce their own state/cookie binding. Prefix match covers /start and\n // /callback for every provider id.\n if (routePath.startsWith('/auth/oauth/')) {return;}\n\n // Webhook delivery routes (/webhooks/:pluginId/:event[/:instanceId]) are\n // called by external senders (GitHub, Stripe, etc.) that have no Bearer\n // token for this platform — they authenticate via their own per-webhook\n // secret/HMAC, checked inside the handler itself. This scope was\n // originally registered outside `gatewayRoutes` specifically so the old,\n // more narrowly-scoped auth hook would skip it automatically; now that\n // the hook runs globally (GHSA-75rf-rhxh-2p52 fix) it needs an explicit\n // bypass here instead. Distinct from the admin routes under\n // /api/v1/webhooks/*, which remain fully auth-gated.\n if (routePath.startsWith('/webhooks/')) {return;}\n\n // Static Module Federation widget bundles proxied through to rest-api\n // (/plugins/@scope/name/widgets/*) — plain JS/CSS files the Studio SPA\n // shell needs to load widgets, with no user data and no side effects.\n // Same category as /mf-manifest.json above.\n if (routePath.startsWith('/plugins/')) {return;}\n\n // Studio's own static bundle (/studio/assets/*.js, etc.) — the SPA shell\n // itself, needed before a user has logged in. Same category as\n // /mf-manifest.json and /plugins/*/widgets/* above.\n if (routePath.startsWith('/studio/')) {return;}\n\n // Bearer header takes precedence; fall back to ?access_token= for SSE\n // connections where browsers cannot set custom headers.\n const queryToken = (request.query as Record<string, string | undefined>)['access_token'];\n const token = extractBearerToken(request.headers.authorization) ?? queryToken ?? null;\n\n // Skip machine Bearer check when the request is already user-authenticated\n // via cookie AND no explicit Bearer token was provided.\n // When BOTH cookie and Bearer are present (e.g. a Playwright context that\n // accumulated session cookies while also sending machine credentials), we\n // honour the Bearer token so that machine-auth context (namespaceId, etc.)\n // is populated — critical for per-tenant rate limiting and route permissions.\n if (!token && request.userAuthContext) {return;}\n\n if (!token) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Missing Authorization header' });\n }\n\n const authContext = await resolveToken(token, cache, jwtConfig);\n if (!authContext) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid token' });\n }\n\n request.authContext = authContext;\n };\n}\n","/**\n * @module @kb-labs/gateway-app/auth/user-cookies\n *\n * Canonical cookie names + setter / clearer helpers for the user-auth\n * flow (ADR-0020).\n *\n * The triple:\n * - `kb_access` — HttpOnly, holds the access JWT. Path `/`. TTL = access TTL.\n * - `kb_refresh` — HttpOnly, holds the refresh JWT. Path `/api/auth/refresh`.\n * TTL = refresh TTL.\n * - `kb_csrf` — non-HttpOnly so Studio JS can read it and echo via\n * X-CSRF-Token. Path `/`. TTL = refresh TTL (matches the\n * longest-lived cookie so it survives access rotation).\n *\n * No `Domain` attribute — cookies are origin-scoped to `{tenant}.kblabs.ru`,\n * structurally preventing cross-tenant leakage.\n *\n * Production sets `Secure` and `SameSite=Strict`. Dev (cookieSecure=false)\n * drops `Secure` so http://localhost works without a cert.\n */\n\nimport type { FastifyReply } from 'fastify';\n\nexport const COOKIE_ACCESS = 'kb_access';\nexport const COOKIE_REFRESH = 'kb_refresh';\nexport const COOKIE_CSRF = 'kb_csrf';\nexport const COOKIE_OAUTH_STATE = 'kb_oauth_state';\n\nexport const REFRESH_COOKIE_PATH = '/api/auth/refresh';\nexport const OAUTH_COOKIE_PATH = '/api/auth/oauth';\n\nexport interface CookieOptions {\n /** False in dev (http://localhost), true in prod (https) — set Secure flag. */\n cookieSecure: boolean;\n}\n\nexport interface SetSessionCookiesInput {\n accessToken: string;\n accessTtlSec: number;\n refreshToken: string;\n refreshTtlSec: number;\n csrfToken: string;\n}\n\nconst baseAttrs = (cookieSecure: boolean, ttlSec: number) => ({\n httpOnly: true,\n secure: cookieSecure,\n sameSite: 'strict' as const,\n maxAge: ttlSec,\n});\n\n/**\n * Write all three session cookies on the reply.\n *\n * The `kb_csrf` cookie is non-HttpOnly — the SPA must be able to read\n * it via document.cookie and submit it via X-CSRF-Token. Its `maxAge`\n * matches the refresh TTL so a long-running session doesn't lose CSRF\n * cover between access rotations.\n */\nexport const setSessionCookies = (\n reply: FastifyReply,\n input: SetSessionCookiesInput,\n opts: CookieOptions,\n): void => {\n reply.setCookie(COOKIE_ACCESS, input.accessToken, {\n ...baseAttrs(opts.cookieSecure, input.accessTtlSec),\n path: '/',\n });\n reply.setCookie(COOKIE_REFRESH, input.refreshToken, {\n ...baseAttrs(opts.cookieSecure, input.refreshTtlSec),\n path: REFRESH_COOKIE_PATH,\n });\n reply.setCookie(COOKIE_CSRF, input.csrfToken, {\n // CSRF cookie is NON-HttpOnly so JS can read it.\n httpOnly: false,\n secure: opts.cookieSecure,\n sameSite: 'strict' as const,\n maxAge: input.refreshTtlSec,\n path: '/',\n });\n};\n\n/**\n * The OAuth state cookie binds the browser that *started* a flow to the\n * one that *finishes* it (defence against state-fixation / login CSRF).\n *\n * It MUST be `SameSite=Lax`, NOT Strict: the IdP→callback hop is a\n * cross-site top-level navigation, and a Strict cookie would not be sent\n * on it, breaking the binding. Lax still blocks cross-site sub-resource\n * sends, which is all we need here. Scoped to the OAuth path so it never\n * rides along with normal API calls.\n */\nexport const setOAuthStateCookie = (\n reply: FastifyReply,\n state: string,\n opts: CookieOptions,\n ttlSec: number,\n): void => {\n reply.setCookie(COOKIE_OAUTH_STATE, state, {\n httpOnly: true,\n secure: opts.cookieSecure,\n sameSite: 'lax' as const,\n maxAge: ttlSec,\n path: OAUTH_COOKIE_PATH,\n });\n};\n\nexport const clearOAuthStateCookie = (reply: FastifyReply, opts: CookieOptions): void => {\n reply.clearCookie(COOKIE_OAUTH_STATE, {\n secure: opts.cookieSecure,\n sameSite: 'lax' as const,\n path: OAUTH_COOKIE_PATH,\n });\n};\n\nexport const clearSessionCookies = (reply: FastifyReply, opts: CookieOptions): void => {\n const common = { secure: opts.cookieSecure, sameSite: 'strict' as const };\n reply.clearCookie(COOKIE_ACCESS, { ...common, path: '/' });\n reply.clearCookie(COOKIE_REFRESH, { ...common, path: REFRESH_COOKIE_PATH });\n reply.clearCookie(COOKIE_CSRF, { ...common, path: '/' });\n};\n","/**\n * Auth routes — machine-client endpoints for agent registration and token management.\n *\n * POST /auth/register — register new agent, get clientId + clientSecret\n * (gated behind MACHINE_REGISTER permission; see gate below)\n * POST /auth/token — exchange credentials for JWT pair\n * POST /auth/refresh — rotate refresh token (machine body path); user cookie\n * path is handled first if userRefreshFn is provided\n *\n * NOTE: GET /auth/me is NOT registered here — it lives in registerUserAuthRoutes\n * because it must handle both user-cookie and machine-Bearer contexts in one handler.\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type { AuthService, IPolicyDecisionPoint } from '@kb-labs/gateway-auth';\nimport {\n RegisterRequestSchema,\n TokenRequestSchema,\n RefreshRequestSchema,\n} from '@kb-labs/gateway-contracts';\nimport { PERMISSIONS } from '@kb-labs/core-contracts';\nimport { COOKIE_REFRESH } from './user-cookies.js';\n\nexport interface MachineAuthRoutesUserExt {\n /** Called when a user refresh cookie is detected in POST /auth/refresh.\n * Must write the reply and return true; return false to fall through to\n * the machine body-refresh path. */\n userRefreshFn: (request: FastifyRequest, reply: FastifyReply) => Promise<boolean>;\n /** PDP for checking MACHINE_REGISTER permission on cookie-authenticated admin users. */\n pdp: IPolicyDecisionPoint;\n}\n\nexport function registerAuthRoutes(\n app: FastifyInstance,\n authService: AuthService,\n userExt?: MachineAuthRoutesUserExt,\n): void {\n // Register new agent.\n // Requires MACHINE_REGISTER permission. Auth checks:\n // - Anonymous (no cookie, no Bearer) → 401 from machine-auth middleware\n // - Cookie-auth user without permission → 403 (PDP check below)\n // - Cookie-auth admin with MACHINE_REGISTER → 200\n // - Bearer-auth machine with machine:register in JWT permissions → 200\n app.post('/auth/register', { schema: { tags: ['Auth'], summary: 'Register new agent and get credentials' } }, async (request, reply) => {\n // Gate behind MACHINE_REGISTER permission.\n // Two auth paths: cookie-authenticated user (userAuthContext) or Bearer machine (authContext).\n const userCtx = request.userAuthContext;\n const machineCtx = request.authContext;\n\n if (userCtx && userExt?.pdp) {\n // Cookie-authenticated user — check via PDP.\n const decision = await userExt.pdp.check(\n { userId: userCtx.userId, tenantId: userCtx.tenantId, type: 'user' },\n PERMISSIONS.MACHINE_REGISTER,\n );\n if (!decision.allow) {\n return reply.code(403).send({ error: 'Forbidden', message: `Permission denied: ${PERMISSIONS.MACHINE_REGISTER}` });\n }\n } else if (machineCtx) {\n // Bearer-authenticated machine — check permissions embedded in JWT.\n if (!machineCtx.permissions.includes(PERMISSIONS.MACHINE_REGISTER)) {\n return reply.code(403).send({ error: 'Forbidden', message: `Permission denied: ${PERMISSIONS.MACHINE_REGISTER}` });\n }\n } else {\n // No auth context at all (should have been caught by middleware, but guard defensively).\n return reply.code(401).send({ error: 'Unauthorized', message: 'Authentication required' });\n }\n\n const parsed = RegisterRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const { name, capabilities, publicKey, handle, email } = parsed.data;\n try {\n const result = await authService.register({ name, capabilities, publicKey, handle, email });\n return reply.code(200).send(result);\n } catch (err) {\n if (err instanceof Error && (err as NodeJS.ErrnoException).code === 'HANDLE_TAKEN') {\n return reply.code(409).send({ error: 'Conflict', message: err.message });\n }\n throw err;\n }\n });\n\n // Issue token pair (machine credentials → JWT pair).\n app.post('/auth/token', { schema: { tags: ['Auth'], summary: 'Issue JWT token pair' } }, async (request, reply) => {\n const parsed = TokenRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const tokens = await authService.issueTokens(parsed.data.clientId, parsed.data.clientSecret);\n if (!tokens) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid credentials' });\n }\n\n return reply.send(tokens);\n });\n\n // Refresh token pair.\n // If a user refresh cookie is detected AND userExt.userRefreshFn is provided,\n // the user path is handled first. Otherwise, falls back to machine body refresh.\n app.post('/auth/refresh', { schema: { tags: ['Auth'], summary: 'Refresh JWT token pair (machine or user)' } }, async (request, reply) => {\n // User cookie refresh — handled by the user-auth subsystem if wired.\n const cookies = (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies;\n const refreshCookie = cookies?.[COOKIE_REFRESH];\n if (refreshCookie && userExt) {\n const handled = await userExt.userRefreshFn(request, reply);\n if (handled) {return;}\n }\n\n // Machine body refresh (existing logic).\n const parsed = RefreshRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const tokens = await authService.refreshTokens(parsed.data.refreshToken);\n if (!tokens) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid or expired refresh token' });\n }\n\n return reply.send(tokens);\n });\n}\n","/**\n * @module @kb-labs/gateway-app/auth/user-auth-middleware\n *\n * Fastify onRequest hook for cookie-based user authentication\n * (ADR-0020, Phase 1.16).\n *\n * Runs BEFORE the existing machine-token middleware. Three outcomes:\n *\n * - **No `kb_access` cookie** — middleware is a no-op. Downstream\n * (Bearer-based machine auth) takes over.\n * - **Cookie present, valid, user active in correct tenant** — sets\n * `request.userAuthContext` with `{ type, userId, tenantId,\n * familyId }` and lets the request through.\n * - **Cookie present but invalid in any way** — returns 401 WITHOUT\n * falling through to machine auth. A tampered cookie must not\n * silently bypass into the Bearer path.\n *\n * What this middleware enforces:\n *\n * - **CD-1**: `users.getById(userId).status === 'active'`. The PDP\n * does not see this; without an explicit check a disabled user\n * keeps acting for up to one access TTL.\n * - **Cross-tenant guard**: `payload.tenantId ===\n * tenantResolver(req.host)`. A cookie from tenant A presented on\n * tenant B's subdomain is rejected.\n */\n\nimport type { FastifyRequest, FastifyReply, FastifyError } from 'fastify';\nimport type { UsersStore, JwtConfig, TenantResolver } from '@kb-labs/gateway-auth';\nimport { verifyUserAccessToken } from '@kb-labs/gateway-auth';\nimport { COOKIE_ACCESS } from './user-cookies.js';\n\nexport interface UserAuthContext {\n type: 'user';\n userId: string;\n tenantId: string;\n familyId: string;\n}\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n userAuthContext?: UserAuthContext;\n }\n}\n\nexport interface UserAuthMiddlewareDeps {\n users: UsersStore;\n tenantResolver: TenantResolver;\n jwtConfig: JwtConfig;\n}\n\nconst sendUnauthorized = (reply: FastifyReply, message: string) =>\n reply.code(401).send({ error: 'Unauthorized', message });\n\nexport const createUserAuthMiddleware = (deps: UserAuthMiddlewareDeps) => {\n return async function userAuthMiddleware(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void | FastifyError> {\n const cookies = (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies;\n const token = cookies?.[COOKIE_ACCESS];\n if (!token) {\n // No user cookie — let machine middleware (Bearer) handle the request.\n return;\n }\n\n const payload = await verifyUserAccessToken(token, deps.jwtConfig);\n if (!payload) {\n return sendUnauthorized(reply, 'Invalid session');\n }\n\n // Cross-tenant guard. The cookie alone doesn't tell us \"which\n // tenant origin\" the browser thinks it's on — we re-derive from\n // Host so a stolen cookie cannot be presented on another tenant.\n //\n // Guard fires only when the Host resolves to a known tenant. When\n // resolvedTenant is null (localhost, raw IP, development, E2E), the\n // request is not subdomain-routed and we cannot enforce per-tenant\n // isolation — let it through. An attacker cannot fake a legitimate\n // tenant subdomain without also controlling DNS / TLS, so the guard\n // only needs to activate when the resolver returns a concrete slug.\n const hostHeader = request.headers['host'];\n const resolvedTenant = deps.tenantResolver.resolve(\n typeof hostHeader === 'string' ? hostHeader : undefined,\n );\n if (resolvedTenant !== null && resolvedTenant !== payload.tenantId) {\n return sendUnauthorized(reply, 'Tenant mismatch');\n }\n\n // CD-1: explicit user.status check on every request. Without this\n // a disabled user keeps acting for the remaining access TTL.\n const user = await deps.users.getById(payload.userId);\n if (!user || user.status !== 'active') {\n return sendUnauthorized(reply, 'Session no longer valid');\n }\n\n request.userAuthContext = {\n type: 'user',\n userId: payload.userId,\n tenantId: payload.tenantId,\n familyId: payload.familyId,\n };\n };\n};\n","/**\n * @module @kb-labs/gateway-app/auth/oauth-return-to\n *\n * Open-redirect guard for the OAuth flow (ADR-0020, Step 4b).\n *\n * `returnTo` is attacker-influenceable (it rides in the `/start` query\n * string). After a successful callback we redirect the now-authenticated\n * browser to it, so it MUST be a same-origin relative path — never an\n * absolute or protocol-relative URL that could bounce the user to a\n * phishing origin.\n *\n * Whitelist: a path that starts with a single `/` not followed by another\n * `/` or a `\\` (browsers normalise `/\\` to `//`, i.e. protocol-relative).\n * Anything else collapses to `/`.\n */\n\n// Starts with '/', and the next char (if any) is not '/' or '\\'.\nconst SAFE_RELATIVE_PATH = /^\\/(?![/\\\\])/;\n\nexport function validateReturnTo(raw: unknown): string {\n if (typeof raw !== 'string' || raw.length === 0) {\n return '/';\n }\n if (!SAFE_RELATIVE_PATH.test(raw)) {\n return '/';\n }\n return raw;\n}\n","/**\n * @module @kb-labs/gateway-app/auth/oauth-routes\n *\n * HTTP routes for the redirect/OAuth identity flow (ADR-0020, Step 4 + 4b).\n *\n * GET /auth/oauth/:id/start — mint an opaque `state`, persist the flow\n * context in KV, set a SameSite=Lax state\n * cookie, then 302 to the upstream IdP.\n * GET /auth/oauth/:id/callback — verify the state (KV + cookie binding +\n * one-shot consume + cross-tenant + mix-up\n * guards), run the provider through\n * userAuthService.login (DD-6), set the\n * session cookies, then 302 to returnTo.\n *\n * Security invariants (Step 4b):\n * - **Open-redirect guard**: returnTo is validated to a same-origin\n * relative path (validateReturnTo); anything else collapses to '/'.\n * - **State-cookie binding**: the query `state` must equal the value in\n * the Lax state cookie — defends against login-CSRF / state fixation.\n * - **One-shot state**: OAuthStateStore.consume deletes on read, so a\n * replayed callback cannot be processed twice.\n * - **Cross-tenant guard**: the tenant the callback Host resolves to must\n * match the tenant the state was minted for.\n * - **Mix-up guard**: the provider is taken from the KV state, not the\n * URL — and the URL :id must match it.\n * - **Per-IP rate-limit**: both /start and /callback are throttled (via a\n * preHandler barrier) before any KV / provider work to blunt floods.\n * - Secrets (code / id_token / session) are never logged.\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type {\n ProviderRegistry,\n TenantResolver,\n OAuthStateStore,\n RateLimiter,\n SessionResult,\n} from '@kb-labs/gateway-auth';\nimport { AuthError, issueCsrfToken } from '@kb-labs/gateway-auth';\nimport type { IRedirectIdentityProvider } from '@kb-labs/core-contracts';\nimport type { UserAuthServiceForRoutes } from './user-routes.js';\nimport { validateReturnTo } from './oauth-return-to.js';\nimport {\n setSessionCookies,\n setOAuthStateCookie,\n clearOAuthStateCookie,\n COOKIE_OAUTH_STATE,\n type CookieOptions,\n} from './user-cookies.js';\n\n/** State cookie / KV TTL — abandoned flows self-clean after this window. */\nconst OAUTH_STATE_TTL_SEC = 10 * 60;\n\nexport interface OAuthRouteDeps {\n userAuthService: UserAuthServiceForRoutes;\n providers: ProviderRegistry;\n tenantResolver: TenantResolver;\n oauthState: OAuthStateStore;\n cookieOpts: CookieOptions;\n /** Optional limiter; per-IP callback throttling is skipped when absent. */\n rateLimiter?: RateLimiter;\n /** Max callbacks per IP per minute. Default 60 when a limiter is present. */\n oauthCallbackPerIpPerMinute?: number;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction getCookies(request: FastifyRequest): Record<string, string | undefined> {\n return (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies ?? {};\n}\n\n/** Builds the absolute callback URL from the request Host (nginx-set in prod). */\nfunction callbackUrl(request: FastifyRequest, id: string, secure: boolean): string {\n const host = typeof request.headers.host === 'string' ? request.headers.host : 'localhost';\n const proto = secure ? 'https' : 'http';\n return `${proto}://${host}/api/auth/oauth/${id}/callback`;\n}\n\nfunction isRedirectProvider(\n p: ReturnType<ProviderRegistry['get']>,\n): p is IRedirectIdentityProvider {\n return !!p && p.kind === 'redirect';\n}\n\nfunction accessTtl(result: SessionResult): number {\n return result.access.expiresInSec;\n}\nfunction refreshTtl(result: SessionResult): number {\n return result.refresh.expiresInSec;\n}\n\n// ── Registrar ───────────────────────────────────────────────────────────────────\n\nexport function registerOAuthRoutes(app: FastifyInstance, deps: OAuthRouteDeps): void {\n const { userAuthService, providers, tenantResolver, oauthState, cookieOpts, rateLimiter } = deps;\n const perIpPerMinute = deps.oauthCallbackPerIpPerMinute ?? 60;\n\n /**\n * Per-IP rate-limit barrier (Step 4b). Runs as a `preHandler` BEFORE any\n * KV / provider work on both `/start` and `/callback`, so a flood from one\n * source costs ~0 beyond the counter bump. `bucket` keeps the two routes on\n * independent counters. A no-op when no limiter is wired (tests / dev).\n */\n function rateLimitGate(bucket: string) {\n return async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {\n if (!rateLimiter) {\n return;\n }\n const r = await rateLimiter.check(`rl:oauth:${bucket}:ip:${request.ip}`, {\n max: perIpPerMinute,\n windowMs: 60_000,\n });\n if (!r.allowed) {\n reply.header('Retry-After', String(r.retryAfterSec));\n await reply\n .code(429)\n .send({ error: 'Too Many Requests', message: 'Rate limit exceeded', retryAfterSec: r.retryAfterSec });\n }\n };\n }\n\n /** Clear the state cookie and bounce to the login page with an error flag. */\n function failCallback(reply: FastifyReply): FastifyReply {\n clearOAuthStateCookie(reply, cookieOpts);\n return reply.redirect('/login?error=oauth', 302);\n }\n\n // ── GET /auth/oauth/:id/start ─────────────────────────────────────────────────\n app.get<{ Params: { id: string }; Querystring: { returnTo?: string } }>(\n '/auth/oauth/:id/start',\n {\n schema: { tags: ['Auth'], summary: 'Begin a redirect/OAuth login flow' },\n preHandler: rateLimitGate('start'),\n },\n async (request, reply) => {\n const { id } = request.params;\n const provider = providers.get(id);\n if (!isRedirectProvider(provider)) {\n return reply.code(400).send({ error: 'Bad Request', message: 'Unknown or non-redirect provider' });\n }\n\n // Tenant is derived from Host (authoritative in subdomain deployments).\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const tenantId = tenantResolver.resolve(host) ?? '';\n\n const returnTo = validateReturnTo(request.query?.returnTo);\n const state = issueCsrfToken();\n const redirectUri = callbackUrl(request, id, cookieOpts.cookieSecure);\n\n const startResult = await provider.startAuthorization({ state, redirectUri });\n\n await oauthState.put(state, {\n providerId: id,\n tenantId,\n returnTo,\n session: startResult.session,\n createdAt: Date.now(),\n });\n\n setOAuthStateCookie(reply, state, cookieOpts, OAUTH_STATE_TTL_SEC);\n return reply.redirect(startResult.redirectUrl, 302);\n },\n );\n\n // ── GET /auth/oauth/:id/callback ───────────────────────────────────────────────\n app.get<{ Params: { id: string }; Querystring: { state?: string; code?: string; error?: string } }>(\n '/auth/oauth/:id/callback',\n {\n schema: { tags: ['Auth'], summary: 'Complete a redirect/OAuth login flow' },\n preHandler: rateLimitGate('cb'),\n },\n async (request, reply) => {\n const { id } = request.params;\n const { state, code, error } = request.query ?? {};\n\n // IdP signalled an error (user denied consent, etc.) — never touch the\n // provider; just bounce back to login.\n if (error) {\n return failCallback(reply);\n }\n\n // State-cookie binding: the query state must echo the Lax cookie value.\n const cookieState = getCookies(request)[COOKIE_OAUTH_STATE];\n if (!state || !cookieState || state !== cookieState) {\n return failCallback(reply);\n }\n\n // One-shot consume — unknown / forged / replayed states resolve to null.\n const record = await oauthState.consume(state);\n if (!record) {\n return failCallback(reply);\n }\n\n // Mix-up guard: the URL :id must match the provider that minted the state.\n if (record.providerId !== id) {\n return failCallback(reply);\n }\n\n // Cross-tenant guard: the callback Host must resolve to the same tenant\n // the state was minted for (when the Host is subdomain-routed at all).\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const callbackTenant = tenantResolver.resolve(host);\n if (callbackTenant !== null && callbackTenant !== record.tenantId) {\n return failCallback(reply);\n }\n\n // The provider is the source of truth from the KV record (not the URL).\n const provider = providers.get(record.providerId);\n if (!isRedirectProvider(provider)) {\n return failCallback(reply);\n }\n\n const redirectUri = callbackUrl(request, record.providerId, cookieOpts.cookieSecure);\n\n try {\n // DD-6: reuse the standard login path. The provider's authenticate()\n // receives the callback bundle and resolves it to an email; the service\n // does email→user→session→tokens exactly as for password login.\n const result = await userAuthService.login(\n {\n providerId: record.providerId,\n input: { code, state, session: record.session, redirectUri },\n },\n record.tenantId,\n { ip: request.ip, userAgent: request.headers['user-agent'] as string | undefined },\n );\n\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n\n clearOAuthStateCookie(reply, cookieOpts);\n return reply.redirect(record.returnTo, 302);\n } catch (err) {\n if (err instanceof AuthError) {\n return failCallback(reply);\n }\n throw err;\n }\n },\n );\n}\n","/**\n * @module @kb-labs/gateway-app/auth/user-routes\n *\n * HTTP route registrar for the user-auth flow (ADR-0020, Phase 1.16).\n *\n * Endpoints registered here:\n * GET /auth/me (user cookie or machine Bearer)\n * GET /auth/providers\n * POST /auth/login\n * POST /auth/logout\n * GET /auth/permissions\n * POST /auth/activate\n * POST /auth/password/change\n * GET /auth/sessions\n * POST /auth/sessions/revoke-all (before /:fam/revoke to avoid param capture)\n * POST /auth/sessions/:fam/revoke\n * POST /auth/invites\n * POST /auth/invites/:id/revoke\n * GET /auth/invites\n * GET /auth/users\n * POST /auth/users/:id/disable\n * POST /auth/users/:id/enable\n *\n * NOTE: POST /auth/refresh is NOT registered here. Instead,\n * createUserRefreshFn() returns a handler that registerAuthRoutes() wires\n * as its `userExt.userRefreshFn` option — avoiding duplicate route registration.\n *\n * Security invariants:\n * - All state-mutating cookie-auth endpoints validate CSRF (double-submit).\n * - Admin endpoints check PDP via PERMISSIONS enum (CD-7).\n * - /auth/me never returns role/group fields.\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type {\n UsersStore,\n SessionsStore,\n InvitesStore,\n ProviderRegistry,\n IPolicyDecisionPoint,\n JwtConfig,\n SessionResult,\n RateLimiter,\n TenantResolver,\n OAuthStateStore,\n} from '@kb-labs/gateway-auth';\nimport { registerOAuthRoutes } from './oauth-routes.js';\nimport { AuthError, verifyCsrfToken } from '@kb-labs/gateway-auth';\nimport { PERMISSIONS } from '@kb-labs/core-contracts';\nimport type { UserAuthContext } from './user-auth-middleware.js';\nimport {\n setSessionCookies,\n clearSessionCookies,\n COOKIE_REFRESH,\n COOKIE_CSRF,\n type CookieOptions,\n} from './user-cookies.js';\n\nexport type { UserAuthContext };\n\n// ── Service interface (matches createUserAuthService return type) ──────────────\n\n/**\n * Minimal interface for the UserAuthService used by user-routes.\n *\n * Mirrors the actual return type of createUserAuthService from gateway-auth.\n * login() takes (input: LoginInput, tenantId, deviceCtx) — three separate args.\n * refresh() / logout() take the full refresh JWT string (service verifies internally).\n * activate() takes { activationToken, password, deviceCtx }.\n */\nexport interface UserAuthServiceForRoutes {\n login(\n input: { providerId: string; input: unknown },\n tenantId: string,\n deviceCtx: { ip?: string; userAgent?: string },\n ): Promise<SessionResult>;\n refresh(refreshToken: string): Promise<SessionResult>;\n logout(refreshToken: string): Promise<void>;\n changePassword(input: {\n userId: string;\n currentFamilyId: string;\n currentPassword: string;\n newPassword: string;\n }): Promise<void>;\n activate(input: {\n activationToken: string;\n password: string;\n deviceCtx: { ip?: string; userAgent?: string };\n }): Promise<SessionResult>;\n}\n\nexport interface UserAuthRouteDeps {\n userAuthService: UserAuthServiceForRoutes;\n users: UsersStore;\n sessions: SessionsStore;\n invites: InvitesStore;\n providers: ProviderRegistry;\n pdp: IPolicyDecisionPoint;\n /** Resolves the tenant from the Host header — used to prevent tenantId bypass via body. */\n tenantResolver: TenantResolver;\n cookieOpts: CookieOptions;\n accessTtlSec: number;\n refreshTtlSec: number;\n inviteTtlMs: number;\n jwtConfig: JwtConfig;\n /** Fixed-window rate limiter for login/activate endpoints. Optional — rate limiting\n * is silently skipped when absent (e.g. unit tests without IKVStore). */\n rateLimiter?: RateLimiter;\n /** Rate limit thresholds (defaults applied when rateLimiter is present). */\n authRateLimit?: {\n loginPerIpPerMinute: number;\n loginPerEmailPerMinute: number;\n };\n /** OAuth state store. When present, the redirect/OAuth routes are registered. */\n oauthState?: OAuthStateStore;\n /** Per-IP callback rate-limit for the OAuth callback (defaults applied when set). */\n oauthCallbackPerIpPerMinute?: number;\n}\n\n// ── Cookie helpers ────────────────────────────────────────────────────────────\n\nfunction getCookies(request: FastifyRequest): Record<string, string | undefined> {\n return (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies ?? {};\n}\n\n// ── Auth/CSRF helpers ─────────────────────────────────────────────────────────\n\n/** Returns the UserAuthContext or sends 401 and returns null. */\nfunction requireUser(request: FastifyRequest, reply: FastifyReply): UserAuthContext | null {\n const ctx = request.userAuthContext;\n if (!ctx) {\n void reply.code(401).send({ error: 'Unauthorized', message: 'No active user session' });\n return null;\n }\n return ctx;\n}\n\n/**\n * Validates double-submit CSRF token.\n * Returns true if valid; sends 403 and returns false otherwise.\n */\nfunction checkCsrf(request: FastifyRequest, reply: FastifyReply): boolean {\n const cookieVal = getCookies(request)[COOKIE_CSRF];\n const headerVal = request.headers['x-csrf-token'];\n const headerStr = typeof headerVal === 'string' ? headerVal : undefined;\n if (!verifyCsrfToken(cookieVal, headerStr)) {\n void reply.code(403).send({ error: 'Forbidden', message: 'CSRF token mismatch' });\n return false;\n }\n return true;\n}\n\n// ── Cookie TTL helpers ────────────────────────────────────────────────────────\n\n/** Derives MaxAge for access cookie from SessionResult. */\nfunction accessTtl(result: SessionResult): number {\n return result.access.expiresInSec;\n}\n\n/** Derives MaxAge for refresh cookie from SessionResult. */\nfunction refreshTtl(result: SessionResult): number {\n return result.refresh.expiresInSec;\n}\n\n// ── User refresh handler factory ──────────────────────────────────────────────\n\n/**\n * Creates the user-cookie refresh handler for POST /auth/refresh.\n *\n * Pass this as `userExt.userRefreshFn` to `registerAuthRoutes()`. Returns\n * true if the cookie was present and the response has been sent. Returns\n * false (no response sent) if there is no refresh cookie, letting the\n * machine body-refresh path take over.\n */\nexport function createUserRefreshFn(\n deps: Pick<UserAuthRouteDeps, 'userAuthService' | 'cookieOpts'>,\n): (request: FastifyRequest, reply: FastifyReply) => Promise<boolean> {\n const { userAuthService, cookieOpts } = deps;\n\n return async function userRefreshFn(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<boolean> {\n const refreshCookie = getCookies(request)[COOKIE_REFRESH];\n if (!refreshCookie) {return false;}\n\n try {\n const result = await userAuthService.refresh(refreshCookie);\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n void reply.send({ ok: true });\n return true;\n } catch (err) {\n if (err instanceof AuthError) {\n clearSessionCookies(reply, cookieOpts);\n void reply.code(401).send({ error: 'Unauthorized', message: 'Session expired or revoked' });\n return true;\n }\n throw err;\n }\n };\n}\n\n// ── Route registrar ───────────────────────────────────────────────────────────\n\nexport function registerUserAuthRoutes(app: FastifyInstance, deps: UserAuthRouteDeps): void {\n const { userAuthService, users, sessions, invites, providers, pdp, tenantResolver, cookieOpts, inviteTtlMs, rateLimiter, authRateLimit, oauthState, oauthCallbackPerIpPerMinute } = deps;\n // Apply config defaults so the rest of the handler can use them without null-checks.\n const authRateLimitCfg = { loginPerIpPerMinute: 10, loginPerEmailPerMinute: 5, ...authRateLimit };\n\n // Redirect/OAuth routes are only registered when an OAuth state store is wired\n // (DD-5). Without a (shared) KV-backed store there is nowhere to hold the\n // per-attempt `state` binding, so the flow is simply unavailable.\n if (oauthState) {\n registerOAuthRoutes(app, {\n userAuthService,\n providers,\n tenantResolver,\n oauthState,\n cookieOpts,\n rateLimiter,\n oauthCallbackPerIpPerMinute,\n });\n }\n\n // ── GET /auth/me ────────────────────────────────────────────────────────────\n // Handles both user cookie auth and machine Bearer auth. User takes precedence.\n // NOTE: Removed from registerAuthRoutes to avoid duplicate route registration.\n app.get('/auth/me', {\n schema: { tags: ['Auth'], summary: 'Get profile for the authenticated caller' },\n }, async (request, reply) => {\n // User cookie auth (takes precedence)\n if (request.userAuthContext) {\n const { userId, tenantId } = request.userAuthContext;\n const user = await users.getById(userId);\n if (!user) {\n return reply.code(404).send({ error: 'Not found', message: 'User record not found' });\n }\n // Never expose role/group fields — return minimal public fields only.\n return reply.send({ userId: user.userId, email: user.email, tenantId });\n }\n\n // Machine Bearer auth (includes LOCAL_ADMIN, injected when auth.enabled=false —\n // see B-023). Studio's PublicUser type (studio/app/src/auth/auth-provider.tsx)\n // requires `email`/`tenantId`; a machine context has neither concept, so we\n // derive Studio-displayable stand-ins from userId/namespaceId rather than\n // omitting the fields — omitting them broke Studio's header/status bar under\n // `--local` installs, where every request runs as this machine context.\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Not authenticated' });\n }\n return reply.send({\n userId: auth.userId,\n namespaceId: auth.namespaceId,\n email: auth.userId,\n tenantId: auth.namespaceId,\n });\n });\n\n // ── GET /auth/providers ─────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES in middleware.ts).\n app.get('/auth/providers', {\n schema: { tags: ['Auth'], summary: 'List registered identity providers' },\n }, async (_request, reply) => {\n return reply.send({ providers: providers.list() });\n });\n\n // ── POST /auth/login ────────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES). Rate-limited per-IP + per-email via fixed-window counter.\n app.post<{ Body: { email?: string; password?: string; providerId?: string; tenantId?: string } }>('/auth/login', {\n schema: { tags: ['Auth'], summary: 'Login with email/password (sets session cookies)' },\n }, async (request, reply) => {\n const { email, password, providerId, tenantId: bodyTenantId } = request.body ?? {};\n if (typeof email !== 'string' || !email) {\n return reply.code(400).send({ error: 'Bad Request', message: 'email is required' });\n }\n if (typeof password !== 'string' || !password) {\n return reply.code(400).send({ error: 'Bad Request', message: 'password is required' });\n }\n\n // Derive tenantId — Host header is authoritative (set by nginx in production).\n // bodyTenantId is accepted only as a fallback when the Host doesn't resolve to\n // a valid tenant (e.g. direct gateway access: localhost:4000, CI without nginx).\n // This prevents tenant isolation bypass via body in subdomain deployments.\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const hostTenant = tenantResolver.resolve(host);\n const tenantId = hostTenant ?? bodyTenantId ?? '';\n\n // Rate-limit GATE (peek, non-incrementing) BEFORE invoking the provider,\n // which runs a bcrypt compare (~300ms CPU at cost 12). Once the per-IP or\n // per-email failure window is exhausted we reject here, so a flood of\n // requests past the limit costs ~0 CPU instead of one bcrypt each. The\n // counter is only INCREMENTED on an actual auth failure (catch block\n // below) — successful logins never count, so legitimate users are never\n // throttled.\n if (rateLimiter) {\n const emailNorm = email.toLowerCase().trim();\n const [ipPeek, emailPeek] = await Promise.all([\n rateLimiter.peek(`rl:login:ip:${request.ip}`, { max: authRateLimitCfg.loginPerIpPerMinute, windowMs: 60_000 }),\n rateLimiter.peek(`rl:login:email:${emailNorm}`, { max: authRateLimitCfg.loginPerEmailPerMinute, windowMs: 60_000 }),\n ]);\n if (!ipPeek.allowed || !emailPeek.allowed) {\n const retryAfter = !ipPeek.allowed\n ? ipPeek.retryAfterSec\n : (!emailPeek.allowed ? emailPeek.retryAfterSec : 60);\n reply.header('Retry-After', String(retryAfter));\n return reply.code(429).send({ error: 'Too Many Requests', message: 'Rate limit exceeded', retryAfterSec: retryAfter });\n }\n }\n\n try {\n const result = await userAuthService.login(\n { providerId: providerId ?? 'email-password', input: { email, password } },\n tenantId,\n { ip: request.ip, userAgent: request.headers['user-agent'] as string | undefined },\n );\n\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n\n return reply.send({ ok: true });\n } catch (err) {\n // CD-8: always return identical shape regardless of failure reason.\n if (err instanceof AuthError) {\n // Rate-limit only on failed authentication attempts. Counting only\n // failures prevents false positives for legitimate users while still\n // protecting against brute-force attacks.\n if (rateLimiter) {\n const perIpMax = authRateLimitCfg.loginPerIpPerMinute;\n const perEmailMax = authRateLimitCfg.loginPerEmailPerMinute;\n const emailNorm = email.toLowerCase().trim();\n\n const [ipResult, emailResult] = await Promise.all([\n rateLimiter.check(`rl:login:ip:${request.ip}`, { max: perIpMax, windowMs: 60_000 }),\n rateLimiter.check(`rl:login:email:${emailNorm}`, { max: perEmailMax, windowMs: 60_000 }),\n ]);\n\n if (!ipResult.allowed || !emailResult.allowed) {\n const retryAfter = !ipResult.allowed\n ? ipResult.retryAfterSec\n : (!emailResult.allowed ? emailResult.retryAfterSec : 60);\n reply.header('Retry-After', String(retryAfter));\n return reply.code(429).send({ error: 'Too Many Requests', message: 'Rate limit exceeded', retryAfterSec: retryAfter });\n }\n }\n return reply.code(401).send({ error: 'invalid_credentials' });\n }\n throw err;\n }\n });\n\n // ── POST /auth/logout ───────────────────────────────────────────────────────\n // Cookie-auth, CSRF required.\n app.post('/auth/logout', {\n schema: { tags: ['Auth'], summary: 'Logout and clear session cookies' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const refreshCookie = getCookies(request)[COOKIE_REFRESH];\n if (refreshCookie) {\n // The service verifies the token internally — just pass it through.\n await userAuthService.logout(refreshCookie).catch(() => {});\n }\n\n clearSessionCookies(reply, cookieOpts);\n return reply.send({ ok: true });\n });\n\n // ── GET /auth/permissions ───────────────────────────────────────────────────\n // Cookie-auth. Returns the caller's effective permissions via PDP (CD-3).\n app.get('/auth/permissions', {\n schema: { tags: ['Auth'], summary: 'List permissions for the authenticated user' },\n }, async (request, reply) => {\n // User cookie auth takes precedence — enumerate via PDP for per-user RBAC.\n if (request.userAuthContext) {\n const ctx = request.userAuthContext;\n const permissions = await pdp.enumeratePermissions({\n userId: ctx.userId,\n tenantId: ctx.tenantId,\n type: 'user',\n });\n return reply.send({ permissions });\n }\n\n // Machine Bearer auth (including LOCAL_ADMIN when auth is disabled).\n // Permissions are already embedded in the machine AuthContext.\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'No active session' });\n }\n return reply.send({ permissions: auth.permissions });\n });\n\n // ── POST /auth/activate ─────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES). Creates user from invite + auto-logs in.\n app.post<{ Body: { token?: string; password?: string } }>('/auth/activate', {\n schema: { tags: ['Auth'], summary: 'Activate invite and create account (auto-login)' },\n }, async (request, reply) => {\n const { token, password } = request.body ?? {};\n if (typeof token !== 'string' || !token) {\n return reply.code(400).send({ error: 'Bad Request', message: 'token is required' });\n }\n if (typeof password !== 'string' || !password) {\n return reply.code(400).send({ error: 'Bad Request', message: 'password is required' });\n }\n\n try {\n const result = await userAuthService.activate({\n activationToken: token,\n password,\n deviceCtx: {\n ip: request.ip,\n userAgent: request.headers['user-agent'] as string | undefined,\n },\n });\n\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n\n return reply.send({ ok: true });\n } catch (err) {\n if (err instanceof AuthError) {\n const code = (err as AuthError).code;\n if (code === 'unknown_invite') {\n // 401 Unauthorized: token not found (garbage, never issued, or swept by TTL).\n // Use error:'invalid_invite' so the activate-page shows the user-friendly\n // \"This invite link is invalid or expired\" message (same as 422 path).\n return reply.code(401).send({ error: 'invalid_invite', message: 'Invalid or expired invite' });\n }\n if (code === 'invalid_invite') {\n // 422 Unprocessable Entity: the token was found but is expired or already consumed.\n // The client (activate-page) maps error:'invalid_invite' to the\n // user-friendly \"This invite link is invalid or expired\" message.\n return reply.code(422).send({ error: 'invalid_invite', message: 'Invalid or expired invite' });\n }\n return reply.code(400).send({ error: 'Bad Request', message: err.message });\n }\n throw err;\n }\n });\n\n // ── POST /auth/password/change ──────────────────────────────────────────────\n // Cookie-auth, CSRF required.\n app.post<{ Body: { currentPassword?: string; newPassword?: string } }>('/auth/password/change', {\n schema: { tags: ['Auth'], summary: 'Change password (revokes all other sessions)' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const { currentPassword, newPassword } = request.body ?? {};\n if (!currentPassword || !newPassword) {\n return reply.code(400).send({\n error: 'Bad Request',\n message: 'currentPassword and newPassword are required',\n });\n }\n\n try {\n await userAuthService.changePassword({\n userId: ctx.userId,\n currentFamilyId: ctx.familyId,\n currentPassword,\n newPassword,\n });\n return reply.send({ ok: true });\n } catch (err) {\n if (err instanceof AuthError) {\n const code = (err as AuthError).code;\n if (code === 'invalid_current_password') {\n return reply.code(400).send({ error: 'Bad Request', message: 'Current password is incorrect' });\n }\n if (code === 'weak_password') {\n return reply.code(400).send({ error: 'Bad Request', message: err.message });\n }\n }\n throw err;\n }\n });\n\n // ── GET /auth/sessions ──────────────────────────────────────────────────────\n // Cookie-auth. Lists all session families for the authenticated user.\n app.get('/auth/sessions', {\n schema: { tags: ['Auth'], summary: 'List active sessions for the authenticated user' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n\n const families = await sessions.listFamiliesByUser(ctx.userId);\n return reply.send({\n sessions: families.map((f) => ({\n familyId: f.familyId,\n createdAt: f.createdAt,\n lastUsedAt: f.lastUsedAt,\n userAgent: f.userAgent,\n ipFirst: f.ipFirst,\n isCurrent: f.familyId === ctx.familyId,\n })),\n });\n });\n\n // ── POST /auth/sessions/revoke-all ──────────────────────────────────────────\n // Registered BEFORE /:fam/revoke to prevent param capture.\n // Cookie-auth, CSRF required.\n app.post('/auth/sessions/revoke-all', {\n schema: { tags: ['Auth'], summary: 'Revoke all sessions except the current one' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n await sessions.revokeAllUserSessionsExcept(ctx.userId, ctx.familyId);\n return reply.send({ ok: true });\n });\n\n // ── POST /auth/sessions/:fam/revoke ─────────────────────────────────────────\n // Cookie-auth, CSRF required.\n app.post<{ Params: { fam: string } }>('/auth/sessions/:fam/revoke', {\n schema: { tags: ['Auth'], summary: 'Revoke a specific session family' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const { fam } = request.params;\n\n // Ownership check — only allow revoking own sessions.\n const ownFamilies = await sessions.listFamiliesByUser(ctx.userId);\n if (!ownFamilies.some((f) => f.familyId === fam)) {\n return reply.code(404).send({ error: 'Not found', message: 'Session not found' });\n }\n\n await sessions.revokeFamily(fam);\n return reply.send({ ok: true });\n });\n\n // ── Admin permission helper ───────────────────────────────────────────────\n\n /** Checks the given permission; sends 401 or 403 and returns false on failure. */\n async function requirePermission(\n request: FastifyRequest,\n reply: FastifyReply,\n permission: string,\n ): Promise<boolean> {\n const ctx = requireUser(request, reply);\n if (!ctx) {return false;}\n\n const decision = await pdp.check(\n { userId: ctx.userId, tenantId: ctx.tenantId, type: 'user' },\n permission,\n );\n\n if (!decision.allow) {\n void reply.code(403).send({ error: 'Forbidden', message: `Permission denied: ${permission}` });\n return false;\n }\n return true;\n }\n\n // ── POST /auth/invites ──────────────────────────────────────────────────────\n app.post<{ Body: { email?: string; groupId?: string; ttlMs?: number } }>('/auth/invites', {\n schema: { tags: ['Auth'], summary: 'Create an invite for a new user (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.INVITES_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n const { email, groupId, ttlMs: bodyTtlMs } = request.body ?? {};\n if (!email || !groupId) {\n return reply.code(400).send({ error: 'Bad Request', message: 'email and groupId are required' });\n }\n\n // Allow callers to specify a custom TTL (e.g., short-lived invites for testing\n // AUTH-14). If not provided or invalid, fall back to the server default.\n const effectiveTtlMs =\n typeof bodyTtlMs === 'number' && bodyTtlMs > 0 ? bodyTtlMs : inviteTtlMs;\n\n const result = await invites.createInvite({\n email,\n tenantId: ctx.tenantId,\n groupId: groupId as 'tenant-admin' | 'tenant-member',\n createdBy: ctx.userId,\n ttlMs: effectiveTtlMs,\n });\n\n const host = typeof request.headers.host === 'string' ? request.headers.host : 'localhost';\n const protocol = cookieOpts.cookieSecure ? 'https' : 'http';\n const activationUrl = `${protocol}://${host}/activate?token=${result.activationToken}`;\n\n return reply.code(201).send({ inviteId: result.inviteId, activationUrl });\n });\n\n // ── POST /auth/invites/:id/revoke ────────────────────────────────────────────\n app.post<{ Params: { id: string } }>('/auth/invites/:id/revoke', {\n schema: { tags: ['Auth'], summary: 'Revoke a pending invite (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.INVITES_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n // Tenant-ownership guard: only revoke invites belonging to the admin's\n // tenant. Without this an admin of tenant A could revoke tenant B's invite\n // by guessing the id. 404 to avoid cross-tenant existence leakage.\n const invite = await invites.findById(request.params.id);\n if (!invite || invite.tenantId !== ctx.tenantId) {\n return reply.code(404).send({ error: 'Not found', message: 'Invite not found' });\n }\n\n await invites.revoke(request.params.id);\n return reply.send({ ok: true });\n });\n\n // ── GET /auth/invites ────────────────────────────────────────────────────────\n app.get('/auth/invites', {\n schema: { tags: ['Auth'], summary: 'List invites for the tenant (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.INVITES_READ))) {return;}\n\n const ctx = request.userAuthContext!;\n const all = await invites.listByTenant(ctx.tenantId);\n return reply.send({ invites: all });\n });\n\n // ── GET /auth/users ──────────────────────────────────────────────────────────\n app.get('/auth/users', {\n schema: { tags: ['Auth'], summary: 'List users for the tenant (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.USERS_READ))) {return;}\n\n const ctx = request.userAuthContext!;\n const all = await users.listByTenant(ctx.tenantId);\n return reply.send({\n users: all.map((u) => ({\n userId: u.userId,\n email: u.email,\n tenantId: u.tenantId,\n status: u.status,\n })),\n });\n });\n\n // ── POST /auth/users/:id/disable ────────────────────────────────────────────\n // CD-1: user-auth-middleware checks user.status on every request, so this\n // takes effect immediately without waiting for token expiry.\n app.post<{ Params: { id: string } }>('/auth/users/:id/disable', {\n schema: { tags: ['Auth'], summary: 'Disable a user account (immediate via CD-1)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.USERS_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n const { id } = request.params;\n const target = await users.getById(id);\n // Tenant-ownership guard: an admin may only act on users in their own\n // tenant. requirePermission only proves \"you are an admin of ctx.tenantId\",\n // not that the target belongs there. Return 404 (not 403) so we don't leak\n // the existence of users in other tenants.\n if (!target || target.tenantId !== ctx.tenantId) {\n return reply.code(404).send({ error: 'Not found', message: 'User not found' });\n }\n\n await users.setStatus(id, 'disabled');\n await sessions.revokeAllUserSessions(id);\n\n return reply.send({ ok: true });\n });\n\n // ── POST /auth/users/:id/enable ─────────────────────────────────────────────\n app.post<{ Params: { id: string } }>('/auth/users/:id/enable', {\n schema: { tags: ['Auth'], summary: 'Re-enable a disabled user account' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.USERS_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n const { id } = request.params;\n const target = await users.getById(id);\n // Tenant-ownership guard (see /disable). 404 to avoid cross-tenant leakage.\n if (!target || target.tenantId !== ctx.tenantId) {\n return reply.code(404).send({ error: 'Not found', message: 'User not found' });\n }\n\n await users.setStatus(id, 'active');\n return reply.send({ ok: true });\n });\n}\n","/**\n * @module gateway-app/execute/execution-registry\n *\n * Tracks active executions with AbortController for cancellation.\n *\n * Lifecycle:\n * 1. POST /execute → registry.register(executionId, ...) → AbortSignal\n * 2. POST /execute/:id/cancel → registry.cancel(executionId, reason) → abort()\n * 3. Execution completes or aborted → registry.remove(executionId)\n *\n * Also supports host disconnect: cancelByHost() aborts all executions\n * dispatched to a host that went offline.\n */\n\nimport type { CancellationReason } from '@kb-labs/core-contracts';\n\nexport interface ActiveExecution {\n executionId: string;\n requestId: string;\n namespaceId: string;\n hostId: string;\n pluginId: string;\n handlerRef: string;\n controller: AbortController;\n startedAt: number;\n cancelledReason?: CancellationReason;\n}\n\nexport class ExecutionRegistry {\n private executions = new Map<string, ActiveExecution>();\n\n /** Register a new execution. Returns AbortSignal to wire into the dispatch. */\n register(entry: Omit<ActiveExecution, 'controller' | 'startedAt'>): AbortSignal {\n const controller = new AbortController();\n this.executions.set(entry.executionId, {\n ...entry,\n controller,\n startedAt: Date.now(),\n });\n return controller.signal;\n }\n\n /** Cancel an execution by ID. Returns true if found and aborted. */\n cancel(executionId: string, reason: CancellationReason): boolean {\n const entry = this.executions.get(executionId);\n if (!entry) { return false; }\n if (entry.controller.signal.aborted) { return false; }\n\n entry.cancelledReason = reason;\n entry.controller.abort(reason);\n return true;\n }\n\n /** Remove a completed/cancelled execution. */\n remove(executionId: string): void {\n this.executions.delete(executionId);\n }\n\n /** Get an active execution. */\n get(executionId: string): ActiveExecution | undefined {\n return this.executions.get(executionId);\n }\n\n /** Cancel all executions dispatched to a host (on host disconnect). */\n cancelByHost(hostId: string, reason: CancellationReason): string[] {\n const cancelled: string[] = [];\n for (const entry of this.executions.values()) {\n if (entry.hostId === hostId && !entry.controller.signal.aborted) {\n entry.cancelledReason = reason;\n entry.controller.abort(reason);\n cancelled.push(entry.executionId);\n }\n }\n return cancelled;\n }\n\n /** Number of active executions. */\n get size(): number {\n return this.executions.size;\n }\n}\n\n/** Singleton — shared across Gateway process. */\nexport const executionRegistry = new ExecutionRegistry();\n","/**\n * @module gateway-app/clients/subscription-registry\n *\n * Tracks which client connections are subscribed to which executions.\n * Gateway broadcasts ExecutionEvents to all subscribers of an execution.\n *\n * Lifecycle:\n * - client sends client:subscribe → subscribe(connectionId, executionId)\n * - client sends client:unsubscribe → unsubscribe(connectionId, executionId)\n * - execution emits event → broadcast(executionId, event) → all subscribers\n * - client disconnects → removeConnection(connectionId) → cleanup\n *\n * The initiator of POST /api/v1/execute is NOT auto-subscribed here —\n * they receive events inline via ndjson stream. This registry is for\n * secondary observers joining an in-flight execution.\n */\n\nimport type { WebSocket } from '@fastify/websocket';\nimport type { ExecutionEventMessage } from '@kb-labs/gateway-contracts';\n\nexport interface ISubscriptionRegistry {\n subscribe(connectionId: string, executionId: string): void;\n unsubscribe(connectionId: string, executionId: string): void;\n getSubscribers(executionId: string): ReadonlySet<string>;\n getSubscriptions(connectionId: string): ReadonlySet<string>;\n /** Called on client disconnect. Returns executionIds that now have zero subscribers. */\n removeConnection(connectionId: string): string[];\n broadcast(executionId: string, event: ExecutionEventMessage): void;\n}\n\nexport class SubscriptionRegistry implements ISubscriptionRegistry {\n /** executionId → Set<connectionId> */\n private readonly byExecution = new Map<string, Set<string>>();\n /** connectionId → Set<executionId> */\n private readonly byConnection = new Map<string, Set<string>>();\n /** connectionId → WebSocket (for sending events) */\n private readonly sockets = new Map<string, WebSocket>();\n\n /** Register a WebSocket for a connection. Must be called before subscribe(). */\n registerSocket(connectionId: string, socket: WebSocket): void {\n this.sockets.set(connectionId, socket);\n }\n\n /** Remove a connection's socket on disconnect. */\n removeSocket(connectionId: string): void {\n this.sockets.delete(connectionId);\n }\n\n subscribe(connectionId: string, executionId: string): void {\n let executionSubs = this.byExecution.get(executionId);\n if (!executionSubs) {\n executionSubs = new Set();\n this.byExecution.set(executionId, executionSubs);\n }\n executionSubs.add(connectionId);\n\n let connectionSubs = this.byConnection.get(connectionId);\n if (!connectionSubs) {\n connectionSubs = new Set();\n this.byConnection.set(connectionId, connectionSubs);\n }\n connectionSubs.add(executionId);\n }\n\n unsubscribe(connectionId: string, executionId: string): void {\n this.byExecution.get(executionId)?.delete(connectionId);\n this.byConnection.get(connectionId)?.delete(executionId);\n\n // GC empty sets\n if (this.byExecution.get(executionId)?.size === 0) {\n this.byExecution.delete(executionId);\n }\n if (this.byConnection.get(connectionId)?.size === 0) {\n this.byConnection.delete(connectionId);\n }\n }\n\n getSubscribers(executionId: string): ReadonlySet<string> {\n return this.byExecution.get(executionId) ?? new Set();\n }\n\n getSubscriptions(connectionId: string): ReadonlySet<string> {\n return this.byConnection.get(connectionId) ?? new Set();\n }\n\n removeConnection(connectionId: string): string[] {\n const subscriptions = this.byConnection.get(connectionId);\n if (!subscriptions) {\n this.sockets.delete(connectionId);\n return [];\n }\n\n const orphaned: string[] = [];\n for (const executionId of subscriptions) {\n const subs = this.byExecution.get(executionId);\n if (subs) {\n subs.delete(connectionId);\n if (subs.size === 0) {\n this.byExecution.delete(executionId);\n orphaned.push(executionId);\n }\n }\n }\n\n this.byConnection.delete(connectionId);\n this.sockets.delete(connectionId);\n return orphaned;\n }\n\n broadcast(executionId: string, event: ExecutionEventMessage): void {\n const subscribers = this.byExecution.get(executionId);\n if (!subscribers || subscribers.size === 0) { return; }\n\n const payload = JSON.stringify(event);\n for (const connectionId of subscribers) {\n const socket = this.sockets.get(connectionId);\n if (socket && socket.readyState === socket.OPEN) {\n socket.send(payload);\n }\n }\n }\n\n get connectionCount(): number {\n return this.byConnection.size;\n }\n\n get subscriptionCount(): number {\n let total = 0;\n for (const subs of this.byExecution.values()) {\n total += subs.size;\n }\n return total;\n }\n}\n\n/** Singleton — shared across Gateway process. */\nexport const subscriptionRegistry = new SubscriptionRegistry();\n","/**\n * @module gateway-app/execute/errors\n *\n * Shared error types for execution pipeline.\n */\n\nimport type { CancellationReason } from '@kb-labs/core-contracts';\n\n/**\n * Thrown when an execution is cancelled (CC2).\n * Caught by routes.ts to emit execution:cancelled + execution:done(130).\n */\nexport class CancelledError extends Error {\n readonly reason: CancellationReason;\n\n constructor(reason: CancellationReason) {\n super(`Execution cancelled: ${reason}`);\n this.name = 'CancelledError';\n this.reason = reason;\n }\n}\n","/**\n * @module gateway-app/execute/retry-executor\n *\n * Level 2 retry wrapper for execution dispatch (CC3).\n *\n * Wraps a dispatch function with configurable retry + exponential backoff.\n * Emits execution:retry events between attempts so clients see progress.\n * Respects AbortSignal — cancels immediately, no retry after abort.\n *\n * Each attempt is raced against the AbortSignal so that a cancelled\n * execution doesn't block on a hung dispatcher call.\n */\n\nimport type { ExecutionRetryConfig, CancellationReason } from '@kb-labs/core-contracts';\nimport type { ExecutionEventMessage } from '@kb-labs/gateway-contracts';\nimport { CancelledError } from './errors.js';\n\nconst DEFAULTS: Required<ExecutionRetryConfig> = {\n maxAttempts: 1,\n initialDelayMs: 1000,\n backoffMultiplier: 2,\n maxDelayMs: 30_000,\n onlyRetryable: true,\n};\n\nexport interface RetryContext {\n executionId: string;\n requestId: string;\n signal: AbortSignal;\n config: ExecutionRetryConfig | undefined;\n /** Emit event to client stream (and WS subscribers via routes.ts). */\n write: (event: ExecutionEventMessage) => void;\n}\n\n/**\n * Execute dispatch function with retry + abort-race logic.\n *\n * - maxAttempts=1 (default) → single call, raced against signal.\n * - maxAttempts>1 → retry loop with backoff, each attempt raced against signal.\n */\nexport async function executeWithRetry<T>(\n ctx: RetryContext,\n dispatch: () => Promise<T>,\n): Promise<T> {\n const cfg = { ...DEFAULTS, ...ctx.config };\n const maxAttempts = Math.max(1, cfg.maxAttempts);\n\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n if (ctx.signal.aborted) {\n throw new CancelledError(ctx.signal.reason as CancellationReason);\n }\n\n try {\n return await raceAbort(ctx.signal, dispatch());\n } catch (err) {\n // Cancellation is never retried\n if (err instanceof CancelledError) { throw err; }\n\n lastError = err instanceof Error ? err : new Error(String(err));\n\n // Last attempt — propagate error\n if (attempt >= maxAttempts) { break; }\n\n // Check if error is retryable\n const classified = classifyError(err);\n if (cfg.onlyRetryable && !classified.retryable) { break; }\n\n // Backoff delay\n const delay = Math.min(\n cfg.initialDelayMs * Math.pow(cfg.backoffMultiplier, attempt - 1),\n cfg.maxDelayMs,\n );\n\n ctx.write({\n type: 'execution:retry',\n requestId: ctx.requestId,\n executionId: ctx.executionId,\n attempt,\n maxAttempts,\n delayMs: delay,\n error: classified.message,\n } satisfies ExecutionEventMessage);\n\n await interruptibleDelay(delay, ctx.signal);\n }\n }\n\n throw lastError ?? new Error('executeWithRetry: no attempts made');\n}\n\n// ── Internals ──\n\n/**\n * Race a promise against an AbortSignal.\n */\nfunction raceAbort<T>(signal: AbortSignal, promise: Promise<T>): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(new CancelledError(signal.reason as CancellationReason));\n }\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(new CancelledError(signal.reason as CancellationReason));\n signal.addEventListener('abort', onAbort, { once: true });\n\n promise.then(\n (v) => { signal.removeEventListener('abort', onAbort); resolve(v); },\n (e) => { signal.removeEventListener('abort', onAbort); reject(e); },\n );\n });\n}\n\n/**\n * Sleep interruptible by AbortSignal.\n */\nfunction interruptibleDelay(ms: number, signal: AbortSignal): Promise<void> {\n if (signal.aborted) {\n return Promise.reject(new CancelledError(signal.reason as CancellationReason));\n }\n\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(new CancelledError(signal.reason as CancellationReason));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\ninterface ClassifiedError {\n code: string;\n message: string;\n retryable: boolean;\n}\n\nfunction classifyError(err: unknown): ClassifiedError {\n if (!(err instanceof Error)) {\n return { code: 'UNKNOWN', message: String(err), retryable: false };\n }\n\n const msg = err.message;\n\n // Transport / network — retryable\n if (msg.includes('ECONNREFUSED') || msg.includes('ECONNRESET') ||\n msg.includes('ETIMEDOUT') || msg.includes('timed out') ||\n msg.includes('503') || msg.includes('Service Unavailable')) {\n return { code: 'TRANSPORT_ERROR', message: msg, retryable: true };\n }\n\n // Host went offline — retryable (may reconnect)\n if (msg.includes('Host not connected')) {\n return { code: 'HOST_UNAVAILABLE', message: msg, retryable: true };\n }\n\n // Everything else — not retryable\n return { code: 'HANDLER_ERROR', message: msg, retryable: false };\n}\n","/**\n * @module gateway-app/execute/routes\n *\n * POST /api/v1/execute — Execute handler via Gateway with ndjson streaming.\n * POST /api/v1/execute/:executionId/cancel — Cancel an active execution.\n *\n * Response: Transfer-Encoding: chunked, Content-Type: application/x-ndjson\n * Each line = JSON ExecutionEvent.\n *\n * Integrates:\n * CC2 — Cancellation via ExecutionRegistry + AbortController\n * CC3 — Retry via executeWithRetry (exponential backoff, retryable errors)\n * CC5 — Broadcast to WS subscribers via SubscriptionRegistry\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport { randomUUID } from 'node:crypto';\nimport { ExecuteRequestSchema, type ExecutionEventMessage } from '@kb-labs/gateway-contracts';\nimport { logDiagnosticEvent, type ILogger } from '@kb-labs/core-platform';\nimport type { CancellationReason } from '@kb-labs/core-contracts';\nimport { globalDispatcher } from '../hosts/dispatcher.js';\nimport { executionRegistry } from './execution-registry.js';\nimport { subscriptionRegistry } from '../clients/subscription-registry.js';\nimport { executeWithRetry } from './retry-executor.js';\nimport { CancelledError } from './errors.js';\n\nexport function registerExecuteRoutes(app: FastifyInstance, logger: ILogger): void {\n /**\n * POST /api/v1/execute\n * hide: true — uses ndjson chunked streaming via reply.raw, incompatible with OpenAPI response schema\n */\n app.post('/api/v1/execute', { schema: { tags: ['Execute'], summary: 'Execute a plugin handler', hide: true } }, async (request: FastifyRequest, reply: FastifyReply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const parsed = ExecuteRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const { pluginId, handlerRef, exportName, input, timeoutMs } = parsed.data;\n const executionId = randomUUID();\n const requestId = randomUUID();\n const startTime = Date.now();\n\n logger.info('Execute request received', {\n executionId,\n pluginId,\n handlerRef,\n namespaceId: auth.namespaceId,\n });\n\n // Resolve host with 'execution' capability\n const hostId = globalDispatcher.firstHostWithCapability(auth.namespaceId, 'execution');\n if (!hostId) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.execution.dispatch',\n level: 'warn',\n reasonCode: 'execution_host_unavailable',\n message: 'No execution host connected for namespace',\n outcome: 'failed',\n serviceId: 'gateway',\n evidence: {\n namespaceId: auth.namespaceId,\n pluginId,\n handlerRef,\n },\n });\n return reply.code(503).send({\n error: 'No execution host connected',\n hint: 'Ensure a RuntimeServer is running and connected to Gateway',\n namespaceId: auth.namespaceId,\n });\n }\n\n // Register in execution registry (CC2)\n const signal = executionRegistry.register({\n executionId,\n requestId,\n namespaceId: auth.namespaceId,\n hostId,\n pluginId,\n handlerRef,\n });\n\n // Auto-cancel on client disconnect.\n // reply.raw 'close' fires when connection drops before response finishes.\n // Check writableFinished to distinguish mid-stream disconnect from normal completion.\n reply.raw.on('close', () => {\n if (!reply.raw.writableFinished && !signal.aborted) {\n executionRegistry.cancel(executionId, 'disconnect');\n }\n });\n\n // Hijack response for ndjson streaming\n reply.raw.writeHead(200, {\n 'Content-Type': 'application/x-ndjson',\n 'Transfer-Encoding': 'chunked',\n 'Cache-Control': 'no-cache',\n 'X-Execution-Id': executionId,\n });\n // Flush headers immediately so the client can see X-Execution-Id before any events\n reply.raw.flushHeaders();\n\n // Write typed event to initiator ndjson stream + broadcast to WS subscribers (CC5)\n const writeEvent = (event: ExecutionEventMessage): void => {\n const payload = JSON.stringify(event) + '\\n';\n if (!reply.raw.writableEnded) {\n reply.raw.write(payload);\n }\n subscriptionRegistry.broadcast(executionId, event);\n };\n\n try {\n // Dispatch with retry + abort-race (CC2 + CC3)\n // TODO: read retry config from platform config when available\n const result = await executeWithRetry(\n { executionId, requestId, signal, config: undefined, write: writeEvent },\n () => globalDispatcher.call(\n auth.namespaceId,\n hostId,\n 'execution',\n 'execute',\n [{ pluginId, handlerRef, exportName, input, executionId, requestId, timeoutMs }],\n ),\n );\n\n writeEvent({\n type: 'execution:done',\n requestId,\n executionId,\n exitCode: 0,\n durationMs: Date.now() - startTime,\n metadata: { result: result as Record<string, unknown> },\n });\n } catch (err) {\n if (err instanceof CancelledError) {\n writeEvent({\n type: 'execution:cancelled',\n requestId,\n executionId,\n reason: err.reason ?? 'user',\n durationMs: Date.now() - startTime,\n });\n\n writeEvent({\n type: 'execution:done',\n requestId,\n executionId,\n exitCode: 130,\n durationMs: Date.now() - startTime,\n });\n } else {\n const message = err instanceof Error ? err.message : String(err);\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.execution.dispatch',\n level: 'error',\n reasonCode: 'execution_dispatch_failed',\n message: 'Gateway execution dispatch failed',\n outcome: 'failed',\n error: err instanceof Error ? err : new Error(String(err)),\n serviceId: 'gateway',\n evidence: {\n namespaceId: auth.namespaceId,\n executionId,\n requestId,\n pluginId,\n handlerRef,\n hostId,\n },\n });\n\n writeEvent({\n type: 'execution:error',\n requestId,\n executionId,\n code: 'EXECUTION_FAILED',\n message,\n retryable: false,\n });\n\n writeEvent({\n type: 'execution:done',\n requestId,\n executionId,\n exitCode: 1,\n durationMs: Date.now() - startTime,\n });\n }\n } finally {\n executionRegistry.remove(executionId);\n if (!reply.raw.writableEnded) {\n reply.raw.end();\n }\n }\n });\n\n /**\n * POST /api/v1/execute/:executionId/cancel\n */\n app.post('/api/v1/execute/:executionId/cancel', { schema: { tags: ['Execute'], summary: 'Cancel an active execution' } }, async (request: FastifyRequest, reply: FastifyReply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const { executionId } = request.params as { executionId: string };\n const body = request.body as { reason?: string } | undefined;\n const reason = (body?.reason ?? 'user') as CancellationReason;\n\n const execution = executionRegistry.get(executionId);\n if (!execution) {\n return reply.code(404).send({ error: 'Execution not found or already completed' });\n }\n\n if (execution.namespaceId !== auth.namespaceId) {\n return reply.code(403).send({ error: 'Forbidden — execution belongs to another namespace' });\n }\n\n const cancelled = executionRegistry.cancel(executionId, reason);\n\n logger.info('Cancel request processed', {\n executionId,\n reason,\n cancelled,\n namespaceId: auth.namespaceId,\n });\n\n return reply.code(cancelled ? 200 : 409).send({\n executionId,\n status: cancelled ? 'cancelled' : 'already_cancelled',\n reason,\n });\n });\n}\n","/**\n * @module AI Gateway — OpenAI-compatible LLM endpoint.\n *\n * Exposes `POST /api/v1/llm/chat/completions` using OpenAI ChatCompletion format.\n * Model field is a tier abstraction (small/medium/large) — never a literal model name.\n * All calls go through the platform LLM chain: QueuedLLM → AnalyticsLLM → LLMRouter → adapter.\n */\nimport type { FastifyInstance } from 'fastify';\nimport { platform } from '@kb-labs/core-runtime';\nimport type {\n ILLM,\n ILogger,\n LLMMessage,\n LLMToolCallOptions,\n LLMTool,\n ILLMRouter,\n LLMTier,\n} from '@kb-labs/core-platform';\nimport {\n ChatCompletionRequestSchema,\n type ChatCompletionRequest,\n type ChatCompletionResponse,\n type ChatCompletionChunk,\n} from '@kb-labs/gateway-contracts';\n\n// ── Tier resolution ───────────────────────────────────────────────────────\n\nfunction isLLMRouter(llm: ILLM): llm is ILLM & ILLMRouter {\n return typeof (llm as any).resolveAdapter === 'function';\n}\n\n/**\n * Resolve tier to a concrete ILLM adapter via LLMRouter.\n * If no router (single-adapter setup), returns platform.llm directly.\n */\nasync function resolveLLMForTier(tier: LLMTier): Promise<ILLM | undefined> {\n const llm = platform.llm;\n if (!llm) {return undefined;}\n\n if (isLLMRouter(llm)) {\n const binding = await llm.resolveAdapter({ tier });\n return binding.adapter;\n }\n\n // Single adapter — ignore tier, return as-is\n return llm;\n}\n\n// ── Route registration ────────────────────────────────────────────────────\n\n/**\n * Register AI Gateway routes on the given Fastify scope.\n * The scope is expected to have the auth middleware already applied.\n */\nexport function registerLLMGatewayRoutes(app: FastifyInstance, logger: ILogger): void {\n // hide: true — can stream SSE (text/event-stream), incompatible with OpenAPI response schema\n app.post('/api/v1/llm/chat/completions', { schema: { tags: ['LLM'], summary: 'OpenAI-compatible chat completions', hide: true } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const parsed = ChatCompletionRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({\n error: {\n message: 'Bad Request',\n type: 'invalid_request_error',\n code: null,\n param: null,\n },\n issues: parsed.error.issues,\n });\n }\n\n const req = parsed.data;\n const requestId = `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n // Resolve tier to LLM adapter\n const llm = await resolveLLMForTier(req.model);\n if (!llm) {\n return reply.code(503).send({\n error: {\n message: `LLM not available for tier \"${req.model}\"`,\n type: 'server_error',\n code: null,\n param: null,\n },\n });\n }\n\n logger.info('AI Gateway request', {\n requestId,\n tier: req.model,\n stream: req.stream,\n messageCount: req.messages.length,\n hasTools: !!req.tools?.length,\n tenantId: auth.namespaceId,\n });\n\n try {\n if (req.stream) {\n return await handleStreamingRequest(reply, llm, req, requestId, logger);\n }\n return await handleCompletionRequest(reply, llm, req, requestId);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error('AI Gateway error', error, { requestId, tier: req.model });\n return reply.code(500).send({\n error: {\n message: 'Internal server error',\n type: 'server_error',\n code: null,\n param: null,\n },\n });\n }\n });\n}\n\n// ── Non-streaming handler ─────────────────────────────────────────────────\n\nasync function handleCompletionRequest(\n reply: any,\n llm: ILLM,\n req: ChatCompletionRequest,\n requestId: string,\n) {\n const messages = toILLMMessages(req);\n const startTime = Date.now();\n const hasTools = req.tools && req.tools.length > 0;\n\n if (hasTools && llm.chatWithTools) {\n const tools = toILLMTools(req.tools!);\n const options: LLMToolCallOptions = {\n temperature: req.temperature,\n maxTokens: req.max_tokens,\n stop: normalizeStop(req.stop),\n tools,\n toolChoice: req.tool_choice as LLMToolCallOptions['toolChoice'],\n };\n\n const result = await llm.chatWithTools(messages, options);\n\n const toolCalls = result.toolCalls?.map((tc) => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.name,\n arguments: typeof tc.input === 'string' ? tc.input : JSON.stringify(tc.input),\n },\n }));\n\n const finishReason =\n result.stopReason === 'tool_use'\n ? ('tool_calls' as const)\n : result.stopReason === 'max_tokens'\n ? ('length' as const)\n : ('stop' as const);\n\n const response: ChatCompletionResponse = {\n id: requestId,\n object: 'chat.completion',\n created: Math.floor(startTime / 1000),\n model: req.model,\n choices: [\n {\n index: 0,\n message: {\n role: 'assistant',\n content: result.content || null,\n ...(toolCalls?.length ? { tool_calls: toolCalls } : {}),\n },\n finish_reason: finishReason,\n },\n ],\n usage: {\n prompt_tokens: result.usage.promptTokens,\n completion_tokens: result.usage.completionTokens,\n total_tokens: result.usage.promptTokens + result.usage.completionTokens,\n },\n };\n\n return reply.code(200).send(response);\n }\n\n // No tools — use simple complete()\n const systemPrompt = messages.find((m) => m.role === 'system')?.content;\n const userMessages = messages.filter((m) => m.role !== 'system');\n const prompt = userMessages.map((m) => m.content).join('\\n\\n');\n\n const result = await llm.complete(prompt, {\n systemPrompt,\n temperature: req.temperature,\n maxTokens: req.max_tokens,\n stop: normalizeStop(req.stop),\n });\n\n const response: ChatCompletionResponse = {\n id: requestId,\n object: 'chat.completion',\n created: Math.floor(startTime / 1000),\n model: req.model,\n choices: [\n {\n index: 0,\n message: { role: 'assistant', content: result.content },\n finish_reason: 'stop',\n },\n ],\n usage: {\n prompt_tokens: result.usage.promptTokens,\n completion_tokens: result.usage.completionTokens,\n total_tokens: result.usage.promptTokens + result.usage.completionTokens,\n },\n };\n\n return reply.code(200).send(response);\n}\n\n// ── Streaming handler ─────────────────────────────────────────────────────\n\nasync function handleStreamingRequest(\n reply: any,\n llm: ILLM,\n req: ChatCompletionRequest,\n requestId: string,\n logger: ILogger,\n) {\n const created = Math.floor(Date.now() / 1000);\n\n reply.raw.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'X-Request-Id': requestId,\n });\n reply.raw.flushHeaders();\n\n const writeChunk = (chunk: ChatCompletionChunk): void => {\n if (!reply.raw.writableEnded) {\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n };\n\n const writeDone = (): void => {\n if (!reply.raw.writableEnded) {\n reply.raw.write('data: [DONE]\\n\\n');\n reply.raw.end();\n }\n };\n\n try {\n // Initial role chunk\n writeChunk({\n id: requestId,\n object: 'chat.completion.chunk',\n created,\n model: req.model,\n choices: [{ index: 0, delta: { role: 'assistant' }, finish_reason: null }],\n });\n\n // Stream text from LLM\n const systemPrompt = req.messages.find((m) => m.role === 'system')?.content;\n const userMessages = req.messages.filter((m) => m.role !== 'system');\n const prompt = userMessages.map((m) => m.content).join('\\n\\n');\n\n for await (const text of llm.stream(prompt, {\n systemPrompt,\n temperature: req.temperature,\n maxTokens: req.max_tokens,\n stop: normalizeStop(req.stop),\n })) {\n writeChunk({\n id: requestId,\n object: 'chat.completion.chunk',\n created,\n model: req.model,\n choices: [{ index: 0, delta: { content: text }, finish_reason: null }],\n });\n }\n\n // Finish chunk\n writeChunk({\n id: requestId,\n object: 'chat.completion.chunk',\n created,\n model: req.model,\n choices: [{ index: 0, delta: {}, finish_reason: 'stop' }],\n });\n\n writeDone();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error('AI Gateway stream error', error, { requestId });\n if (!reply.raw.writableEnded) {\n reply.raw.write(\n `data: ${JSON.stringify({ error: { message: error.message, type: 'server_error' } })}\\n\\n`,\n );\n reply.raw.end();\n }\n }\n\n return reply;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction toILLMMessages(req: ChatCompletionRequest): LLMMessage[] {\n return req.messages.map((m) => {\n const msg: LLMMessage = { role: m.role, content: m.content };\n if (m.tool_call_id) {msg.toolCallId = m.tool_call_id;}\n if (m.tool_calls) {\n msg.toolCalls = m.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n input: safeJsonParse(tc.function.arguments),\n }));\n }\n return msg;\n });\n}\n\nfunction toILLMTools(tools: NonNullable<ChatCompletionRequest['tools']>): LLMTool[] {\n return tools.map((t) => ({\n name: t.function.name,\n description: t.function.description ?? '',\n inputSchema: t.function.parameters ?? {},\n }));\n}\n\nfunction normalizeStop(stop: string | string[] | undefined): string[] | undefined {\n if (!stop) {return undefined;}\n return Array.isArray(stop) ? stop : [stop];\n}\n\nfunction safeJsonParse(str: string): unknown {\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n","/**\n * @module Telemetry Ingestion — unified event collection endpoint.\n *\n * Exposes `POST /telemetry/v1/ingest` for external products to send events.\n * Events are written to platform analytics via IAnalytics.track().\n * Auth required — tenantId extracted from auth context.\n */\nimport type { FastifyInstance } from 'fastify';\nimport { platform } from '@kb-labs/core-runtime';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport {\n TelemetryIngestRequestSchema,\n type TelemetryIngestResponse,\n} from '@kb-labs/gateway-contracts';\n\n/**\n * Register telemetry ingestion routes on the given Fastify scope.\n * The scope is expected to have the auth middleware already applied.\n */\nexport function registerTelemetryRoutes(app: FastifyInstance, logger: ILogger): void {\n app.post('/telemetry/v1/ingest', { schema: { tags: ['Telemetry'], summary: 'Ingest telemetry events' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const parsed = TelemetryIngestRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({\n error: 'Bad Request',\n issues: parsed.error.issues,\n });\n }\n\n const analytics = platform.analytics;\n if (!analytics) {\n return reply.code(503).send({\n error: 'Analytics adapter not configured',\n });\n }\n\n const { events } = parsed.data;\n let accepted = 0;\n let rejected = 0;\n const errors: Array<{ index: number; message: string }> = [];\n\n for (let i = 0; i < events.length; i++) {\n const event = events[i]!;\n try {\n await analytics.track(event.type, {\n // Source attribution — who sent this event\n _source: event.source,\n _tenantId: auth.namespaceId,\n _ts: event.timestamp ?? new Date().toISOString(),\n // Tags as flat properties for indexing\n ...event.tags,\n // Free-form payload\n ...event.payload,\n });\n accepted++;\n } catch (err) {\n rejected++;\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ index: i, message });\n logger.warn('Telemetry event rejected', {\n index: i,\n type: event.type,\n source: event.source,\n error: message,\n });\n }\n }\n\n logger.info('Telemetry ingest', {\n tenantId: auth.namespaceId,\n accepted,\n rejected,\n totalEvents: events.length,\n });\n\n const response: TelemetryIngestResponse = {\n accepted,\n rejected,\n ...(errors.length > 0 ? { errors } : {}),\n };\n\n return reply.code(accepted > 0 ? 200 : 422).send(response);\n });\n}\n","/**\n * @module Unified Platform API — single dispatch for any adapter.\n *\n * Route: POST /platform/v1/{adapter}/{method}\n *\n * Provides a single entry point for all platform adapters (LLM, Cache,\n * VectorStore, Analytics, Storage, Embeddings, etc.). Adapter and method\n * come from URL params; arguments come from the request body.\n *\n * Security: only methods explicitly listed in ALLOWED_METHODS are callable.\n */\nimport type { FastifyInstance } from 'fastify';\nimport { platform } from '@kb-labs/core-runtime';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport {\n PlatformCallRequestSchema,\n type PlatformCallResponse,\n} from '@kb-labs/gateway-contracts';\n\n// ── Method allowlist ──────────────────────────────────────────────────────\n// Only methods listed here are callable via the Platform API.\n// Internal/lifecycle methods (setSource, shutdown, etc.) are NOT exposed.\n// Intentionally static — new methods must be added here explicitly;\n// dynamic derivation from the adapter list would bypass security review.\n\nconst ALLOWED_METHODS: Record<string, Set<string>> = {\n llm: new Set(['complete', 'stream', 'chatWithTools']),\n cache: new Set(['get', 'set', 'delete', 'clear']),\n vectorStore: new Set(['search', 'upsert', 'delete', 'count']),\n analytics: new Set(['track', 'identify', 'flush', 'getEvents', 'getStats', 'getDailyStats']),\n embeddings: new Set(['embed']),\n storage: new Set(['read', 'write', 'delete', 'list', 'exists']),\n eventBus: new Set(['publish', 'subscribe']),\n documentDatabase: new Set([\n 'find', 'findById', 'count',\n 'insertOne', 'insertMany',\n 'updateOne', 'updateMany', 'updateById',\n 'deleteMany', 'deleteById',\n 'bulkWrite',\n 'ensureCollection',\n 'ping',\n ]),\n kvStore: new Set([\n 'get', 'getMany',\n 'set', 'setMany', 'setIfNotExists',\n 'delete', 'exists',\n 'cas', 'incr',\n 'ttl', 'expire', 'persist',\n 'ping',\n ]),\n};\n\n// ── Adapter resolution ────────────────────────────────────────────────────\n\nfunction resolveAdapter(name: string): unknown | undefined {\n // Map URL param to platform property\n const adapterMap: Record<string, () => unknown> = {\n llm: () => platform.llm,\n cache: () => platform.cache,\n analytics: () => platform.analytics,\n vectorStore: () => platform.vectorStore,\n embeddings: () => platform.embeddings,\n storage: () => platform.storage,\n eventBus: () => platform.eventBus,\n documentDatabase: () => platform.documentDatabase,\n kvStore: () => platform.kvStore,\n };\n\n const getter = adapterMap[name];\n return getter ? getter() : undefined;\n}\n\n// ── Streaming detection ───────────────────────────────────────────────────\n\nfunction isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n Symbol.asyncIterator in (value as object)\n );\n}\n\n// ── Route registration ────────────────────────────────────────────────────\n\nexport function registerPlatformRoutes(app: FastifyInstance, logger: ILogger): void {\n // hide: true — can return SSE (text/event-stream) for streaming adapter calls, incompatible with OpenAPI response schema\n app.post<{ Params: { adapter: string; method: string } }>(\n '/platform/v1/:adapter/:method',\n { schema: { tags: ['Platform'], summary: 'Invoke a platform adapter method', hide: true } },\n async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const { adapter: adapterName, method: methodName } = request.params;\n\n // 1. Check adapter is in allowlist\n const allowedMethods = ALLOWED_METHODS[adapterName];\n if (!allowedMethods) {\n return reply.code(404).send({\n ok: false,\n error: { message: `Unknown adapter: \"${adapterName}\"`, code: 'ADAPTER_NOT_FOUND' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 2. Check method is allowed\n if (!allowedMethods.has(methodName)) {\n return reply.code(403).send({\n ok: false,\n error: { message: `Method \"${methodName}\" not allowed on adapter \"${adapterName}\"`, code: 'METHOD_NOT_ALLOWED' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 3. Resolve adapter instance\n const adapter = resolveAdapter(adapterName);\n if (!adapter) {\n return reply.code(503).send({\n ok: false,\n error: { message: `Adapter \"${adapterName}\" not configured`, code: 'ADAPTER_UNAVAILABLE' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 4. Check method exists on adapter\n const method = (adapter as Record<string, unknown>)[methodName];\n if (typeof method !== 'function') {\n return reply.code(501).send({\n ok: false,\n error: { message: `Method \"${methodName}\" not implemented on adapter \"${adapterName}\"`, code: 'METHOD_NOT_IMPLEMENTED' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 5. Parse args\n const parsed = PlatformCallRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({\n ok: false,\n error: { message: 'Invalid request body', code: 'VALIDATION_ERROR' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n const { args } = parsed.data;\n\n logger.info('Platform API call', {\n adapter: adapterName,\n method: methodName,\n argCount: args.length,\n tenantId: auth.namespaceId,\n });\n\n // 6. Execute\n const startTime = Date.now();\n\n try {\n const result = method.apply(adapter, args);\n\n // Handle async results\n const resolved = result instanceof Promise ? await result : result;\n\n // 7. Detect streaming response (e.g., llm.stream)\n if (isAsyncIterable(resolved)) {\n reply.raw.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n reply.raw.flushHeaders();\n\n for await (const chunk of resolved) {\n if (!reply.raw.writableEnded) {\n const data = typeof chunk === 'string' ? chunk : JSON.stringify(chunk);\n reply.raw.write(`data: ${data}\\n\\n`);\n }\n }\n\n if (!reply.raw.writableEnded) {\n reply.raw.write('data: [DONE]\\n\\n');\n reply.raw.end();\n }\n\n return reply;\n }\n\n // 8. Regular response\n const durationMs = Date.now() - startTime;\n return reply.code(200).send({\n ok: true,\n result: resolved,\n durationMs,\n } satisfies PlatformCallResponse);\n } catch (err) {\n const durationMs = Date.now() - startTime;\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error('Platform API error', error, {\n adapter: adapterName,\n method: methodName,\n tenantId: auth.namespaceId,\n });\n return reply.code(502).send({\n ok: false,\n error: { message: error.message, code: 'ADAPTER_ERROR' },\n durationMs,\n } satisfies PlatformCallResponse);\n }\n },\n );\n}\n","/**\n * @module gateway-app/docs/routes\n * Aggregated OpenAPI documentation endpoints.\n *\n * GET /openapi-merged.json — merged spec from all upstream services\n * GET /docs-all — Swagger UI pointing at the merged spec\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport { mergeOpenAPISpecs } from '@kb-labs/core-registry';\nimport type { ICache, IServiceTransport } from '@kb-labs/core-platform';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\n\nconst MERGED_CACHE_KEY = '__gateway_merged_openapi';\nconst MERGED_CACHE_TTL = 30_000; // 30 second cache\n\nexport function registerAggregatedDocsRoutes(\n app: FastifyInstance,\n config: GatewayConfig,\n serviceTransport: IServiceTransport,\n cache?: ICache,\n): void {\n const upstreamServiceIds = Object.values(config.upstreams).map((u) => u.serviceId);\n\n // Merged OpenAPI spec from all upstreams\n app.get('/openapi-merged.json', async (_req, reply) => {\n // Try cache first\n if (cache) {\n try {\n const hit = await cache.get<Record<string, unknown>>(MERGED_CACHE_KEY);\n if (hit) {\n return reply.send(hit);\n }\n } catch { /* cache miss */ }\n }\n\n // Fetch all upstream specs in parallel via transport\n const results = await Promise.allSettled(\n upstreamServiceIds.map((serviceId) =>\n serviceTransport.call(serviceId, {\n path: '/openapi.json',\n signal: AbortSignal.timeout(3000),\n }).then((r) => r.payload),\n ),\n );\n\n const specs = results\n .filter((r): r is PromiseFulfilledResult<unknown> => r.status === 'fulfilled')\n .map((r) => r.value);\n\n const merged = mergeOpenAPISpecs(specs as Parameters<typeof mergeOpenAPISpecs>[0]);\n\n // Cache result\n if (cache) {\n try {\n await cache.set(MERGED_CACHE_KEY, merged as unknown as Record<string, unknown>, MERGED_CACHE_TTL);\n } catch { /* cache write failure is non-critical */ }\n }\n\n return reply.send(merged);\n });\n\n // Second Swagger UI pointing at merged spec\n // Registered last so /docs (gateway-native) is already bound at this point\n app.register(async function docsAll(scope) {\n const swaggerUi = await import('@fastify/swagger-ui');\n await scope.register(swaggerUi.default ?? swaggerUi, {\n routePrefix: '/docs-all',\n uiConfig: {\n url: '/openapi-merged.json',\n docExpansion: 'list',\n deepLinking: true,\n },\n });\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport type { ICache } from '@kb-labs/core-platform';\nimport type { HostDescriptor, HostRegistration, IHostStore } from '@kb-labs/gateway-contracts';\n\nexport interface HostRegisterResult {\n descriptor: HostDescriptor;\n machineToken: string;\n}\n\n/**\n * Host Registry — coordinates cache (hot) and store (cold) layers.\n *\n * - Cache: online/offline status, connections, heartbeat (transient)\n * - Store: host descriptors, tokens (durable, survives restarts)\n *\n * Write path: store.save() + cache.set()\n * Read path: cache.get() ?? store.get() → cache warm\n */\nconst DEFAULT_RECONNECT_GRACE_MS = 10_000;\n\nexport class HostRegistry {\n private readonly graceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly reconnectGraceMs: number;\n\n constructor(\n private readonly cache: ICache,\n private readonly store?: IHostStore,\n options?: { reconnectGraceMs?: number },\n ) {\n this.reconnectGraceMs = options?.reconnectGraceMs ?? DEFAULT_RECONNECT_GRACE_MS;\n }\n\n /**\n * Restore hosts from persistent store into cache on startup.\n * All restored hosts start as offline — live status comes from WS connections.\n *\n * Also resets any stale online/reconnecting hosts in cache to offline,\n * since no WebSocket connections survive a Gateway restart.\n */\n async restore(): Promise<number> {\n // 1. Reset stale hosts in cache (covers Redis cache surviving restarts)\n await this.resetStaleHosts();\n\n // 2. Restore from store if available\n if (!this.store) {return 0;}\n const hosts = await this.store.listAll();\n for (const host of hosts) {\n const offline = { ...host, status: 'offline' as const, connections: [] as string[] };\n const cacheKey = this.hostKey(host.namespaceId, host.hostId);\n await this.cache.set(cacheKey, offline);\n await this.store.save(offline);\n await this.addToIndex(host.namespaceId, host.hostId);\n }\n return hosts.length;\n }\n\n /**\n * Reset all hosts in cache to offline.\n * Called on startup — no WS connections exist yet, so nothing should be online.\n * Uses namespace index maintained in cache to discover all namespaces.\n */\n private async resetStaleHosts(): Promise<void> {\n const namespaces = await this.cache.get<string[]>('host:namespaces') ?? ['default'];\n for (const ns of namespaces) {\n const hostIds = await this.cache.get<string[]>(`host:index:${ns}`) ?? [];\n for (const hostId of hostIds) {\n const host = await this.cache.get<HostDescriptor>(this.hostKey(ns, hostId));\n if (host && (host.status === 'online' || host.status === 'reconnecting')) {\n await this.cache.set(this.hostKey(ns, hostId), {\n ...host, status: 'offline', connections: [],\n });\n }\n }\n }\n }\n\n async register(reg: HostRegistration): Promise<HostRegisterResult> {\n const hostId = `host_${randomUUID().replace(/-/g, '').slice(0, 24)}`;\n const machineToken = randomUUID();\n const now = Date.now();\n\n const descriptor: HostDescriptor = {\n hostId,\n name: reg.name,\n namespaceId: reg.namespaceId,\n capabilities: reg.capabilities,\n status: 'offline',\n lastSeen: now,\n connections: [],\n hostType: reg.hostType,\n createdAt: now,\n updatedAt: now,\n };\n\n // Persist to store (durable)\n if (this.store) {\n await this.store.save(descriptor);\n await this.store.saveToken(machineToken, hostId, reg.namespaceId);\n }\n\n // Write to cache (hot)\n await this.cache.set(this.hostKey(reg.namespaceId, hostId), descriptor);\n await this.cache.set(this.tokenKey(machineToken), { hostId, namespaceId: reg.namespaceId });\n await this.addToIndex(reg.namespaceId, hostId);\n\n return { descriptor, machineToken };\n }\n\n async setOnline(hostId: string, namespaceId: string, connectionId: string): Promise<void> {\n const host = await this.getFromCache(hostId, namespaceId);\n if (!host) {return;}\n\n // Cancel grace timer if reconnecting\n const graceKey = `${namespaceId}:${hostId}`;\n const graceTimer = this.graceTimers.get(graceKey);\n if (graceTimer) {\n clearTimeout(graceTimer);\n this.graceTimers.delete(graceKey);\n }\n\n const updated = {\n ...host,\n status: 'online' as const,\n lastSeen: Date.now(),\n connections: [connectionId],\n };\n await this.cache.set(this.hostKey(namespaceId, hostId), updated);\n if (this.store) {await this.store.save(updated);}\n }\n\n async setOffline(hostId: string, namespaceId: string, connectionId: string): Promise<void> {\n const host = await this.getFromCache(hostId, namespaceId);\n if (!host) {return;}\n const connections = host.connections.filter((c) => c !== connectionId);\n\n if (connections.length > 0) {\n // Other connections still active — stay online\n await this.cache.set(this.hostKey(namespaceId, hostId), {\n ...host, status: 'online', lastSeen: Date.now(), connections,\n });\n return;\n }\n\n // Last connection gone — enter grace period (reconnecting)\n const reconnecting = {\n ...host, status: 'reconnecting' as const, lastSeen: Date.now(), connections: [] as string[],\n };\n await this.cache.set(this.hostKey(namespaceId, hostId), reconnecting);\n if (this.store) {await this.store.save(reconnecting);}\n\n // Cancel any existing grace timer for this host\n const graceKey = `${namespaceId}:${hostId}`;\n const existing = this.graceTimers.get(graceKey);\n if (existing) {clearTimeout(existing);}\n\n // After grace period, mark truly offline\n this.graceTimers.set(graceKey, setTimeout(async () => {\n this.graceTimers.delete(graceKey);\n const current = await this.getFromCache(hostId, namespaceId);\n if (current?.status === 'reconnecting') {\n const offline = { ...current, status: 'offline' as const, lastSeen: Date.now() };\n await this.cache.set(this.hostKey(namespaceId, hostId), offline);\n if (this.store) {await this.store.save(offline);}\n }\n }, this.reconnectGraceMs));\n }\n\n async heartbeat(hostId: string, namespaceId: string): Promise<void> {\n const host = await this.getFromCache(hostId, namespaceId);\n if (!host) {return;}\n await this.cache.set(this.hostKey(namespaceId, hostId), { ...host, lastSeen: Date.now() });\n }\n\n async get(hostId: string, namespaceId: string): Promise<HostDescriptor | null> {\n // Try cache first (hot)\n const cached = await this.cache.get<HostDescriptor>(this.hostKey(namespaceId, hostId));\n if (cached) {return cached;}\n\n // Fall through to store (cold)\n if (!this.store) {return null;}\n const stored = await this.store.get(hostId, namespaceId);\n if (!stored) {return null;}\n\n // Warm cache\n await this.cache.set(this.hostKey(namespaceId, hostId), { ...stored, status: 'offline', connections: [] });\n await this.addToIndex(namespaceId, hostId);\n return { ...stored, status: 'offline', connections: [] };\n }\n\n async resolveToken(token: string): Promise<{ hostId: string; namespaceId: string } | null> {\n // Try cache first\n const cached = await this.cache.get<{ hostId: string; namespaceId: string }>(this.tokenKey(token));\n if (cached) {return cached;}\n\n // Fall through to store\n if (!this.store) {return null;}\n const stored = await this.store.resolveToken(token);\n if (!stored) {return null;}\n\n // Warm cache\n await this.cache.set(this.tokenKey(token), stored);\n return stored;\n }\n\n async list(namespaceId: string): Promise<HostDescriptor[]> {\n // Use store as authoritative source if available\n if (this.store) {\n const persisted = await this.store.list(namespaceId);\n // Enrich with live status from cache\n return Promise.all(\n persisted.map(async (host) => {\n const cached = await this.cache.get<HostDescriptor>(this.hostKey(namespaceId, host.hostId));\n return cached ?? { ...host, status: 'offline' as const, connections: [] };\n }),\n );\n }\n\n // Fallback: cache-only (no store)\n const indexKey = `host:index:${namespaceId}`;\n const hostIds = (await this.cache.get<string[]>(indexKey)) ?? [];\n const results = await Promise.all(\n hostIds.map((id) => this.cache.get<HostDescriptor>(this.hostKey(namespaceId, id))),\n );\n return results.filter((h): h is HostDescriptor => h !== null);\n }\n\n async deregister(hostId: string, namespaceId: string): Promise<boolean> {\n if (this.store) {\n const deleted = await this.store.delete(hostId, namespaceId);\n await this.cache.delete(this.hostKey(namespaceId, hostId));\n await this.removeFromIndex(namespaceId, hostId);\n return deleted;\n }\n // No persistent store — cache is the source of truth.\n const exists = !!(await this.cache.get<HostDescriptor>(this.hostKey(namespaceId, hostId)));\n await this.cache.delete(this.hostKey(namespaceId, hostId));\n await this.removeFromIndex(namespaceId, hostId);\n return exists;\n }\n\n async ensureRegistered(\n hostId: string,\n namespaceId: string,\n name: string,\n capabilities: HostDescriptor['capabilities'] = [],\n ): Promise<void> {\n const existing = await this.get(hostId, namespaceId);\n if (existing) {\n if (capabilities.length > 0 && JSON.stringify(existing.capabilities) !== JSON.stringify(capabilities)) {\n const updated = { ...existing, capabilities, updatedAt: Date.now() };\n if (this.store) {await this.store.save(updated);}\n await this.cache.set(this.hostKey(namespaceId, hostId), updated);\n }\n return;\n }\n\n const now = Date.now();\n const descriptor: HostDescriptor = {\n hostId,\n name,\n namespaceId,\n capabilities,\n status: 'offline',\n lastSeen: now,\n connections: [],\n createdAt: now,\n updatedAt: now,\n };\n\n if (this.store) {await this.store.save(descriptor);}\n await this.cache.set(this.hostKey(namespaceId, hostId), descriptor);\n await this.addToIndex(namespaceId, hostId);\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private hostKey(namespaceId: string, hostId: string): string {\n return `host:registry:${namespaceId}:${hostId}`;\n }\n\n private tokenKey(token: string): string {\n return `host:token:${token}`;\n }\n\n private async getFromCache(hostId: string, namespaceId: string): Promise<HostDescriptor | null> {\n return this.cache.get<HostDescriptor>(this.hostKey(namespaceId, hostId));\n }\n\n private async addToIndex(namespaceId: string, hostId: string): Promise<void> {\n const indexKey = `host:index:${namespaceId}`;\n const hostIds = (await this.cache.get<string[]>(indexKey)) ?? [];\n if (!hostIds.includes(hostId)) {\n await this.cache.set(indexKey, [...hostIds, hostId]);\n }\n // Track namespace for resetStaleHosts()\n const nsKey = 'host:namespaces';\n const namespaces = (await this.cache.get<string[]>(nsKey)) ?? [];\n if (!namespaces.includes(namespaceId)) {\n await this.cache.set(nsKey, [...namespaces, namespaceId]);\n }\n }\n\n private async removeFromIndex(namespaceId: string, hostId: string): Promise<void> {\n const indexKey = `host:index:${namespaceId}`;\n const hostIds = (await this.cache.get<string[]>(indexKey)) ?? [];\n await this.cache.set(indexKey, hostIds.filter((id) => id !== hostId));\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { WebSocket } from 'ws';\n\ninterface WsRequest {\n headers: { authorization?: string };\n url?: string;\n}\nimport { logDiagnosticEvent, type ICache, type ILogger } from '@kb-labs/core-platform';\nimport {\n HelloMessageSchema,\n AdapterCallMessageSchema,\n AdapterNameSchema,\n HostCapabilitySchema,\n SUPPORTED_PROTOCOL_VERSIONS,\n type HostCapability,\n type OutboundMessage,\n} from '@kb-labs/gateway-contracts';\nimport { AdaptiveBuffer } from '@kb-labs/gateway-core';\nimport { getClientByHostId, type JwtConfig } from '@kb-labs/gateway-auth';\nimport { HostRegistry } from './registry.js';\nimport { extractBearerToken, resolveToken } from '../auth/tokens.js';\nimport { globalDispatcher } from './dispatcher.js';\nimport { executionRegistry } from '../execute/execution-registry.js';\n\nconst HELLO_TIMEOUT_MS = 5_000;\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst HEARTBEAT_GRACE_MS = 10_000;\n\nfunction send(ws: WebSocket, msg: OutboundMessage): void {\n ws.send(JSON.stringify(msg));\n}\n\nexport function createWsHandler(\n cache: ICache,\n jwtConfig: JwtConfig,\n logger: ILogger,\n hostRegistry?: HostRegistry,\n) {\n const registry = hostRegistry ?? new HostRegistry(cache);\n const buffer = new AdaptiveBuffer(cache);\n\n return async function wsHandler(\n socket: WebSocket,\n request: WsRequest,\n ): Promise<void> {\n // 1. Auth — machine token required\n const token = extractBearerToken(request.headers.authorization);\n if (!token) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.auth',\n level: 'warn',\n reasonCode: 'websocket_auth_failed',\n message: 'Host WebSocket connection missing authorization token',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n });\n socket.close(1008, 'Missing Authorization header');\n return;\n }\n\n // 2. Start buffering hello BEFORE async auth to prevent race condition.\n // Client may send hello during await resolveToken — capture it immediately.\n let resolveHello!: (raw: Buffer) => void;\n let rejectHello!: (err: Error) => void;\n const helloRawPromise = new Promise<Buffer>((res, rej) => {\n resolveHello = res;\n rejectHello = rej;\n });\n // Consume rejection so early-return paths (e.g. token rejected before the\n // socket.once('close') listener fires) don't leak an unhandledRejection,\n // which BulkTransferHelper's process-wide uncaughtException handler would\n // escalate into process.exit(1), killing the gateway.\n helloRawPromise.catch(() => { /* awaited below or intentionally discarded */ });\n const helloTimeout = setTimeout(() => {\n socket.close(1008, 'Hello timeout');\n rejectHello(new Error('Hello timeout'));\n }, HELLO_TIMEOUT_MS);\n socket.once('message', (raw) => {\n clearTimeout(helloTimeout);\n resolveHello(raw as Buffer);\n });\n socket.once('close', () => {\n clearTimeout(helloTimeout);\n rejectHello(new Error('Socket closed before hello'));\n });\n\n const tokenEntry = await resolveToken(token, cache, jwtConfig);\n if (!tokenEntry || tokenEntry.type !== 'machine') {\n clearTimeout(helloTimeout);\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.auth',\n level: 'warn',\n reasonCode: 'websocket_auth_failed',\n message: 'Host WebSocket machine token rejected',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n });\n socket.close(1008, 'Invalid machine token');\n return;\n }\n\n const { userId: hostId, namespaceId } = tokenEntry;\n const connectionId = randomUUID();\n const sessionId = randomUUID();\n\n // 3. Process buffered hello (may already be resolved if client was fast)\n let protocolVersion: string | null = null;\n let helloCaps: string[] = [];\n\n const protocolVersions: readonly string[] = SUPPORTED_PROTOCOL_VERSIONS;\n\n try {\n const helloRaw = await helloRawPromise;\n const msg = HelloMessageSchema.parse(JSON.parse(helloRaw.toString()));\n\n if (!protocolVersions.includes(msg.protocolVersion)) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'websocket_protocol_unsupported',\n message: 'Host WebSocket protocol version is unsupported',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n protocolVersion: msg.protocolVersion,\n supportedVersions: [...SUPPORTED_PROTOCOL_VERSIONS],\n },\n });\n send(socket, {\n type: 'negotiate',\n supportedVersions: [...SUPPORTED_PROTOCOL_VERSIONS],\n });\n socket.close(1008, 'Unsupported protocol version');\n return;\n }\n\n protocolVersion = msg.protocolVersion;\n helloCaps = msg.capabilities ?? [];\n } catch (error) {\n const isTimeout = error instanceof Error && error.message === 'Hello timeout';\n if (isTimeout) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'websocket_hello_timeout',\n message: 'Host WebSocket hello timed out',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: { hostId, namespaceId },\n });\n } else if (!(error instanceof Error && error.message === 'Socket closed before hello')) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'websocket_handshake_invalid',\n message: 'Host WebSocket hello message is invalid',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: { hostId, namespaceId },\n });\n socket.close(1008, 'Invalid hello message');\n }\n return;\n }\n\n if (!protocolVersion) {return;}\n\n // 3. Resolve capabilities for dispatcher routing.\n //\n // Priority order:\n // 1. AuthStore clientRecord (JWT-registered via /auth/register) — authoritative\n // 2. HostRegistry descriptor (registered via /hosts/register) — authoritative\n // 3. Hello-message capabilities (static/dev tokens with no registry entry) — validated\n const clientRecord = await getClientByHostId(cache, hostId);\n const registryCaps: HostCapability[] = (clientRecord?.capabilities ?? []).flatMap((c) => {\n const r = HostCapabilitySchema.safeParse(c);\n return r.success ? [r.data] : [];\n });\n\n let capabilities: HostCapability[];\n if (clientRecord) {\n // JWT-registered host: use AuthStore capabilities only\n capabilities = registryCaps;\n } else {\n // Check HostRegistry for machine-token-registered hosts (/hosts/register)\n let existingDescriptor = null;\n try {\n existingDescriptor = await registry.get(hostId, namespaceId);\n } catch (err) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'registry_lookup_failed',\n message: 'Failed to look up host descriptor from registry, falling back to hello capabilities',\n outcome: 'failed',\n error: err instanceof Error ? err : new Error(String(err)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: { hostId, namespaceId },\n });\n }\n if (existingDescriptor && existingDescriptor.capabilities.length > 0) {\n capabilities = existingDescriptor.capabilities.flatMap((c) => {\n const r = HostCapabilitySchema.safeParse(c);\n return r.success ? [r.data] : [];\n });\n } else {\n // Static/dev token with no registry entry: accept validated hello capabilities\n capabilities = helloCaps.flatMap((c) => {\n const r = HostCapabilitySchema.safeParse(c);\n return r.success ? [r.data] : [];\n });\n }\n }\n\n await registry.ensureRegistered(hostId, namespaceId, clientRecord?.name ?? hostId, capabilities);\n\n // 4. Set online + register in dispatcher (with capabilities for routing) + send connected\n await registry.setOnline(hostId, namespaceId, connectionId);\n globalDispatcher.registerConnection(hostId, namespaceId, socket, capabilities);\n\n send(socket, {\n type: 'connected',\n protocolVersion,\n hostId,\n sessionId,\n });\n\n // 4. Flush buffered calls\n const buffered = await buffer.flush(hostId);\n for (const call of buffered) {\n send(socket, {\n type: 'call',\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n args: call.args,\n trace: { traceId: call.requestId, spanId: randomUUID() },\n });\n }\n\n // 5. Heartbeat watchdog\n let lastHeartbeat = Date.now();\n const heartbeatWatchdog = setInterval(async () => {\n const elapsed = Date.now() - lastHeartbeat;\n if (elapsed > HEARTBEAT_INTERVAL_MS + HEARTBEAT_GRACE_MS) {\n // Mark as degraded (don't close — allow recovery)\n const host = await registry.get(hostId, namespaceId);\n if (host && host.status !== 'degraded') {\n await cache.set(`host:registry:${namespaceId}:${hostId}`, {\n ...host,\n status: 'degraded',\n });\n }\n }\n }, HEARTBEAT_INTERVAL_MS);\n\n // 6. Message handler\n socket.on('message', async (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as { type: string; requestId?: string };\n\n switch (msg.type) {\n case 'heartbeat':\n lastHeartbeat = Date.now();\n await registry.heartbeat(hostId, namespaceId);\n send(socket, { type: 'ack' });\n break;\n\n case 'chunk':\n case 'result':\n case 'error':\n globalDispatcher.handleInbound(msg as { type: string; requestId?: string; data?: unknown; error?: unknown });\n break;\n\n case 'adapter:call':\n void handleAdapterCall(msg, socket, hostId, namespaceId);\n break;\n }\n } catch (error) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.message',\n level: 'warn',\n reasonCode: 'websocket_message_invalid',\n message: 'Host WebSocket message is malformed',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n },\n });\n }\n });\n\n // 7. Disconnect cleanup\n socket.on('close', async () => {\n clearInterval(heartbeatWatchdog);\n globalDispatcher.removeConnection(hostId, namespaceId);\n\n // Cancel all executions dispatched to this host (CC2)\n const cancelled = executionRegistry.cancelByHost(hostId, 'disconnect');\n if (cancelled.length > 0) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.disconnect',\n level: 'warn',\n reasonCode: 'execution_dispatch_failed',\n message: 'Host disconnected and active executions were cancelled',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n cancelledExecutions: cancelled.length,\n },\n });\n }\n\n await registry.setOffline(hostId, namespaceId, connectionId);\n });\n };\n\n /**\n * Handle adapter:call from Host — forward to REST API for platform service execution.\n * Flow: Host → WS adapter:call → Gateway → HTTP POST /api/v1/internal/adapter-call → REST API\n *\n * @see ADR-0051: Bidirectional Gateway Protocol\n */\n async function handleAdapterCall(\n msg: Record<string, unknown>,\n socket: WebSocket,\n hostId: string,\n namespaceId: string,\n ): Promise<void> {\n const requestId = msg['requestId'] as string;\n\n // 1. Validate message schema\n const parsed = AdapterCallMessageSchema.safeParse(msg);\n if (!parsed.success) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.adapter-call',\n level: 'warn',\n reasonCode: 'websocket_message_invalid',\n message: 'Host adapter call message is invalid',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n requestId,\n },\n });\n send(socket, {\n type: 'adapter:error',\n requestId: requestId ?? 'unknown',\n error: { code: 'INVALID_MESSAGE', message: parsed.error.message, retryable: false },\n });\n return;\n }\n\n const call = parsed.data;\n\n // 2. Validate adapter is in allowlist\n const adapterCheck = AdapterNameSchema.safeParse(call.adapter);\n if (!adapterCheck.success) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.adapter-call',\n level: 'warn',\n reasonCode: 'adapter_call_rejected',\n message: 'Host adapter call rejected by gateway allowlist',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n },\n });\n send(socket, {\n type: 'adapter:error',\n requestId: call.requestId,\n error: { code: 'ADAPTER_CALL_REJECTED', message: `Adapter not allowed: ${call.adapter}`, retryable: false },\n });\n return;\n }\n\n // 3. Forward to REST API\n const restApiUrl = process.env.REST_API_URL ?? 'http://localhost:5050';\n const internalSecret = process.env.GATEWAY_INTERNAL_SECRET ?? '';\n\n try {\n const response = await fetch(`${restApiUrl}/api/v1/internal/adapter-call`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-internal-secret': internalSecret,\n },\n body: JSON.stringify({\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n args: call.args,\n context: {\n ...call.context,\n namespaceId,\n hostId,\n },\n }),\n });\n\n const body = await response.json() as {\n ok: boolean;\n result?: unknown;\n error?: { code: string; message: string; retryable: boolean; details?: unknown };\n };\n\n if (body.ok) {\n send(socket, {\n type: 'adapter:response',\n requestId: call.requestId,\n result: body.result,\n });\n } else {\n send(socket, {\n type: 'adapter:error',\n requestId: call.requestId,\n error: body.error ?? { code: 'ADAPTER_ERROR', message: 'Unknown error', retryable: false },\n });\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.adapter-call',\n level: 'error',\n reasonCode: 'adapter_bridge_unavailable',\n message: 'Gateway could not reach REST adapter bridge',\n outcome: 'failed',\n error: err instanceof Error ? err : new Error(String(err)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n restApiUrl,\n },\n });\n send(socket, {\n type: 'adapter:error',\n requestId: call.requestId,\n error: { code: 'ADAPTER_CALL_TIMEOUT', message: `REST API unreachable: ${message}`, retryable: true },\n });\n }\n }\n}\n","/**\n * @module gateway-app/clients/ws-handler\n *\n * WebSocket handler for observer clients (CLI, Studio, IDE).\n * Endpoint: GET /clients/connect (requires Bearer JWT)\n *\n * Supports:\n * - client:subscribe — start receiving events for an executionId\n * - client:unsubscribe — stop receiving events\n * - client:cancel — cancel an execution (proxied to ExecutionRegistry)\n *\n * Auth: same Bearer JWT as HTTP endpoints (user or machine token, NOT host machine token).\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { WebSocket } from 'ws';\n\ninterface WsRequest {\n headers: { authorization?: string };\n url?: string;\n}\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { CancellationReason } from '@kb-labs/core-contracts';\nimport {\n ClientHelloSchema,\n ClientSubscribeSchema,\n ClientUnsubscribeSchema,\n ClientCancelSchema,\n CLIENT_PROTOCOL_VERSION,\n type ClientOutboundMessage,\n} from '@kb-labs/gateway-contracts';\nimport { type JwtConfig } from '@kb-labs/gateway-auth';\nimport { extractBearerToken, resolveToken } from '../auth/tokens.js';\nimport { executionRegistry } from '../execute/execution-registry.js';\nimport { subscriptionRegistry } from './subscription-registry.js';\n\nconst HELLO_TIMEOUT_MS = 5_000;\n\nfunction send(ws: WebSocket, msg: ClientOutboundMessage): void {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nexport function createClientWsHandler(cache: ICache, jwtConfig: JwtConfig, logger: ILogger) {\n return async function clientWsHandler(\n socket: WebSocket,\n request: WsRequest,\n ): Promise<void> {\n // 1. Auth — Bearer JWT required (user or machine token)\n const queryToken = new URL(request.url ?? '/', 'http://localhost').searchParams.get('access_token');\n const token = extractBearerToken(request.headers.authorization)\n ?? queryToken\n ?? null;\n\n if (!token) {\n socket.close(1008, 'Missing Authorization');\n return;\n }\n\n const authContext = await resolveToken(token, cache, jwtConfig);\n if (!authContext) {\n socket.close(1008, 'Invalid token');\n return;\n }\n\n const connectionId = randomUUID();\n\n // 2. Wait for client:hello (with timeout)\n let helloDone = false;\n\n await new Promise<void>((resolve, reject) => {\n const helloTimeout = setTimeout(() => {\n if (!helloDone) {\n helloDone = true;\n socket.close(1008, 'Hello timeout');\n reject(new Error('Hello timeout'));\n }\n }, HELLO_TIMEOUT_MS);\n\n socket.once('message', (raw) => {\n if (helloDone) { return; }\n helloDone = true;\n clearTimeout(helloTimeout);\n\n try {\n const msg = ClientHelloSchema.parse(JSON.parse(raw.toString()));\n void msg; // clientVersion logged below if needed\n resolve();\n } catch {\n socket.close(1008, 'Invalid hello message');\n reject(new Error('Invalid client:hello'));\n }\n });\n }).catch(() => {\n // socket already closed\n });\n\n if (!helloDone || socket.readyState !== socket.OPEN) { return; }\n\n // 3. Register connection\n subscriptionRegistry.registerSocket(connectionId, socket);\n\n send(socket, {\n type: 'client:connected',\n protocolVersion: CLIENT_PROTOCOL_VERSION,\n connectionId,\n });\n\n logger.debug('Client connected', { connectionId, namespaceId: authContext.namespaceId });\n\n // 4. Message handler\n socket.on('message', (raw) => {\n let parsed: { type: string };\n try {\n parsed = JSON.parse(raw.toString()) as { type: string };\n } catch {\n send(socket, {\n type: 'client:error',\n code: 'INVALID_MESSAGE',\n message: 'Malformed JSON',\n });\n return;\n }\n\n switch (parsed.type) {\n case 'client:subscribe': {\n const result = ClientSubscribeSchema.safeParse(parsed);\n if (!result.success) {\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: 'Invalid subscribe message' });\n return;\n }\n const { executionId } = result.data;\n\n // Verify execution exists and belongs to this namespace\n const execution = executionRegistry.get(executionId);\n if (!execution) {\n send(socket, { type: 'client:error', code: 'EXECUTION_NOT_FOUND', message: `Execution ${executionId} not found`, executionId });\n return;\n }\n if (execution.namespaceId !== authContext.namespaceId) {\n send(socket, { type: 'client:error', code: 'FORBIDDEN', message: 'Execution belongs to another namespace', executionId });\n return;\n }\n\n subscriptionRegistry.subscribe(connectionId, executionId);\n break;\n }\n\n case 'client:unsubscribe': {\n const result = ClientUnsubscribeSchema.safeParse(parsed);\n if (!result.success) {\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: 'Invalid unsubscribe message' });\n return;\n }\n subscriptionRegistry.unsubscribe(connectionId, result.data.executionId);\n break;\n }\n\n case 'client:cancel': {\n const result = ClientCancelSchema.safeParse(parsed);\n if (!result.success) {\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: 'Invalid cancel message' });\n return;\n }\n const { executionId, reason } = result.data;\n\n const execution = executionRegistry.get(executionId);\n if (!execution) {\n send(socket, { type: 'client:error', code: 'EXECUTION_NOT_FOUND', message: `Execution ${executionId} not found`, executionId });\n return;\n }\n if (execution.namespaceId !== authContext.namespaceId) {\n send(socket, { type: 'client:error', code: 'FORBIDDEN', message: 'Execution belongs to another namespace', executionId });\n return;\n }\n\n const cancelled = executionRegistry.cancel(executionId, (reason ?? 'user') as CancellationReason);\n if (!cancelled) {\n send(socket, { type: 'client:error', code: 'CANCEL_FAILED', message: 'Execution already completed or cancelled', executionId });\n }\n break;\n }\n\n default:\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: `Unknown message type: ${String(parsed.type)}` });\n }\n });\n\n // 5. Disconnect cleanup\n socket.on('close', () => {\n subscriptionRegistry.removeConnection(connectionId);\n logger.debug('Client disconnected', { connectionId });\n });\n };\n}\n","/**\n * @module gateway-app/ws/pump\n *\n * Bidirectional frame relay between a downstream client WebSocket and an\n * upstream WebSocket (opened over a Unix domain socket via the `ws+unix://`\n * scheme). Used by the gateway's WS dialer to proxy WebSocket traffic to\n * socket-bound services, which @fastify/http-proxy cannot do.\n *\n * Guarantees:\n * - client frames sent before the upstream is OPEN are buffered, then flushed\n * in order on 'open' (no lost frames);\n * - binary/text framing is preserved in both directions;\n * - close (code/reason) and error propagate to the other side exactly once.\n */\nimport type { RawData, WebSocket } from 'ws';\nimport type { ILogger } from '@kb-labs/core-platform';\n\nconst OPEN = 1; // WebSocket.OPEN\n\n/**\n * Close codes that must NOT be echoed back via close(code): 1005 (no status)\n * and 1006 (abnormal) are reserved and throw if passed to close().\n */\nfunction normalizeCloseCode(code: number | undefined): number | undefined {\n if (code === undefined || code === 1005 || code === 1006) {\n return undefined;\n }\n return code;\n}\n\nfunction safeClose(ws: WebSocket, code?: number, reason?: Buffer | string): void {\n if (ws.readyState === OPEN || ws.readyState === 0 /* CONNECTING */) {\n try {\n if (code === undefined) {\n ws.close();\n } else if (reason === undefined) {\n ws.close(code);\n } else {\n ws.close(code, reason);\n }\n } catch {\n /* already closing/closed — ignore */\n }\n }\n}\n\nexport function pumpBidirectional(client: WebSocket, upstream: WebSocket, logger: ILogger): void {\n const pending: Array<{ data: RawData; binary: boolean }> = [];\n let upstreamOpen = false;\n let closed = false;\n\n const closeBoth = (code?: number, reason?: Buffer | string): void => {\n if (closed) {\n return;\n }\n closed = true;\n safeClose(client, code, reason);\n safeClose(upstream, code, reason);\n };\n\n // client → upstream (buffer until upstream is OPEN)\n client.on('message', (data: RawData, isBinary: boolean) => {\n if (upstreamOpen && upstream.readyState === OPEN) {\n upstream.send(data, { binary: isBinary });\n } else {\n pending.push({ data, binary: isBinary });\n }\n });\n\n upstream.on('open', () => {\n upstreamOpen = true;\n for (const frame of pending) {\n if (upstream.readyState === OPEN) {\n upstream.send(frame.data, { binary: frame.binary });\n }\n }\n pending.length = 0;\n });\n\n // upstream → client\n upstream.on('message', (data: RawData, isBinary: boolean) => {\n if (client.readyState === OPEN) {\n client.send(data, { binary: isBinary });\n }\n });\n\n upstream.on('close', (code: number, reason: Buffer) => {\n closeBoth(normalizeCloseCode(code), reason);\n });\n client.on('close', (code: number, reason: Buffer) => {\n closeBoth(normalizeCloseCode(code), reason);\n });\n\n upstream.on('error', (err: Error) => {\n logger.warn('Upstream WS error', { error: err.message });\n closeBoth(1011);\n });\n client.on('error', (err: Error) => {\n logger.warn('Client WS error', { error: err.message });\n closeBoth(1011);\n });\n}\n","/**\n * @module gateway-app/ws/gateway-ws\n *\n * Unified WebSocket upgrade handler for the gateway.\n *\n * Intercepts upgrade requests BEFORE @fastify/http-proxy:\n * - Gateway-own WS paths (/hosts/connect, /clients/connect) → raw ws handlers\n * - Everything else → delegated to @fastify/http-proxy for upstream WS proxy\n *\n * This eliminates the conflict between @fastify/websocket and @fastify/http-proxy\n * which both try to attach 'upgrade' listeners and call assignSocket().\n */\n\nimport type { Server, IncomingMessage } from 'node:http';\nimport type { Duplex } from 'node:stream';\nimport { WebSocket, WebSocketServer } from 'ws';\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { JwtConfig } from '@kb-labs/gateway-auth';\nimport { createWsHandler } from '../hosts/ws-handler.js';\nimport { createClientWsHandler } from '../clients/ws-handler.js';\nimport type { HostRegistry } from '../hosts/registry.js';\nimport { pumpBidirectional } from './pump.js';\n\nconst GATEWAY_WS_PATHS = new Set(['/hosts/connect', '/clients/connect']);\n\n/**\n * A WS-enabled upstream reachable over a Unix domain socket. @fastify/http-proxy\n * cannot proxy WS upgrades over unix sockets, so the gateway dials these itself.\n */\nexport interface SocketWsUpstream {\n /** Gateway-side path prefix, e.g. \"/api/v1\". */\n prefix: string;\n /** Upstream-side prefix replacement (http-proxy rewritePrefix semantics). */\n rewritePrefix: string;\n /** Absolute unix socket path the upstream service is bound to. */\n socketPath: string;\n}\n\n/** Headers forwarded to the upstream WS handshake (auth, correlation, subprotocol). */\nconst FORWARDED_WS_HEADERS = [\n 'authorization',\n 'cookie',\n 'x-request-id',\n 'x-trace-id',\n 'sec-websocket-protocol',\n] as const;\n\n/**\n * Pick the socket upstream that owns this pathname. Matches on a path boundary\n * (exact prefix or prefix followed by \"/\"), so \"/api/v1x\" does not match \"/api/v1\".\n */\nexport function pickSocketWsUpstream(\n pathname: string,\n upstreams: SocketWsUpstream[],\n): SocketWsUpstream | undefined {\n return upstreams.find(\n (u) => pathname === u.prefix || pathname.startsWith(`${u.prefix}/`),\n );\n}\n\n/**\n * Build the `ws+unix://<socket>:<path>` URL — the only form the `ws` client\n * accepts for a unix socket (the `socketPath` option is ignored by ws). The\n * gateway prefix is rewritten to the upstream prefix, query string preserved.\n */\nexport function buildUpstreamWsUrl(\n upstream: SocketWsUpstream,\n pathname: string,\n search: string,\n): string {\n const rewritten = upstream.rewritePrefix + pathname.slice(upstream.prefix.length);\n return `ws+unix://${upstream.socketPath}:${rewritten}${search}`;\n}\n\n/** Extract the subset of request headers forwarded to the upstream WS handshake. */\nexport function forwardWsHeaders(req: IncomingMessage): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of FORWARDED_WS_HEADERS) {\n const value = req.headers[name];\n if (typeof value === 'string') {\n out[name] = value;\n }\n }\n return out;\n}\n\n/**\n * Attach gateway-own WebSocket endpoints using raw `ws` package.\n *\n * Must be called AFTER `app.ready()` (so http-proxy has registered its\n * upgrade listener) but BEFORE `app.listen()`.\n *\n * Captures all existing 'upgrade' listeners, removes them, then installs\n * a single unified handler that dispatches:\n * - Gateway WS paths → raw ws handlers\n * - All other paths → delegated to captured listeners (http-proxy)\n */\nexport function attachGatewayWs(\n server: Server,\n cache: ICache,\n jwtConfig: JwtConfig,\n logger: ILogger,\n hostRegistry?: HostRegistry,\n socketWsUpstreams: SocketWsUpstream[] = [],\n): void {\n const wss = new WebSocketServer({ noServer: true });\n const hostsHandler = createWsHandler(cache, jwtConfig, logger, hostRegistry);\n const clientsHandler = createClientWsHandler(cache, jwtConfig, logger);\n\n // Capture @fastify/http-proxy's upgrade listener(s)\n const existingListeners = server.listeners('upgrade').slice() as Array<\n (req: IncomingMessage, socket: Duplex, head: Buffer) => void\n >;\n server.removeAllListeners('upgrade');\n\n server.on('upgrade', (req: IncomingMessage, socket: Duplex, head: Buffer) => {\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n\n if (GATEWAY_WS_PATHS.has(pathname)) {\n // Gateway-own WS — handle directly with raw ws\n wss.handleUpgrade(req, socket, head, (ws) => {\n const handlerPromise = pathname === '/hosts/connect'\n ? hostsHandler(ws, req)\n : clientsHandler(ws, req);\n handlerPromise.catch((err) => {\n logger.error('Unhandled WS handler error', err instanceof Error ? err : new Error(String(err)), { pathname });\n try { ws.close(1011, 'Internal error'); } catch { /* already closed */ }\n });\n });\n return;\n }\n\n // Socket-bound upstream WS: @fastify/http-proxy can't dial unix sockets for\n // upgrades, so the gateway opens the upstream WS itself (ws+unix://) and\n // relays frames. TCP upstreams fall through to http-proxy below.\n const socketUpstream = pickSocketWsUpstream(pathname, socketWsUpstreams);\n if (socketUpstream) {\n const { search } = new URL(req.url ?? '/', 'http://localhost');\n const upstreamUrl = buildUpstreamWsUrl(socketUpstream, pathname, search);\n wss.handleUpgrade(req, socket, head, (clientWs) => {\n const upstreamWs = new WebSocket(upstreamUrl, { headers: forwardWsHeaders(req) });\n pumpBidirectional(clientWs, upstreamWs, logger);\n });\n return;\n }\n\n // Delegate to @fastify/http-proxy for TCP upstream WS proxy\n for (const listener of existingListeners) {\n listener.call(server, req, socket, head);\n }\n });\n\n logger.info('Gateway WS endpoints attached', { paths: [...GATEWAY_WS_PATHS] });\n}\n","import type { FastifyInstance, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from 'fastify';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\nimport {\n OBSERVABILITY_CONTRACT_VERSION,\n OBSERVABILITY_SCHEMA,\n CANONICAL_OBSERVABILITY_METRICS,\n type ServiceHealthStatus,\n type ObservabilityCheck,\n} from '@kb-labs/core-contracts';\nimport type { ServiceObservabilityDescribe, ServiceObservabilityHealth } from '@kb-labs/core-contracts';\nimport {\n createServiceObservabilityDescribe,\n createServiceObservabilityHealth,\n OperationMetricsTracker,\n} from '@kb-labs/shared-http';\nimport { hostname } from 'node:os';\nimport { monitorEventLoopDelay, performance } from 'node:perf_hooks';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n kbMetricsStart?: number;\n }\n}\n\ntype RouteStats = {\n count: number;\n totalDurationMs: number;\n maxDurationMs: number;\n errorCount: number;\n};\n\nfunction normalizeRoute(route: string | undefined): string {\n if (!route) {\n return 'unknown';\n }\n return route\n .split('?')[0]!\n .replace(/\\/[0-9a-fA-F-]{6,}/g, '/:id');\n}\n\nfunction metricLine(name: string, value: number, labels?: Record<string, string>): string {\n if (!labels || Object.keys(labels).length === 0) {\n return `${name} ${value}`;\n }\n const pairs = Object.entries(labels).map(([key, labelValue]) => `${key}=\"${labelValue.replace(/\"/g, '\\\\\"')}\"`);\n return `${name}{${pairs.join(',')}} ${value}`;\n}\n\nexport class GatewayObservabilityCollector {\n private readonly instanceId = `${hostname()}:${process.pid}`;\n private readonly eventLoop = monitorEventLoopDelay({ resolution: 20 });\n private readonly routeStats = new Map<string, RouteStats>();\n private readonly operationMetrics = new OperationMetricsTracker();\n private readonly startedAt = Date.now();\n private readonly dependencies;\n private lastCpuUsage = process.cpuUsage();\n private lastCpuTime = Date.now();\n private intervalId: NodeJS.Timeout | null = null;\n private activeOperations = 0;\n private requestsTotal = 0;\n private errorsTotal = 0;\n private lastSnapshot = {\n cpuPercent: 0,\n rssBytes: process.memoryUsage().rss,\n heapUsedBytes: process.memoryUsage().heapUsed,\n eventLoopLagMs: 0,\n };\n\n constructor(private readonly config: GatewayConfig) {\n this.dependencies = Object.keys(this.config.upstreams).map((serviceId) => ({\n serviceId,\n required: false,\n description: 'Gateway upstream',\n }));\n }\n\n register(server: unknown): void {\n const hookServer = server as FastifyInstance;\n this.eventLoop.enable();\n this.intervalId = setInterval(() => this.captureRuntimeSnapshot(), 10_000);\n this.captureRuntimeSnapshot();\n\n hookServer.addHook('onRequest', (request: FastifyRequest, _reply: FastifyReply, done: HookHandlerDoneFunction) => {\n request.kbMetricsStart = performance.now();\n this.activeOperations += 1;\n done();\n });\n\n hookServer.addHook('onResponse', (request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) => {\n const started = request.kbMetricsStart ?? performance.now();\n const durationMs = Math.max(performance.now() - started, 0);\n const route = `${request.method.toUpperCase()} ${normalizeRoute(request.routeOptions?.url ?? request.url)}`;\n const stats = this.routeStats.get(route) ?? {\n count: 0,\n totalDurationMs: 0,\n maxDurationMs: 0,\n errorCount: 0,\n };\n\n stats.count += 1;\n stats.totalDurationMs += durationMs;\n stats.maxDurationMs = Math.max(stats.maxDurationMs, durationMs);\n if (reply.statusCode >= 400) {\n stats.errorCount += 1;\n this.errorsTotal += 1;\n }\n this.routeStats.set(route, stats);\n this.requestsTotal += 1;\n this.activeOperations = Math.max(0, this.activeOperations - 1);\n done();\n });\n\n hookServer.addHook('onClose', (_instance: unknown, done: HookHandlerDoneFunction) => {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n this.eventLoop.disable();\n done();\n });\n }\n\n buildDescribe(): ServiceObservabilityDescribe {\n return createServiceObservabilityDescribe({\n schema: OBSERVABILITY_SCHEMA,\n contractVersion: OBSERVABILITY_CONTRACT_VERSION,\n serviceId: 'gateway',\n instanceId: this.instanceId,\n serviceType: 'gateway',\n version: '1.0.0',\n environment: process.env.NODE_ENV ?? 'development',\n startedAt: new Date(this.startedAt).toISOString(),\n dependencies: this.dependencies,\n metricsEndpoint: '/metrics',\n healthEndpoint: '/observability/health',\n logsSource: 'gateway',\n capabilities: ['httpMetrics', 'eventLoopMetrics', 'operationMetrics', 'logCorrelation'],\n metricFamilies: [...CANONICAL_OBSERVABILITY_METRICS],\n });\n }\n\n buildHealth(input: {\n status: ServiceHealthStatus;\n adapterChecks: Array<{ id: string; available: boolean; latencyMs?: number }>;\n upstreamChecks: Array<{ id: string; status: string; latencyMs?: number }>;\n }): ServiceObservabilityHealth {\n const checks: ObservabilityCheck[] = [\n ...input.adapterChecks.map((entry): ObservabilityCheck => ({\n id: `adapter:${entry.id}`,\n status: entry.available ? 'ok' : 'warn',\n latencyMs: entry.latencyMs,\n message: entry.available ? 'Adapter available' : 'Adapter unavailable',\n })),\n ...input.upstreamChecks.map((entry): ObservabilityCheck => ({\n id: `upstream:${entry.id}`,\n status: entry.status === 'up' ? 'ok' : 'warn',\n latencyMs: entry.latencyMs,\n message: entry.status === 'up' ? 'Upstream healthy' : 'Upstream unavailable',\n })),\n ];\n\n const topOperations = mergeTopOperations(\n Array.from(this.routeStats.entries())\n .sort((a, b) => b[1].count - a[1].count || b[1].maxDurationMs - a[1].maxDurationMs)\n .slice(0, 5)\n .map(([operation, stats]) => ({\n operation: `http.${operation}`,\n count: stats.count,\n avgDurationMs: stats.count > 0 ? stats.totalDurationMs / stats.count : 0,\n maxDurationMs: stats.maxDurationMs,\n errorCount: stats.errorCount,\n })),\n this.operationMetrics.getTopOperations(),\n );\n\n return createServiceObservabilityHealth({\n schema: OBSERVABILITY_SCHEMA,\n contractVersion: OBSERVABILITY_CONTRACT_VERSION,\n serviceId: 'gateway',\n instanceId: this.instanceId,\n observedAt: new Date().toISOString(),\n status: input.status,\n uptimeSec: Math.floor((Date.now() - this.startedAt) / 1000),\n metricsEndpoint: '/metrics',\n logsSource: 'gateway',\n capabilities: ['httpMetrics', 'eventLoopMetrics', 'operationMetrics', 'logCorrelation'],\n checks,\n snapshot: {\n cpuPercent: this.lastSnapshot.cpuPercent,\n rssBytes: this.lastSnapshot.rssBytes,\n heapUsedBytes: this.lastSnapshot.heapUsedBytes,\n eventLoopLagMs: this.lastSnapshot.eventLoopLagMs,\n activeOperations: this.activeOperations,\n },\n topOperations,\n state: input.status === 'healthy' ? 'active' : input.status === 'degraded' ? 'partial_observability' : 'insufficient_data',\n meta: {\n requestsTotal: this.requestsTotal,\n errorsTotal: this.errorsTotal,\n },\n });\n }\n\n async renderPrometheusMetrics(healthStatus: ServiceHealthStatus): Promise<string> {\n this.captureRuntimeSnapshot();\n\n const lines = [\n '# HELP process_cpu_percent Current process CPU usage percentage',\n '# TYPE process_cpu_percent gauge',\n metricLine('process_cpu_percent', this.lastSnapshot.cpuPercent),\n '# HELP process_rss_bytes Current process resident set size in bytes',\n '# TYPE process_rss_bytes gauge',\n metricLine('process_rss_bytes', this.lastSnapshot.rssBytes),\n '# HELP process_heap_used_bytes Current process heap used in bytes',\n '# TYPE process_heap_used_bytes gauge',\n metricLine('process_heap_used_bytes', this.lastSnapshot.heapUsedBytes),\n '# HELP process_event_loop_lag_ms Current event loop lag in milliseconds',\n '# TYPE process_event_loop_lag_ms gauge',\n metricLine('process_event_loop_lag_ms', this.lastSnapshot.eventLoopLagMs),\n '# HELP service_health_status Service health status (2=healthy, 1=degraded, 0=unhealthy)',\n '# TYPE service_health_status gauge',\n metricLine('service_health_status', healthStatus === 'healthy' ? 2 : healthStatus === 'degraded' ? 1 : 0),\n '# HELP service_restarts_total Service restart counter within current process lifetime',\n '# TYPE service_restarts_total gauge',\n metricLine('service_restarts_total', 0),\n '# HELP service_active_operations Current number of active operations',\n '# TYPE service_active_operations gauge',\n metricLine('service_active_operations', this.activeOperations),\n '# HELP http_requests_total Total number of HTTP requests',\n '# TYPE http_requests_total counter',\n '# HELP http_errors_total Total number of HTTP errors (4xx, 5xx)',\n '# TYPE http_errors_total counter',\n '# HELP http_request_duration_ms Total duration of HTTP requests grouped by route',\n '# TYPE http_request_duration_ms summary',\n '# HELP service_operation_total Total number of service operations',\n '# TYPE service_operation_total counter',\n '# HELP service_operation_duration_ms Total duration of service operations grouped by route',\n '# TYPE service_operation_duration_ms summary',\n ];\n\n for (const [route, stats] of this.routeStats.entries()) {\n const status = stats.errorCount > 0 ? 'error' : 'ok';\n lines.push(metricLine('http_requests_total', stats.count, { route }));\n lines.push(metricLine('http_errors_total', stats.errorCount, { route }));\n lines.push(metricLine('http_request_duration_ms', Number(stats.totalDurationMs.toFixed(2)), { route }));\n lines.push(metricLine('service_operation_total', stats.count, { operation: `http.${route}`, status }));\n lines.push(metricLine('service_operation_duration_ms', Number(stats.totalDurationMs.toFixed(2)), { operation: `http.${route}`, status }));\n }\n\n lines.push(...this.operationMetrics.getMetricLines());\n\n return `${lines.join('\\n')}\\n`;\n }\n\n recordOperation(operation: string, durationMs = 0, status: 'ok' | 'error' = 'ok'): void {\n this.operationMetrics.recordOperation(operation, durationMs, status);\n }\n\n observeOperation<T>(operation: string, work: () => T | Promise<T>): Promise<T> {\n return this.operationMetrics.observeOperation(operation, work);\n }\n\n private captureRuntimeSnapshot(): void {\n const currentUsage = process.cpuUsage(this.lastCpuUsage);\n const currentTime = Date.now();\n const deltaTime = Math.max(currentTime - this.lastCpuTime, 1);\n\n this.lastCpuUsage = process.cpuUsage();\n this.lastCpuTime = currentTime;\n\n const cpuTimeMs = (currentUsage.user + currentUsage.system) / 1000;\n const memory = process.memoryUsage();\n const eventLoopLagMs = Number((this.eventLoop.mean / 1_000_000).toFixed(2));\n\n this.lastSnapshot = {\n cpuPercent: Number(Math.min((cpuTimeMs / deltaTime) * 100, 100).toFixed(2)),\n rssBytes: memory.rss,\n heapUsedBytes: memory.heapUsed,\n eventLoopLagMs: Number.isFinite(eventLoopLagMs) ? eventLoopLagMs : 0,\n };\n\n this.eventLoop.reset();\n }\n}\n\nfunction mergeTopOperations(\n httpOperations: Array<{\n operation: string;\n count: number;\n avgDurationMs: number;\n maxDurationMs: number;\n errorCount: number;\n }>,\n domainOperations: Array<{\n operation: string;\n count?: number;\n avgDurationMs?: number;\n maxDurationMs?: number;\n errorCount?: number;\n }>,\n limit = 5,\n) {\n const merged = new Map<string, {\n operation: string;\n count?: number;\n avgDurationMs?: number;\n maxDurationMs?: number;\n errorCount?: number;\n }>();\n\n for (const item of [...httpOperations, ...domainOperations]) {\n const existing = merged.get(item.operation);\n if (!existing) {\n merged.set(item.operation, { ...item });\n continue;\n }\n\n const count = (existing.count ?? 0) + (item.count ?? 0);\n const totalDurationMs =\n (existing.avgDurationMs ?? 0) * (existing.count ?? 0) +\n (item.avgDurationMs ?? 0) * (item.count ?? 0);\n\n merged.set(item.operation, {\n operation: item.operation,\n count,\n avgDurationMs: count > 0 ? totalDurationMs / count : 0,\n maxDurationMs: Math.max(existing.maxDurationMs ?? 0, item.maxDurationMs ?? 0),\n errorCount: (existing.errorCount ?? 0) + (item.errorCount ?? 0),\n });\n }\n\n const ranked = Array.from(merged.values())\n .sort((a, b) => (b.count ?? 0) - (a.count ?? 0) || (b.maxDurationMs ?? 0) - (a.maxDurationMs ?? 0))\n const sliced = ranked.slice(0, limit);\n\n if (domainOperations.length === 0 || sliced.some((item) => !item.operation.startsWith('http.'))) {\n return sliced;\n }\n\n const firstDomainOperation = ranked.find((item) => !item.operation.startsWith('http.'));\n if (!firstDomainOperation) {\n return sliced;\n }\n\n return [...sliced.slice(0, Math.max(0, limit - 1)), firstDomainOperation];\n}\n","/**\n * @module @kb-labs/gateway-app/internal/routes\n * Service-to-service endpoints — NOT for external clients.\n * Auth: x-internal-secret header (GATEWAY_INTERNAL_SECRET env var).\n *\n * POST /internal/dispatch — invoke adapter method on a connected host\n * POST /internal/resolve-host — resolve hostId for namespace + strategy\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport { globalDispatcher } from '../hosts/dispatcher.js';\nimport type { HostRegistry } from '../hosts/registry.js';\nimport { getClientByHandle } from '@kb-labs/gateway-auth';\n\nexport function registerInternalRoutes(\n scope: FastifyInstance,\n internalSecret: string | undefined,\n hostRegistry: HostRegistry,\n cache?: import('@kb-labs/core-platform').ICache,\n): void {\n scope.post('/internal/dispatch', async (request, reply) => {\n const provided = request.headers['x-internal-secret'];\n if (!internalSecret || provided !== internalSecret) {\n return reply.code(403).send({ error: 'Forbidden' });\n }\n\n const body = request.body as {\n namespaceId?: string;\n hostId?: string;\n adapter?: string;\n method?: string;\n args?: unknown[];\n };\n\n if (!body.namespaceId || !body.adapter || !body.method) {\n return reply.code(400).send({ error: 'Missing required fields: namespaceId, adapter, method' });\n }\n\n const hostId = body.hostId\n ?? globalDispatcher.firstHostWithCapability(body.namespaceId, body.adapter)\n ?? globalDispatcher.firstHost(body.namespaceId);\n if (!hostId) {\n return reply.code(503).send({\n error: 'No host connected',\n namespaceId: body.namespaceId,\n });\n }\n\n try {\n const result = await globalDispatcher.call(\n body.namespaceId,\n hostId,\n body.adapter,\n body.method,\n body.args ?? [],\n );\n return { result };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes('Host not connected')) {\n return reply.code(503).send({ error: message });\n }\n return reply.code(502).send({ error: message });\n }\n });\n\n scope.get('/internal/auth/handle/:handle', async (request, reply) => {\n const provided = request.headers['x-internal-secret'];\n if (!internalSecret || provided !== internalSecret) {\n return reply.code(403).send({ error: 'Forbidden' });\n }\n if (!cache) {\n return reply.code(503).send({ error: 'Cache not available' });\n }\n const { handle } = request.params as { handle: string };\n const record = await getClientByHandle(cache, handle);\n if (!record) {\n return reply.code(404).send({ error: 'Handle not found' });\n }\n return { namespaceId: record.namespaceId, name: record.name, handle: record.handle };\n });\n\n scope.post('/internal/resolve-host', async (request, reply) => {\n const provided = request.headers['x-internal-secret'];\n if (!internalSecret || provided !== internalSecret) {\n return reply.code(403).send({ error: 'Forbidden' });\n }\n\n const body = request.body as {\n namespaceId?: string;\n target?: {\n hostId?: string;\n hostSelection?: string;\n repoFingerprint?: string;\n };\n };\n\n const namespaceId = body.namespaceId ?? 'default';\n const target = body.target ?? {};\n const strategy = (target.hostSelection ?? 'any-matching') as string;\n\n let hostId: string | undefined;\n\n if (strategy === 'pinned' && target.hostId) {\n const host = await hostRegistry.get(target.hostId, namespaceId);\n if (host?.status === 'online' || host?.status === 'reconnecting') {\n hostId = target.hostId;\n }\n } else {\n hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n }\n\n if (!hostId) {\n return reply.code(404).send({ error: 'No matching host found' });\n }\n\n return { hostId, strategy, namespaceId };\n });\n}\n","/**\n * @module pressure/resolve\n * Pure resource-id resolution for HTTP pressure control.\n *\n * Resolves an incoming request to one of three resource ids:\n * - `gateway:route:<slug>` — per-route override (highest priority)\n * - `gateway:service:<name>` — per-upstream fallback\n * - null — no pressure applies\n *\n * No broker access; no I/O. Safe to call in `onRequest` hook.\n */\n\nimport type {\n GatewayConfig,\n PressureConfig,\n PressureRouteOverride,\n} from '@kb-labs/gateway-contracts';\n\nexport type ResolvedPressure =\n | { resource: string; layer: 'route'; override: PressureRouteOverride }\n | { resource: string; layer: 'service'; upstream: string }\n | null;\n\n/**\n * Resolve a request to the resource id that should be checked against the broker.\n *\n * Order:\n * 1. perRoute overrides (first match wins by array order).\n * 2. perService — look up by upstream prefix match.\n * 3. null — pressure does not apply.\n *\n * Returns null when pressure is disabled, no upstream matches, and no route override fires.\n */\nexport function resolveResourceId(\n method: string,\n url: string,\n config: GatewayConfig,\n): ResolvedPressure {\n const pressure: PressureConfig | undefined = config.pressure;\n if (!pressure || pressure.enabled === false) {\n return null;\n }\n\n // Strip query string before prefix matching.\n const path = url.split('?')[0] ?? url;\n const upperMethod = method.toUpperCase();\n\n // 1. per-route overrides (first match wins)\n for (const override of pressure.perRoute) {\n if (!path.startsWith(override.pathPrefix)) {\n continue;\n }\n if (override.methods && override.methods.length > 0) {\n const allowed = override.methods.some(m => m.toUpperCase() === upperMethod);\n if (!allowed) { continue; }\n }\n return { resource: override.resource, layer: 'route', override };\n }\n\n // 2. per-service via upstream prefix match\n for (const [name, upstream] of Object.entries(config.upstreams)) {\n if (path.startsWith(upstream.prefix)) {\n const limits = pressure.perService[name];\n if (!limits) { return null; }\n return { resource: `gateway:service:${name}`, layer: 'service', upstream: name };\n }\n }\n\n return null;\n}\n","/**\n * @module pressure/register-limits\n * Boot-time registration of pressure limits with the platform ResourceBroker.\n *\n * Idempotent: safe to call more than once (relies on `IResourceBroker.registerLimit`\n * being a `Map.set` overwrite — see ADR-0056).\n */\n\nimport type { IResourceBroker } from '@kb-labs/core-resource-broker';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport type { PressureConfig } from '@kb-labs/gateway-contracts';\n\nexport interface RegisterPressureLimitsResult {\n perServiceRegistered: number;\n perRouteRegistered: number;\n perTenantEnabled: boolean;\n}\n\nexport function registerPressureLimits(\n broker: IResourceBroker,\n config: PressureConfig | undefined,\n logger: ILogger,\n): RegisterPressureLimitsResult {\n if (!config || config.enabled === false) {\n return { perServiceRegistered: 0, perRouteRegistered: 0, perTenantEnabled: false };\n }\n\n let perServiceRegistered = 0;\n for (const [name, limits] of Object.entries(config.perService)) {\n broker.registerLimit(`gateway:service:${name}`, limits);\n perServiceRegistered++;\n }\n\n let perRouteRegistered = 0;\n for (const override of config.perRoute) {\n broker.registerLimit(override.resource, override.limits);\n perRouteRegistered++;\n }\n\n const perTenantEnabled = config.perTenant?.enabled === true;\n\n logger.info('pressure.boot', {\n event: 'pressure.boot',\n perService: perServiceRegistered,\n perRoute: perRouteRegistered,\n perTenant: perTenantEnabled,\n });\n\n return { perServiceRegistered, perRouteRegistered, perTenantEnabled };\n}\n","/**\n * @module pressure/hooks\n * Fastify hooks that apply pressure-control via `IResourceBroker.tryAcquire`.\n *\n * Three hooks:\n * - `onRequest` (per-service / per-route) — runs before auth, returns 429 if denied.\n * - `preHandler` (per-tenant) — runs after auth, keyed by AuthContext.namespaceId.\n * - `onResponse` — releases every slot reserved during the request.\n *\n * Aborted connections are caught via `request.raw.on('close', ...)`. Idempotency\n * of `release` (core ResourceBroker guarantee) makes double-fire safe.\n *\n * SSE / WebSocket requests are skipped (long-lived connections would hold a slot\n * past `onResponse`). Detection is via the `Upgrade` header.\n */\n\nimport type { FastifyRequest, FastifyReply, onRequestHookHandler, preHandlerHookHandler, onResponseHookHandler } from 'fastify';\nimport type { IResourceBroker, TryAcquireResult } from '@kb-labs/core-resource-broker';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\nimport { resolveResourceId } from './resolve.js';\n\nimport './types.js';\n\nexport interface PressureHooksDeps {\n broker: IResourceBroker;\n logger: ILogger;\n config: GatewayConfig;\n}\n\n/**\n * Returns true if the request is a WS/SSE upgrade and must be skipped.\n */\nfunction shouldSkip(request: FastifyRequest): boolean {\n const upgrade = request.headers.upgrade;\n if (typeof upgrade === 'string' && upgrade.length > 0) { return true; }\n return false;\n}\n\n/**\n * Initialize the per-request release array and arm an `onClose` safety net.\n * Called from the very first hook that may add a release handle.\n */\nfunction armRequest(request: FastifyRequest): Array<() => Promise<void>> {\n if (!request.pressureReleases) {\n request.pressureReleases = [];\n request.raw.on('close', () => {\n void releaseAll(request);\n });\n }\n return request.pressureReleases;\n}\n\nasync function releaseAll(request: FastifyRequest): Promise<void> {\n const releases = request.pressureReleases;\n if (!releases || releases.length === 0) { return; }\n // Snapshot + clear so a second pass (close after finish) is a no-op.\n const snapshot = releases.slice();\n request.pressureReleases = [];\n for (const release of snapshot) {\n try {\n await release();\n } catch {\n // Release errors are non-fatal; broker idempotency means slot may\n // already be free. Surface via logger if we ever need it, but stay\n // silent here to avoid amplifying noise on shutdown / aborted conns.\n }\n }\n}\n\nfunction retryAfterSeconds(waitTimeMs: number | undefined): number {\n if (!waitTimeMs || waitTimeMs <= 0) { return 1; }\n return Math.max(1, Math.ceil(waitTimeMs / 1000));\n}\n\n/**\n * Per-service / per-route hook. Runs as the first thing on every request.\n */\nexport function createPressureOnRequest(deps: PressureHooksDeps): onRequestHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (shouldSkip(request)) { return; }\n\n const resolved = resolveResourceId(request.method, request.url, deps.config);\n if (!resolved) { return; }\n\n const acquired: TryAcquireResult = await deps.broker.tryAcquire(resolved.resource);\n\n if (!acquired.allowed) {\n const retryAfter = retryAfterSeconds(acquired.waitTimeMs);\n deps.logger.warn('pressure.rejected', {\n event: 'pressure.rejected',\n resource: resolved.resource,\n layer: resolved.layer,\n method: request.method,\n url: request.url,\n waitTimeMs: acquired.waitTimeMs,\n });\n reply\n .code(429)\n .header('Retry-After', String(retryAfter))\n .send({\n error: 'rate_limited',\n resource: resolved.resource,\n waitTimeMs: acquired.waitTimeMs ?? null,\n });\n return reply;\n }\n\n armRequest(request).push(acquired.release);\n };\n}\n\n/**\n * Per-tenant hook. Runs after auth (inside the authenticated scope), so\n * `request.authContext.namespaceId` is available. Lazily registers a\n * limit-only resource per namespace on first encounter.\n *\n * Relies on `broker.registerLimit` idempotency (core ResourceBroker uses\n * `Map.set`) — a concurrent first-request race re-registers harmlessly.\n */\nexport function createPressurePreHandler(deps: PressureHooksDeps): preHandlerHookHandler {\n const registered = new Set<string>();\n const tenantCfg = deps.config.pressure?.perTenant;\n\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (!tenantCfg || tenantCfg.enabled !== true) { return; }\n if (shouldSkip(request)) { return; }\n\n const namespaceId = request.authContext?.namespaceId;\n if (!namespaceId) { return; }\n\n const resource = `gateway:tenant:${namespaceId}`;\n if (!registered.has(namespaceId)) {\n deps.broker.registerLimit(resource, tenantCfg.limits);\n registered.add(namespaceId);\n deps.logger.debug?.('pressure.tenant.registered', {\n event: 'pressure.tenant.registered',\n namespaceId,\n });\n }\n\n const acquired = await deps.broker.tryAcquire(resource);\n if (!acquired.allowed) {\n const retryAfter = retryAfterSeconds(acquired.waitTimeMs);\n deps.logger.warn('pressure.rejected', {\n event: 'pressure.rejected',\n resource,\n layer: 'tenant',\n method: request.method,\n url: request.url,\n namespaceId,\n waitTimeMs: acquired.waitTimeMs,\n });\n reply\n .code(429)\n .header('Retry-After', String(retryAfter))\n .send({\n error: 'rate_limited',\n resource,\n waitTimeMs: acquired.waitTimeMs ?? null,\n });\n return reply;\n }\n\n armRequest(request).push(acquired.release);\n };\n}\n\n/**\n * Response hook that releases every pressure slot reserved for this request.\n */\nexport function createPressureOnResponse(): onResponseHookHandler {\n return async (request: FastifyRequest) => {\n await releaseAll(request);\n };\n}\n","/**\n * @module webhook/secret-store\n *\n * Cache-backed store for webhook delivery secrets.\n *\n * Each provisioned webhook gets a `current` secret. On rotation, the old\n * secret moves to `previous` with a 24-hour grace window — so external\n * services that cached the old secret keep working briefly after rotation.\n *\n * Cache key format:\n * `webhook:secret:{ns}:{pluginId}:{event}`\n * `webhook:secret:{ns}:{pluginId}:{event}:{instanceId}` (multi: true)\n */\n\nimport type { ICache } from '@kb-labs/core-platform';\n\nexport interface WebhookSecretEntry {\n /** Active secret for new deliveries. */\n current: string;\n /** Previous secret, still valid until `previousExpiresAt`. */\n previous?: string;\n /** Unix timestamp (ms) after which `previous` is no longer valid. */\n previousExpiresAt?: number;\n}\n\n/** Grace window for previous secret after rotation: 24 hours. */\nconst PREVIOUS_SECRET_GRACE_MS = 86_400_000;\n\nfunction cacheKey(ns: string, pluginId: string, event: string, instanceId?: string): string {\n const base = `webhook:secret:${ns}:${pluginId}:${event}`;\n return instanceId ? `${base}:${instanceId}` : base;\n}\n\nexport class WebhookSecretStore {\n constructor(private readonly cache: ICache) {}\n\n async get(ns: string, pluginId: string, event: string, instanceId?: string): Promise<WebhookSecretEntry | null> {\n return this.cache.get<WebhookSecretEntry>(cacheKey(ns, pluginId, event, instanceId));\n }\n\n async set(ns: string, pluginId: string, event: string, entry: WebhookSecretEntry, instanceId?: string): Promise<void> {\n await this.cache.set(cacheKey(ns, pluginId, event, instanceId), entry);\n }\n\n async rotate(ns: string, pluginId: string, event: string, newSecret: string, instanceId?: string): Promise<WebhookSecretEntry> {\n const existing = await this.get(ns, pluginId, event, instanceId);\n const entry: WebhookSecretEntry = { current: newSecret };\n\n if (existing) {\n entry.previous = existing.current;\n entry.previousExpiresAt = Date.now() + PREVIOUS_SECRET_GRACE_MS;\n }\n\n await this.set(ns, pluginId, event, entry, instanceId);\n return entry;\n }\n\n async delete(ns: string, pluginId: string, event: string, instanceId?: string): Promise<void> {\n await this.cache.delete(cacheKey(ns, pluginId, event, instanceId));\n }\n}\n","/**\n * @module webhook/provision\n *\n * Provisions a webhook secret for a plugin+event combination.\n *\n * On first call: generates a new secret, stores it, calls onProvision handler.\n * On subsequent calls: rotates the secret (old → previous with 24h grace window).\n *\n * onProvision failures are logged but do not abort provisioning — the secret\n * is always persisted. Callers display the secret once; it cannot be recovered.\n */\n\nimport { randomBytes } from 'node:crypto';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport type { WebhookSecretStore } from './secret-store.js';\nimport type { WebhookManifestEntry } from './router.js';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface ProvisionInput {\n namespaceId: string;\n pluginId: string;\n event: string;\n instanceId?: string;\n baseUrl: string;\n}\n\nexport interface ProvisionResult {\n url: string;\n secret: string;\n rotated: boolean;\n onProvisionCalled: boolean;\n}\n\n/** Minimal execution backend — only `execute` is needed. */\nexport interface ProvisionBackend {\n execute(input: { handlerRef: string; pluginRoot: string; input: unknown; namespaceId?: string }): Promise<unknown>;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Provision (or rotate) a webhook secret for a plugin+event.\n *\n * @throws If the pluginId/event combination is not found in `manifests`.\n */\nexport async function provisionWebhook(\n input: ProvisionInput,\n secretStore: WebhookSecretStore,\n backend: ProvisionBackend,\n manifests: WebhookManifestEntry[],\n logger: ILogger,\n): Promise<ProvisionResult> {\n const { namespaceId, pluginId, event, instanceId, baseUrl } = input;\n\n // Find the declaration\n const manifestEntry = manifests.find((m) => m.pluginId === pluginId);\n const decl = manifestEntry?.manifest.webhooks?.handlers.find((h) => h.event === event);\n\n // manifestEntry check is for TypeScript narrowing — if decl is undefined,\n // manifestEntry is also undefined (decl depends on it via optional chaining).\n if (!manifestEntry || !decl) {\n throw new Error(`webhook '${pluginId}/${event}' not found`);\n }\n\n // Check whether a secret already exists (determines rotated flag)\n const existing = await secretStore.get(namespaceId, pluginId, event, instanceId);\n const rotated = existing !== null;\n\n // Generate a new secret: 32 random bytes as hex (64 chars)\n const newSecret = randomBytes(32).toString('hex');\n\n // Store via rotate (preserves previous with 24h grace) or set (first time)\n if (rotated) {\n await secretStore.rotate(namespaceId, pluginId, event, newSecret, instanceId);\n } else {\n await secretStore.set(namespaceId, pluginId, event, { current: newSecret }, instanceId);\n }\n\n // Build webhook URL — encode pluginId so scoped names (@org/pkg → %40org%2Fpkg)\n // produce a valid single-segment path param that Fastify routes correctly.\n const url = instanceId\n ? `${baseUrl}/webhooks/${encodeURIComponent(pluginId)}/${event}/${instanceId}`\n : `${baseUrl}/webhooks/${encodeURIComponent(pluginId)}/${event}`;\n\n // Call onProvision handler if declared\n let onProvisionCalled = false;\n if (decl.onProvision) {\n try {\n await backend.execute({\n handlerRef: decl.onProvision,\n pluginRoot: manifestEntry.pluginRoot,\n namespaceId,\n input: { instanceId, secret: newSecret, url },\n });\n onProvisionCalled = true;\n } catch (err) {\n logger.error(\n 'onProvision handler failed',\n err instanceof Error ? err : new Error(String(err)),\n { pluginId, event, instanceId },\n );\n }\n }\n\n return { url, secret: newSecret, rotated, onProvisionCalled };\n}\n","/**\n * @module webhook/admin-routes\n *\n * Admin HTTP routes for webhook management. Must be registered inside an\n * authenticated scope (request.authContext is expected to be set).\n *\n * Routes:\n * POST /api/v1/webhooks/provision — provision or rotate a secret\n * GET /api/v1/webhooks[?pluginId=] — list declared webhooks\n * DELETE /api/v1/webhooks/:pluginId/:event — revoke (single-instance)\n * DELETE /api/v1/webhooks/:pluginId/:event/:instanceId — revoke (multi-instance)\n *\n * namespaceId is taken from request.authContext — callers operate on their\n * own namespace only. No cross-namespace access.\n *\n * Rate limiting: each route acquires a token at the start and releases in\n * finally after all work completes — ensures the slot is held for the full\n * duration of the operation, not just the guard check.\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { IResourceBroker } from '@kb-labs/core-resource-broker';\nimport { WebhookSecretStore } from './secret-store.js';\nimport { provisionWebhook, type ProvisionBackend } from './provision.js';\nimport type { WebhookManifestEntry } from './router.js';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface RegisterWebhookAdminRoutesOptions {\n cache: ICache;\n logger: ILogger;\n backend: ProvisionBackend;\n manifests: WebhookManifestEntry[];\n baseUrl: string;\n /** Rate limiter — admin routes are always rate-limited. */\n broker: IResourceBroker;\n}\n\n// ── Rate limit resources ──────────────────────────────────────────────────────\n\nconst RL_PROVISION = 'webhook-admin:provision';\nconst RL_LIST = 'webhook-admin:list';\nconst RL_REVOKE = 'webhook-admin:revoke';\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport function registerWebhookAdminRoutes(\n scope: FastifyInstance,\n options: RegisterWebhookAdminRoutesOptions,\n): void {\n const { cache, logger, backend, manifests, baseUrl, broker } = options;\n const secretStore = new WebhookSecretStore(cache);\n\n // Register per-resource rate limits.\n // Admin operations are infrequent; conservative limits prevent abuse.\n broker.registerLimit(RL_PROVISION, { requestsPerMinute: 10 });\n broker.registerLimit(RL_LIST, { requestsPerMinute: 60 });\n broker.registerLimit(RL_REVOKE, { requestsPerMinute: 10 });\n\n // ── POST /api/v1/webhooks/provision ─────────────────────────────────────────\n\n scope.post('/api/v1/webhooks/provision', async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n // Acquire rate-limit token for the FULL duration of the handler so the\n // slot is not released until all work (provisionWebhook) completes.\n const acquired = await broker.tryAcquire(RL_PROVISION);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const body = request.body as Record<string, unknown> | undefined;\n const pluginId = typeof body?.pluginId === 'string' ? body.pluginId : undefined;\n const event = typeof body?.event === 'string' ? body.event : undefined;\n const instanceId = typeof body?.instanceId === 'string' ? body.instanceId : undefined;\n\n if (!pluginId) {\n return reply.code(400).send({ error: 'Bad Request', message: 'pluginId is required' });\n }\n if (!event) {\n return reply.code(400).send({ error: 'Bad Request', message: 'event is required' });\n }\n\n try {\n const result = await provisionWebhook(\n { namespaceId: auth.namespaceId, pluginId, event, instanceId, baseUrl },\n secretStore,\n backend,\n manifests,\n logger,\n );\n\n return reply.code(200).send({\n url: result.url,\n secret: result.secret,\n rotated: result.rotated,\n });\n } catch (err) {\n if (err instanceof Error && err.message.includes('not found')) {\n return reply.code(404).send({ error: 'Not Found', message: err.message });\n }\n throw err;\n }\n } finally {\n await acquired.release();\n }\n });\n\n // ── GET /api/v1/webhooks ─────────────────────────────────────────────────────\n\n scope.get('/api/v1/webhooks', async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const acquired = await broker.tryAcquire(RL_LIST);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const query = request.query as Record<string, string | undefined>;\n const filterPluginId = query.pluginId;\n\n const webhooks: Array<{ pluginId: string; event: string; multi: boolean; provisioned: boolean }> = [];\n\n for (const entry of manifests) {\n if (filterPluginId && entry.pluginId !== filterPluginId) { continue; }\n if (!entry.manifest.webhooks?.handlers) { continue; }\n\n for (const decl of entry.manifest.webhooks.handlers) {\n // For multi webhooks the provisioned check is per-instanceId; we show false\n // at the list level since there is no shared base entry.\n const secretEntry = decl.multi\n ? null\n : await secretStore.get(auth.namespaceId, entry.pluginId, decl.event);\n\n webhooks.push({\n pluginId: entry.pluginId,\n event: decl.event,\n multi: decl.multi === true,\n provisioned: secretEntry !== null,\n });\n }\n }\n\n return reply.code(200).send({ webhooks });\n } finally {\n await acquired.release();\n }\n });\n\n // ── DELETE /api/v1/webhooks/:pluginId/:event ──────────────────────────────────\n\n scope.delete<{ Params: { pluginId: string; event: string } }>(\n '/api/v1/webhooks/:pluginId/:event',\n async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const acquired = await broker.tryAcquire(RL_REVOKE);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const { pluginId, event } = request.params;\n await secretStore.delete(auth.namespaceId, pluginId, event);\n return reply.code(204).send();\n } finally {\n await acquired.release();\n }\n },\n );\n\n // ── DELETE /api/v1/webhooks/:pluginId/:event/:instanceId ──────────────────────\n\n scope.delete<{ Params: { pluginId: string; event: string; instanceId: string } }>(\n '/api/v1/webhooks/:pluginId/:event/:instanceId',\n async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const acquired = await broker.tryAcquire(RL_REVOKE);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const { pluginId, event, instanceId } = request.params;\n await secretStore.delete(auth.namespaceId, pluginId, event, instanceId);\n return reply.code(204).send();\n } finally {\n await acquired.release();\n }\n },\n );\n}\n","/**\n * @module webhook/idempotency-store\n *\n * Deduplication store for webhook deliveries.\n *\n * Uses `cache.setIfNotExists` for atomic check-and-mark — safe under\n * concurrent deliveries of the same event (e.g. retry storms from GitHub).\n *\n * Key format: `webhook:idempotency:{namespaceId}:{pluginId}:{event}:{deliveryKey}`\n * TTL: 7 days — covers typical webhook retry windows.\n */\n\nimport type { ICache } from '@kb-labs/core-platform';\n\nconst IDEMPOTENCY_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport class WebhookIdempotencyStore {\n constructor(private readonly cache: ICache) {}\n\n /**\n * Check if this delivery has already been processed, and mark it atomically.\n * Keys are scoped by namespaceId to prevent cross-tenant pollution.\n *\n * @returns `true` if duplicate (already processed), `false` if first time\n */\n async checkAndMark(namespaceId: string, pluginId: string, event: string, key: string): Promise<boolean> {\n const cacheKey = `webhook:idempotency:${namespaceId}:${pluginId}:${event}:${key}`;\n const isNew = await this.cache.setIfNotExists(cacheKey, 1, IDEMPOTENCY_TTL_MS);\n return !isNew; // true = duplicate\n }\n}\n","/**\n * @module webhook/auth\n *\n * Webhook delivery authentication — three strategies:\n *\n * - `secret`: static header comparison (`timingSafeEqual`)\n * - `hmac`: HMAC-SHA256 over raw body (`timingSafeEqual`)\n * - `custom`: calls a plugin validator handler via `backend.execute`\n *\n * All strategies support a previous-secret grace window for zero-downtime\n * rotation: if the current secret doesn't match, fall back to `previous`\n * provided it hasn't expired.\n *\n * Never throws — returns `{ valid: false, reason }` on any error so the\n * caller always gets a structured result to act on.\n */\n\nimport { createHmac, timingSafeEqual, randomBytes } from 'node:crypto';\nimport type { WebhookAuthConfig } from '@kb-labs/plugin-contracts';\nimport type { WebhookSecretEntry, WebhookSecretStore } from './secret-store.js';\n\nexport type WebhookAuthResult = { valid: true } | { valid: false; reason: string };\n\nexport interface WebhookAuthRequest {\n headers: Record<string, string | string[] | undefined>;\n rawBody: Buffer;\n namespaceId: string;\n pluginId: string;\n event: string;\n instanceId?: string;\n}\n\n/** Minimal interface for execution backend — only `execute` is needed here. */\ninterface ExecutionBackend {\n execute(input: { handlerRef: string; pluginRoot: string; input: unknown }): Promise<unknown>;\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/** Extract a single header value (case-insensitive). */\nfunction getHeader(headers: Record<string, string | string[] | undefined>, name: string): string | undefined {\n const lower = name.toLowerCase();\n const value = headers[lower] ?? headers[name];\n return Array.isArray(value) ? value[0] : value;\n}\n\n/**\n * Constant-time string comparison.\n *\n * Uses HMAC over a random session key so both inputs are hashed to the same\n * fixed length (32 bytes) before comparison — eliminates length-based\n * timing side-channels that would otherwise occur when short-circuiting on\n * `a.length !== b.length`.\n */\nconst _SESSION_KEY = randomBytes(32);\n\nfunction safeEqual(a: string, b: string): boolean {\n const ha = createHmac('sha256', _SESSION_KEY).update(a).digest();\n const hb = createHmac('sha256', _SESSION_KEY).update(b).digest();\n return timingSafeEqual(ha, hb);\n}\n\nfunction isPreviousValid(entry: WebhookSecretEntry): boolean {\n return (\n entry.previous !== undefined &&\n entry.previousExpiresAt !== undefined &&\n entry.previousExpiresAt > Date.now()\n );\n}\n\n// ── Strategy implementations ──────────────────────────────────────────────────\n\nfunction verifySecret(\n header: string,\n headers: Record<string, string | string[] | undefined>,\n entry: WebhookSecretEntry,\n): boolean {\n const value = getHeader(headers, header);\n if (!value) {\n return false;\n }\n\n if (safeEqual(value, entry.current)) {\n return true;\n }\n\n if (isPreviousValid(entry) && safeEqual(value, entry.previous!)) {\n return true;\n }\n\n return false;\n}\n\nfunction computeHmac(body: Buffer, secret: string): string {\n return createHmac('sha256', secret).update(body).digest('hex');\n}\n\nfunction verifyHmac(\n header: string,\n prefix: string | undefined,\n rawBody: Buffer,\n headers: Record<string, string | string[] | undefined>,\n entry: WebhookSecretEntry,\n): boolean {\n const headerValue = getHeader(headers, header);\n if (!headerValue) {\n return false;\n }\n\n // Strip prefix if configured\n const receivedSig = prefix && headerValue.startsWith(prefix)\n ? headerValue.slice(prefix.length)\n : headerValue;\n\n const expectedCurrent = computeHmac(rawBody, entry.current);\n if (safeEqual(receivedSig, expectedCurrent)) {\n return true;\n }\n\n if (isPreviousValid(entry)) {\n const expectedPrevious = computeHmac(rawBody, entry.previous!);\n if (safeEqual(receivedSig, expectedPrevious)) {\n return true;\n }\n }\n\n return false;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport async function verifyWebhookAuth(\n authConfig: WebhookAuthConfig,\n req: WebhookAuthRequest,\n secretStore: WebhookSecretStore,\n backend?: ExecutionBackend,\n pluginRoot?: string,\n): Promise<WebhookAuthResult> {\n const entry = await secretStore.get(req.namespaceId, req.pluginId, req.event, req.instanceId);\n\n if (!entry) {\n return { valid: false, reason: 'not provisioned' };\n }\n\n switch (authConfig.type) {\n case 'secret': {\n const valid = verifySecret(authConfig.header, req.headers, entry);\n return valid ? { valid: true } : { valid: false, reason: 'invalid secret' };\n }\n\n case 'hmac': {\n const valid = verifyHmac(authConfig.header, authConfig.prefix, req.rawBody, req.headers, entry);\n return valid ? { valid: true } : { valid: false, reason: 'invalid hmac signature' };\n }\n\n case 'custom': {\n if (!backend || !pluginRoot) {\n return { valid: false, reason: 'custom validator requires backend and pluginRoot' };\n }\n try {\n // Send HMAC of the body (not the raw secret) so the validator can\n // verify without ever receiving the plaintext secret.\n const bodyHmac = createHmac('sha256', entry.current).update(req.rawBody).digest('hex');\n const result = await backend.execute({\n handlerRef: authConfig.validator,\n pluginRoot,\n input: {\n headers: req.headers,\n rawBody: req.rawBody.toString('base64'),\n bodyHmac,\n },\n }) as { valid: boolean };\n return result.valid ? { valid: true } : { valid: false, reason: 'custom validator rejected' };\n } catch {\n return { valid: false, reason: 'validator error' };\n }\n }\n }\n}\n","/**\n * @module webhook/router\n *\n * Registers Fastify routes for manifest-declared webhook handlers.\n *\n * Route patterns:\n * POST /webhooks/:pluginId/:event (single-instance)\n * POST /webhooks/:pluginId/:event/:instanceId (multi: true)\n *\n * Per-request pipeline:\n * 1. Lookup declaration → 404 if unknown pluginId/event\n * 2. x-kb-namespace header → 400 if missing\n * 3. Rate limit via IResourceBroker → 429 if denied\n * 4. Challenge response → 200 (before auth, intentional for Slack handshake)\n * 5. Idempotency dedup → 200 early if duplicate delivery\n * 6. Auth (secret / hmac / custom) → 401 on failure\n * 7. Dispatch via globalDispatcher → 200 sync / 202 async\n *\n * Security: missing auth on any declaration causes startup rejection.\n * Plugin code never runs in-process — always dispatched via globalDispatcher.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { Readable } from 'node:stream';\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type { ManifestV3, WebhookHandlerDecl } from '@kb-labs/plugin-contracts';\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { IResourceBroker } from '@kb-labs/core-resource-broker';\nimport { globalDispatcher } from '../hosts/dispatcher.js';\nimport { WebhookSecretStore } from './secret-store.js';\nimport { WebhookIdempotencyStore } from './idempotency-store.js';\nimport { verifyWebhookAuth, type WebhookAuthRequest } from './auth.js';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface WebhookManifestEntry {\n pluginId: string;\n manifest: ManifestV3;\n pluginRoot: string;\n}\n\nexport interface RegisterWebhookRoutesOptions {\n cache: ICache;\n broker: IResourceBroker;\n logger: ILogger;\n manifests: WebhookManifestEntry[];\n baseUrl?: string;\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/** Extract a nested value by dot-separated path (e.g. 'delivery.id'). */\nfunction getByDotPath(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (!current || typeof current !== 'object') { return undefined; }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\n/** Entry in the per-plugin declaration lookup map. */\ninterface DeclEntry {\n pluginId: string;\n decl: WebhookHandlerDecl;\n pluginRoot: string;\n manifest: ManifestV3;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Register webhook routes from plugin manifests.\n *\n * @returns Number of webhook routes registered.\n * @throws If any declaration is missing an `auth` config.\n */\nexport async function registerWebhookRoutes(\n scope: FastifyInstance,\n options: RegisterWebhookRoutesOptions,\n): Promise<number> {\n const { cache, broker, logger, manifests } = options;\n\n const secretStore = new WebhookSecretStore(cache);\n const idempotencyStore = new WebhookIdempotencyStore(cache);\n\n // Build lookup maps, validate, register rate limits\n const declMap = new Map<string, DeclEntry>();\n let needsRawBody = false;\n\n for (const entry of manifests) {\n const { pluginId, manifest, pluginRoot } = entry;\n if (!manifest.webhooks?.handlers.length) { continue; }\n\n for (const decl of manifest.webhooks.handlers) {\n if (!decl.auth) {\n throw new Error(`webhook '${pluginId}/${decl.event}' has no auth config`);\n }\n\n const mapKey = `${pluginId}:${decl.event}:${decl.multi ? 'multi' : 'single'}`;\n declMap.set(mapKey, { pluginId, decl, pluginRoot, manifest });\n\n broker.registerLimit(`webhook:${pluginId}:${decl.event}`, {\n requestsPerMinute: decl.rateLimit?.requestsPerMinute ?? 60,\n });\n\n if (decl.auth.type === 'hmac' || decl.auth.type === 'custom') {\n needsRawBody = true;\n }\n }\n }\n\n if (declMap.size === 0) { return 0; }\n\n // Capture raw body for HMAC / custom auth verification.\n // NOTE: this scope must contain only webhook delivery routes — the preParsing\n // hook fires for every route registered here, buffering the body each time.\n if (needsRawBody) {\n scope.addHook('preParsing', async (_request, _reply, payload) => {\n const chunks: Buffer[] = [];\n for await (const chunk of payload) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as unknown as string));\n }\n const body = Buffer.concat(chunks);\n _request.rawBody = body;\n return Readable.from(body);\n });\n }\n\n // ── Single-instance handler ─────────────────────────────────────────────────\n // NOTE: pluginIds containing '/' (e.g. @scope/name) must be URL-encoded by\n // callers: '@scope%2Fname' → Fastify decodes back to '@scope/name' in params.\n\n scope.post<{ Params: { pluginId: string; event: string } }>(\n '/webhooks/:pluginId/:event',\n async (request, reply) => {\n const { pluginId, event } = request.params;\n const entry = declMap.get(`${pluginId}:${event}:single`);\n if (!entry) {\n return reply.code(404).send({ error: 'Webhook not found' });\n }\n\n return handleWebhook({ request, reply, entry, namespaceHeader: request.headers['x-kb-namespace'], instanceId: undefined, secretStore, idempotencyStore, broker, logger });\n },\n );\n\n // ── Multi-instance handler ──────────────────────────────────────────────────\n\n scope.post<{ Params: { pluginId: string; event: string; instanceId: string } }>(\n '/webhooks/:pluginId/:event/:instanceId',\n async (request, reply) => {\n const { pluginId, event, instanceId } = request.params;\n const entry = declMap.get(`${pluginId}:${event}:multi`);\n if (!entry) {\n return reply.code(404).send({ error: 'Webhook not found' });\n }\n\n return handleWebhook({ request, reply, entry, namespaceHeader: request.headers['x-kb-namespace'], instanceId, secretStore, idempotencyStore, broker, logger });\n },\n );\n\n return declMap.size;\n}\n\n// ── Per-request handler ───────────────────────────────────────────────────────\n\ninterface HandleWebhookArgs {\n request: FastifyRequest;\n reply: FastifyReply;\n entry: DeclEntry;\n namespaceHeader: string | string[] | undefined;\n instanceId: string | undefined;\n secretStore: WebhookSecretStore;\n idempotencyStore: WebhookIdempotencyStore;\n broker: IResourceBroker;\n logger: ILogger;\n}\n\nasync function handleWebhook({\n request,\n reply,\n entry,\n namespaceHeader,\n instanceId,\n secretStore,\n idempotencyStore,\n broker,\n logger,\n}: HandleWebhookArgs): Promise<unknown> {\n const { pluginId, decl, pluginRoot, manifest } = entry;\n\n // Step 1: Resolve namespace\n const namespaceId = Array.isArray(namespaceHeader) ? namespaceHeader[0] : namespaceHeader;\n if (!namespaceId) {\n return reply.code(400).send({ error: 'Missing required header: x-kb-namespace' });\n }\n\n // Step 2: Rate limit\n // Use the unconditional try/finally pattern: release() is a no-op when allowed=false,\n // so the finally block is safe regardless of whether the request was accepted.\n const rateResource = `webhook:${pluginId}:${decl.event}`;\n const acquired = await broker.tryAcquire(rateResource);\n\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({\n error: 'Too Many Requests',\n retryAfterMs: acquired.waitTimeMs ?? null,\n });\n }\n\n // Step 3: Challenge (before auth — Slack-style handshake)\n if (decl.challenge && request.body) {\n const fieldValue = getByDotPath(request.body, decl.challenge.bodyPath);\n if (fieldValue === decl.challenge.value) {\n const replyValue = getByDotPath(request.body, decl.challenge.replyPath);\n // Use the last path segment as the JSON key so dot-paths like\n // 'data.token' reply with { token: value } not { 'data.token': value }.\n const replyKey = decl.challenge.replyPath.split('.').pop()!;\n return reply.code(200).send({ [replyKey]: replyValue });\n }\n }\n\n // Step 4: Auth\n // rawBody is set by the preParsing hook for hmac/custom auth types.\n // Fallback: re-serialize from parsed body for secret auth (no raw body needed).\n // Use empty Buffer for null/undefined body to avoid JSON.stringify artifacts\n // that would break HMAC verification (e.g. stringify(null) = \"null\").\n const rawBody: Buffer = request.rawBody\n ?? (request.body == null\n ? Buffer.alloc(0)\n : Buffer.from(typeof request.body === 'string' ? request.body : JSON.stringify(request.body)));\n\n const authReq: WebhookAuthRequest = {\n headers: request.headers as Record<string, string | string[] | undefined>,\n rawBody,\n namespaceId,\n pluginId,\n event: decl.event,\n instanceId,\n };\n\n const authBackend = decl.auth.type === 'custom'\n ? makeAuthBackend(namespaceId, pluginId)\n : undefined;\n\n const authResult = await verifyWebhookAuth(decl.auth, authReq, secretStore, authBackend, pluginRoot);\n if (!authResult.valid) {\n return reply.code(401).send({ error: 'Unauthorized', reason: authResult.reason });\n }\n\n // Step 5: Idempotency dedup — after auth to prevent unauthenticated callers\n // from poisoning keys and blocking legitimate deliveries (DoS vector).\n // External services that retry deliveries carry the same signature, so they\n // pass auth before hitting the dedup check.\n if (decl.idempotencyKey && request.body) {\n const deliveryKey = getByDotPath(request.body, decl.idempotencyKey);\n if (typeof deliveryKey === 'string') {\n const isDuplicate = await idempotencyStore.checkAndMark(namespaceId, pluginId, decl.event, deliveryKey);\n if (isDuplicate) {\n return reply.code(200).send({ status: 'duplicate' });\n }\n }\n }\n\n // Step 6: Build host context\n const webhookId = randomUUID();\n const hostContext = {\n host: 'webhook' as const,\n event: decl.event,\n source: request.ip,\n payload: request.body,\n namespaceId,\n webhookId,\n ...(instanceId !== undefined ? { instanceId } : {}),\n };\n\n // Step 7: Resolve execution host\n const hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n if (!hostId) {\n return reply.code(503).send({ error: 'No execution host connected' });\n }\n\n const dispatchArgs = [{\n pluginId,\n handlerRef: decl.handler,\n input: request.body,\n executionId: webhookId,\n requestId: webhookId,\n descriptor: {\n hostType: 'webhook' as const,\n hostContext,\n pluginId,\n pluginVersion: manifest.version,\n requestId: webhookId,\n permissions: decl.permissions ?? [],\n },\n }];\n\n // Step 8: Dispatch\n if (decl.async) {\n reply.code(202).send({ status: 'accepted', webhookId });\n void globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', dispatchArgs).catch((err: unknown) => {\n logger.error(\n 'Webhook async dispatch failed',\n err instanceof Error ? err : new Error(String(err)),\n { pluginId, event: decl.event, webhookId },\n );\n });\n return;\n }\n\n try {\n const result = await globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', dispatchArgs);\n return reply.code(200).send({ status: 'ok', webhookId, result });\n } catch (err) {\n logger.error(\n 'Webhook dispatch failed',\n err instanceof Error ? err : new Error(String(err)),\n { pluginId, event: decl.event, webhookId },\n );\n return reply.code(500).send({ error: 'Dispatch failed' });\n }\n } finally {\n await acquired.release();\n }\n}\n\n// ── Auth execution backend for 'custom' auth type ─────────────────────────────\n\nfunction makeAuthBackend(\n namespaceId: string,\n pluginId: string,\n): {\n execute(input: { handlerRef: string; pluginRoot: string; input: unknown }): Promise<unknown>;\n} {\n return {\n async execute({ handlerRef, pluginRoot, input }) {\n const hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n if (!hostId) { throw new Error('No execution host connected for custom auth'); }\n // Pass pluginId so the host-agent's LocalPluginResolver can find the plugin root,\n // and pluginRoot as an absolute path hint for environments that support it.\n return globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', [\n { pluginId, handlerRef, pluginRoot, input },\n ]);\n },\n };\n}\n","import Fastify from 'fastify';\nimport fastifyCookie from '@fastify/cookie';\nimport fastifyCors from '@fastify/cors';\nimport fastifyHttpProxy from '@fastify/http-proxy';\nimport { platform, getAdapterStatus } from '@kb-labs/core-runtime';\nimport {\n createCorrelatedLogger,\n createServiceReadyResponse,\n registerOpenAPI,\n} from '@kb-labs/shared-http';\nimport { logDiagnosticEvent, type ICache, type ILogger, type IServiceTransport } from '@kb-labs/core-platform';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\nimport { HostRegistrationSchema } from '@kb-labs/gateway-contracts';\nimport {\n AuthService,\n type JwtConfig,\n type UsersStore,\n type SessionsStore,\n type InvitesStore,\n type ProviderRegistry,\n type IPolicyDecisionPoint,\n type TenantResolver,\n type RateLimiter,\n type OAuthStateStore,\n} from '@kb-labs/gateway-auth';\nimport { createAuthMiddleware } from './auth/middleware.js';\nimport { registerAuthRoutes, type MachineAuthRoutesUserExt } from './auth/routes.js';\nimport { createUserAuthMiddleware } from './auth/user-auth-middleware.js';\nimport { registerUserAuthRoutes, createUserRefreshFn, type UserAuthServiceForRoutes } from './auth/user-routes.js';\nimport { registerExecuteRoutes } from './execute/routes.js';\nimport { registerLLMGatewayRoutes } from './llm/routes.js';\nimport { registerTelemetryRoutes } from './telemetry/routes.js';\nimport { registerPlatformRoutes } from './platform/routes.js';\nimport { registerAggregatedDocsRoutes } from './docs/routes.js';\nimport { HostRegistry } from './hosts/registry.js';\nimport { attachGatewayWs, type SocketWsUpstream } from './ws/gateway-ws.js';\nimport { GatewayObservabilityCollector } from './observability/collector.js';\nimport { randomUUID } from 'node:crypto';\nimport { registerInternalRoutes } from './internal/routes.js';\nimport {\n createPressureOnRequest,\n createPressurePreHandler,\n createPressureOnResponse,\n} from './pressure/index.js';\nimport { globalDispatcher } from './hosts/dispatcher.js';\nimport { registerWebhookAdminRoutes } from './webhook/admin-routes.js';\nimport { registerWebhookRoutes, type WebhookManifestEntry } from './webhook/router.js';\n\n/**\n * User-auth dependencies injected from bootstrap. All fields optional so\n * the server can start without a documentDatabase adapter (degraded mode).\n */\nexport interface UserAuthServerDeps {\n userAuthService: UserAuthServiceForRoutes;\n users: UsersStore;\n sessions: SessionsStore;\n invites: InvitesStore;\n providers: ProviderRegistry;\n pdp: IPolicyDecisionPoint;\n tenantResolver: TenantResolver;\n cookieSecure: boolean;\n accessTtlSec: number;\n refreshTtlSec: number;\n inviteTtlMs: number;\n rateLimiter?: RateLimiter;\n authRateLimit?: { loginPerIpPerMinute: number; loginPerEmailPerMinute: number };\n /** OAuth state store (KV-backed). When present, redirect/OAuth routes are registered. */\n oauthState?: OAuthStateStore;\n /** Per-IP callback rate-limit for the OAuth callback. */\n oauthCallbackPerIpPerMinute?: number;\n}\n\n/** Strip bearer tokens from query params before logging (prevents JWT leakage in access logs). */\nfunction redactQueryToken(url: string): string {\n return url.replace(/([?&]access_token=)[^&]*/gi, '$1[REDACTED]');\n}\n\nexport async function createServer(\n config: GatewayConfig,\n cache: ICache,\n logger: ILogger,\n jwtConfig: JwtConfig,\n registry: HostRegistry | undefined,\n serviceTransport: IServiceTransport,\n userAuth?: UserAuthServerDeps,\n webhookManifests?: WebhookManifestEntry[],\n) {\n const gatewayLogger = createCorrelatedLogger(logger, {\n serviceId: 'gateway',\n logsSource: 'gateway',\n layer: 'gateway',\n service: 'server',\n operation: 'gateway.http',\n });\n const app = Fastify({\n logger: false,\n // CD-10: gateway sits behind nginx; parse X-Forwarded-For for real client IPs.\n trustProxy: true,\n });\n\n // Cookie parsing — required by user-auth middleware and cookie-based sessions.\n await app.register(fastifyCookie);\n\n const isProduction = process.env.NODE_ENV === 'production';\n\n // OpenAPI / Swagger UI — must be registered before routes\n await registerOpenAPI(app, {\n title: 'KB Labs Gateway',\n description: 'Central API gateway — auth, LLM, telemetry, platform dispatch',\n version: '1.0.0',\n servers: [{ url: 'http://localhost:4000', description: 'Local dev' }],\n ui: !isProduction,\n });\n\n // CORS disabled at gateway level — browser clients (Studio) connect via same-origin or\n // have CORS handled at the reverse-proxy / CDN layer. Reflecting arbitrary origins\n // (origin: true) would allow any attacker site to make credentialed cross-origin requests.\n await app.register(fastifyCors, { origin: false });\n const observability = new GatewayObservabilityCollector(config);\n observability.register(app);\n\n // ── Pressure control (ADR-0056) ────────────────────────────────────\n // Registered BEFORE upstream proxies so 429 is returned before the request\n // is forwarded. No-op when `config.pressure` is absent or disabled.\n if (config.pressure && config.pressure.enabled !== false && platform.hasResourceBroker) {\n const deps = { broker: platform.resourceBroker, logger, config };\n app.addHook('onRequest', createPressureOnRequest(deps));\n app.addHook('onResponse', createPressureOnResponse());\n }\n\n app.addHook('onRequest', async (request, reply) => {\n const requestId = (request.headers['x-request-id'] as string | undefined) || request.id || randomUUID();\n const traceId = (request.headers['x-trace-id'] as string | undefined) || randomUUID();\n\n request.id = requestId;\n reply.header('X-Request-Id', requestId);\n reply.header('X-Trace-Id', traceId);\n\n const safeUrl = redactQueryToken(request.url);\n request.kbLogger = createCorrelatedLogger(logger, {\n serviceId: 'gateway',\n logsSource: 'gateway',\n layer: 'gateway',\n service: 'request',\n requestId,\n traceId,\n method: request.method,\n url: safeUrl,\n operation: 'http.request',\n });\n request.kbLogger.info(`→ ${request.method.toUpperCase()} ${safeUrl}`);\n });\n\n app.addHook('onResponse', async (request, reply) => {\n const requestLogger = request.kbLogger;\n if (!requestLogger) {\n return;\n }\n\n const safeUrl = redactQueryToken(request.url);\n requestLogger.info(`✓ ${request.method.toUpperCase()} ${safeUrl} ${reply.statusCode}`, {\n statusCode: reply.statusCode,\n });\n });\n\n // ── Auth (B-023 fix) ────────────────────────────────────────────────\n // Registered globally on `app`, BEFORE the proxy upstreams below, so it\n // actually covers proxied routes (/api/v1/*, /api/exec/*, etc.) and not\n // just the gateway's own /auth/* routes. A prior version scoped these\n // hooks inside the `gatewayRoutes` child plugin registered AFTER the\n // proxy loop — Fastify hook encapsulation meant they never ran for\n // proxied requests, and rest-api/workflow/marketplace do not enforce\n // auth themselves, so every proxied route was reachable with no token\n // at all (confirmed: garbage Bearer token still got 200 on\n // /api/v1/studio/registry). Mirrors the pressure-hook precedent above,\n // which already runs globally ahead of the proxy loop for the same reason.\n //\n // User-auth middleware runs FIRST (before machine Bearer check).\n // Validates kb_access cookie, cross-tenant guard, CD-1 status check.\n // No-op when no cookie is present — machine auth takes over.\n if (userAuth) {\n app.addHook(\n 'onRequest',\n createUserAuthMiddleware({\n users: userAuth.users,\n tenantResolver: userAuth.tenantResolver,\n jwtConfig,\n }),\n );\n }\n\n // Machine Bearer middleware — skips if userAuthContext already set by above.\n // When auth is disabled (solo/local), the middleware runs every request as\n // the local admin (B-023).\n app.addHook(\n 'onRequest',\n createAuthMiddleware(cache, jwtConfig, { authEnabled: config.auth?.enabled !== false }),\n );\n\n // ── Proxy upstreams ────────────────────────────────────────────────\n // Connection details (baseUrl, socketPath) come from IServiceTransport.\n // WS-enabled upstreams bound to a unix socket: @fastify/http-proxy can't dial\n // unix sockets for WS upgrades, so the gateway proxies those WS itself (see\n // attachGatewayWs). HTTP for the same prefix still goes through http-proxy.\n const socketWsUpstreams: SocketWsUpstream[] = [];\n\n for (const [name, upstream] of Object.entries(config.upstreams)) {\n const conn = serviceTransport.connectionInfo(upstream.serviceId);\n if (!conn) {\n throw new Error(\n `Gateway startup error: no transport config for upstream \"${name}\" (serviceId: \"${upstream.serviceId}\"). ` +\n `Configure @kb-labs/adapters-service-transport-http as adapterOptions.serviceTransport.services in kb.config.json.`,\n );\n }\n // A WS upstream on a unix socket is handled by the gateway's own dialer, not\n // by http-proxy's websocket support (which only works over TCP).\n const wsOverSocket = Boolean(upstream.websocket) && Boolean(conn.socketPath);\n if (wsOverSocket) {\n socketWsUpstreams.push({\n prefix: upstream.prefix,\n rewritePrefix: upstream.rewritePrefix ?? upstream.prefix,\n socketPath: conn.socketPath!,\n });\n }\n await app.register(fastifyHttpProxy, {\n upstream: conn.baseUrl,\n prefix: upstream.prefix,\n rewritePrefix: upstream.rewritePrefix ?? upstream.prefix,\n disableCache: true,\n // Disable http-proxy WS for socket upstreams — the gateway dialer owns it.\n websocket: wsOverSocket ? false : (upstream.websocket ?? false),\n undici: {\n // Restore 1-hour body timeout for SSE streams and large transfers.\n // undici defaults: headersTimeout=30s, bodyTimeout=300s — too short for streaming.\n bodyTimeout: 3_600_000,\n ...(conn.socketPath ? { socketPath: conn.socketPath } : {}),\n },\n });\n const connDesc = conn.socketPath ? `${conn.baseUrl} (unix:${conn.socketPath})` : conn.baseUrl;\n const wsDesc = upstream.websocket ? (wsOverSocket ? ', ws→unix' : ', ws') : '';\n gatewayLogger.info(`Upstream registered: ${name} → ${connDesc} (${upstream.prefix}${wsDesc})`);\n }\n\n // ── Gateway's own routes ────────────────────────────────────────────\n // Auth hooks now run globally (see above) and already cover these routes\n // via Fastify's hook inheritance (parent hooks apply to child-registered\n // routes), so they are not repeated here.\n await app.register(async function gatewayRoutes(scope) {\n // Per-tenant pressure (ADR-0056). Runs after auth so AuthContext is set.\n if (config.pressure?.perTenant?.enabled === true && platform.hasResourceBroker) {\n scope.addHook(\n 'preHandler',\n createPressurePreHandler({ broker: platform.resourceBroker, logger, config }),\n );\n }\n\n // Machine auth routes (/auth/register, /auth/token, /auth/refresh).\n // When userAuth is available, wire user cookie refresh into /auth/refresh.\n const authService = new AuthService(cache, jwtConfig);\n const userExt: MachineAuthRoutesUserExt | undefined = userAuth\n ? {\n userRefreshFn: createUserRefreshFn({\n userAuthService: userAuth.userAuthService,\n cookieOpts: { cookieSecure: userAuth.cookieSecure },\n }),\n pdp: userAuth.pdp,\n }\n : undefined;\n registerAuthRoutes(scope as unknown as Parameters<typeof registerAuthRoutes>[0], authService, userExt);\n\n // User-auth routes — all new endpoints + /auth/me.\n if (userAuth) {\n registerUserAuthRoutes(\n scope as unknown as Parameters<typeof registerUserAuthRoutes>[0],\n {\n userAuthService: userAuth.userAuthService,\n users: userAuth.users,\n sessions: userAuth.sessions,\n invites: userAuth.invites,\n providers: userAuth.providers,\n pdp: userAuth.pdp,\n tenantResolver: userAuth.tenantResolver,\n cookieOpts: { cookieSecure: userAuth.cookieSecure },\n accessTtlSec: userAuth.accessTtlSec,\n refreshTtlSec: userAuth.refreshTtlSec,\n inviteTtlMs: userAuth.inviteTtlMs,\n jwtConfig,\n rateLimiter: userAuth.rateLimiter,\n authRateLimit: userAuth.authRateLimit,\n oauthState: userAuth.oauthState,\n oauthCallbackPerIpPerMinute: userAuth.oauthCallbackPerIpPerMinute,\n },\n );\n }\n\n // Health (public) — comprehensive adapter + upstream health\n const HEALTH_CACHE_KEY = '__gateway_health';\n const HEALTH_CACHE_TTL = 15_000; // 15s cache to prevent health DDoS\n const startupTime = Date.now();\n\n const collectHealthSnapshot = async () => {\n const cached = await cache.get<Record<string, unknown>>(HEALTH_CACHE_KEY).catch(() => null);\n if (cached) {\n return cached;\n }\n\n const adapterNames = ['llm', 'cache', 'analytics', 'vectorStore', 'embeddings'] as const;\n const adapters: Record<string, { available: boolean; latencyMs?: number }> = {};\n\n for (const name of adapterNames) {\n await observability.observeOperation(`gateway.adapter.${name}`, async () => {\n const probeStart = Date.now();\n try {\n // Try direct property first (production runtime stores adapters as platform.llm etc.),\n // then fall back to getAdapter() for environments where only that API is available.\n type FlexPlatform = Record<string, unknown> & { getAdapter?: (n: string) => unknown };\n const pf = platform as unknown as FlexPlatform;\n const adapter = pf[name] ?? pf.getAdapter?.(name);\n adapters[name] = { available: !!adapter, latencyMs: Date.now() - probeStart };\n } catch {\n adapters[name] = { available: false, latencyMs: Date.now() - probeStart };\n }\n });\n }\n\n const upstreams: Record<string, { status: string; latencyMs?: number }> = {};\n for (const [name, upstream] of Object.entries(config.upstreams)) {\n await observability.observeOperation(`gateway.upstream.${name}.health`, async () => {\n const probeStart = Date.now();\n try {\n const res = await serviceTransport.call(upstream.serviceId, {\n path: '/health',\n signal: AbortSignal.timeout(2000),\n });\n const latencyMs = Date.now() - probeStart;\n upstreams[name] = { status: res.ok ? 'up' : 'down', latencyMs };\n if (!res.ok) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.upstream.health',\n level: 'warn',\n reasonCode: 'upstream_unavailable',\n message: 'Gateway upstream health probe failed',\n outcome: 'failed',\n serviceId: 'gateway',\n route: `${upstream.prefix}/health`,\n evidence: {\n upstreamId: name,\n serviceId: upstream.serviceId,\n statusCode: res.statusCode,\n latencyMs,\n },\n });\n }\n } catch (error) {\n const latencyMs = Date.now() - probeStart;\n upstreams[name] = { status: 'down', latencyMs };\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.upstream.health',\n level: 'warn',\n reasonCode: 'upstream_unavailable',\n message: 'Gateway upstream health probe failed',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n route: `${upstream.prefix}/health`,\n evidence: {\n upstreamId: name,\n serviceId: upstream.serviceId,\n latencyMs,\n },\n });\n }\n });\n }\n\n const llmOk = adapters.llm?.available ?? false;\n const allOk = Object.values(adapters).every((a) => a.available);\n const snapshot = {\n status: llmOk ? (allOk ? 'healthy' : 'degraded') : 'unhealthy',\n version: '1.0',\n uptime: Math.floor((Date.now() - startupTime) / 1000),\n timestamp: new Date().toISOString(),\n adapters,\n upstreams,\n };\n\n await cache.set(HEALTH_CACHE_KEY, snapshot, HEALTH_CACHE_TTL).catch(() => {});\n return snapshot;\n };\n\n scope.get('/health', { schema: { tags: ['System'], summary: 'Gateway health check' } }, async () => {\n return collectHealthSnapshot();\n });\n\n scope.get('/health/adapters', {\n schema: {\n tags: ['System'],\n summary: 'Platform adapter status — mode (real | inmemory | noop) per slot',\n },\n }, async () => {\n return getAdapterStatus();\n });\n\n scope.get('/ready', { schema: { tags: ['System'], summary: 'Gateway readiness check' } }, async (_request, reply) => {\n const health = await collectHealthSnapshot();\n const upstreams = (health.upstreams as Record<string, { status?: string }> | undefined) ?? {};\n const missingRequiredUpstreams = ['rest']\n .filter((id) => (upstreams[id]?.status ?? 'down') !== 'up');\n const ready = missingRequiredUpstreams.length === 0;\n\n return reply.code(ready ? 200 : 503).send(createServiceReadyResponse({\n ready,\n status: ready ? 'ready' : 'degraded',\n reason: ready ? 'ready' : `upstream_unavailable:${missingRequiredUpstreams.join(',')}`,\n components: {\n gatewayAdapters: {\n ready: true,\n },\n restUpstream: {\n ready: (upstreams.rest?.status ?? 'down') === 'up',\n status: upstreams.rest?.status ?? 'down',\n },\n workflowUpstream: {\n ready: (upstreams.workflow?.status ?? 'down') === 'up',\n status: upstreams.workflow?.status ?? 'down',\n },\n marketplaceUpstream: {\n ready: (upstreams.marketplace?.status ?? 'down') === 'up',\n status: upstreams.marketplace?.status ?? 'down',\n },\n },\n }));\n });\n\n scope.get('/metrics', { schema: { tags: ['Observability'], summary: 'Gateway metrics in Prometheus format' } }, async (_request, reply) => {\n const health = await collectHealthSnapshot();\n const status = (health.status as 'healthy' | 'degraded' | 'unhealthy' | undefined) ?? 'healthy';\n reply.header('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');\n return observability.renderPrometheusMetrics(status);\n });\n\n scope.get('/observability/describe', {\n schema: { tags: ['Observability'], summary: 'Gateway observability contract descriptor' },\n }, async () => observability.buildDescribe());\n\n scope.get('/observability/health', {\n schema: { tags: ['Observability'], summary: 'Gateway observability health snapshot' },\n }, async () => {\n const health = await collectHealthSnapshot();\n const adapterChecks = Object.entries((health.adapters as Record<string, { available?: boolean; latencyMs?: number }> | undefined) ?? {})\n .map(([id, value]) => ({ id, available: !!value?.available, latencyMs: value?.latencyMs }));\n const upstreamChecks = Object.entries((health.upstreams as Record<string, { status?: string; latencyMs?: number }> | undefined) ?? {})\n .map(([id, value]) => ({ id, status: value?.status ?? 'unknown', latencyMs: value?.latencyMs }));\n const status = (health.status as 'healthy' | 'degraded' | 'unhealthy' | undefined) ?? 'healthy';\n return observability.buildHealth({ status, adapterChecks, upstreamChecks });\n });\n\n // Host registration (public)\n // Use injected registry (with persistence) or fallback to cache-only\n if (!registry) {\n gatewayLogger.warn('No persistent HostRegistry injected — hosts will be lost on restart');\n }\n const hostRegistry = registry ?? new HostRegistry(cache);\n scope.post('/hosts/register', { schema: { tags: ['Hosts'], summary: 'Register a host' } }, async (request, reply) => {\n const parsed = HostRegistrationSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n const result = await hostRegistry.register(parsed.data);\n return reply.code(201).send({\n hostId: result.descriptor.hostId,\n machineToken: result.machineToken,\n status: result.descriptor.status,\n });\n });\n\n // List hosts (auth required)\n scope.get('/hosts', { schema: { tags: ['Hosts'], summary: 'List registered hosts' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n const hosts = await hostRegistry.list(auth.namespaceId);\n return { hosts };\n });\n\n // Get host by ID (auth required)\n scope.get<{ Params: { hostId: string } }>('/hosts/:hostId', { schema: { tags: ['Hosts'], summary: 'Get host by ID' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n const { hostId } = request.params;\n const host = await hostRegistry.get(hostId, auth.namespaceId);\n if (!host) {\n return reply.code(404).send({ error: 'Host not found' });\n }\n return host;\n });\n\n // Deregister host (auth required)\n scope.delete<{ Params: { hostId: string } }>('/hosts/:hostId', { schema: { tags: ['Hosts'], summary: 'Deregister a host' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n const { hostId } = request.params;\n const deleted = await hostRegistry.deregister(hostId, auth.namespaceId);\n if (!deleted) {\n return reply.code(404).send({ error: 'Host not found' });\n }\n return reply.code(204).send();\n });\n\n // Execute endpoint — public API for CLI/Studio clients (auth required)\n registerExecuteRoutes(scope as unknown as Parameters<typeof registerExecuteRoutes>[0], logger);\n\n // AI Gateway — OpenAI-compatible LLM endpoint (auth required)\n registerLLMGatewayRoutes(scope as unknown as Parameters<typeof registerLLMGatewayRoutes>[0], logger);\n\n // Telemetry ingestion — unified event collection (auth required)\n registerTelemetryRoutes(scope as unknown as Parameters<typeof registerTelemetryRoutes>[0], logger);\n\n // Unified Platform API — single dispatch for any adapter (auth required)\n registerPlatformRoutes(scope as unknown as Parameters<typeof registerPlatformRoutes>[0], logger);\n\n // Aggregated docs — /openapi-merged.json + /docs-all\n registerAggregatedDocsRoutes(scope as unknown as Parameters<typeof registerAggregatedDocsRoutes>[0], config, serviceTransport, cache);\n\n\n registerInternalRoutes(scope as unknown as Parameters<typeof registerInternalRoutes>[0], process.env.GATEWAY_INTERNAL_SECRET, hostRegistry, cache);\n\n // Webhook admin routes — provision / list / revoke (auth required, inside scope).\n // Registered unconditionally when the resource broker is available so that the\n // admin API (GET /api/v1/webhooks, POST /api/v1/webhooks/provision, DELETE) works\n // even in environments where no webhook-enabled plugins are currently installed.\n if (platform.hasResourceBroker) {\n const webhookBaseUrl = process.env.GATEWAY_PUBLIC_URL ?? `http://localhost:${config.port + (Number(process.env.KB_NET_OFFSET) || 0)}`;\n // Thin adapter: globalDispatcher.call() requires namespaceId — threaded via optional field\n const provisionBackend = {\n async execute({ handlerRef, pluginRoot, input, namespaceId }: {\n handlerRef: string; pluginRoot: string; input: unknown; namespaceId?: string;\n }): Promise<unknown> {\n if (!namespaceId) { return; }\n const hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n if (!hostId) { return; }\n return globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', [\n { handlerRef, pluginRoot, input },\n ]);\n },\n };\n registerWebhookAdminRoutes(\n scope as unknown as Parameters<typeof registerWebhookAdminRoutes>[0],\n {\n cache,\n logger,\n backend: provisionBackend,\n manifests: webhookManifests ?? [],\n baseUrl: webhookBaseUrl,\n broker: platform.resourceBroker,\n },\n );\n }\n });\n\n // ── Webhook delivery routes (outside gatewayRoutes — no auth middleware) ──────\n // Registered in a separate Fastify scope so both user-auth and machine-token\n // middleware (which live only inside gatewayRoutes) are bypassed automatically.\n // Delivery auth is handled by the webhook router itself (secret / hmac / custom).\n if (webhookManifests?.length && platform.hasResourceBroker) {\n const webhookBaseUrl = process.env.GATEWAY_PUBLIC_URL ?? `http://localhost:${config.port + (Number(process.env.KB_NET_OFFSET) || 0)}`;\n await app.register(async (webhookScope) => {\n await registerWebhookRoutes(webhookScope, {\n cache,\n broker: platform.resourceBroker,\n logger,\n manifests: webhookManifests,\n baseUrl: webhookBaseUrl,\n });\n });\n }\n\n // ── Gateway WebSocket endpoints ────────────────────────────────────\n // Must be after ready() so http-proxy's upgrade listener is registered.\n // attachGatewayWs captures it, removes it, and installs a unified handler\n // that dispatches gateway WS paths to raw ws handlers and delegates\n // everything else (upstream WS proxy) to http-proxy.\n await app.ready();\n attachGatewayWs(app.server, cache, jwtConfig, logger, registry, socketWsUpstreams);\n\n return app;\n}\n","import { logDiagnosticEvent, type IServiceTransport } from '@kb-labs/core-platform';\nimport { createInMemoryDocumentDatabase, createInMemoryKVStore } from '@kb-labs/core-platform/inmemory';\nimport { platform, createServiceBootstrap, getPlatformRoot, getProjectRoot } from '@kb-labs/core-runtime';\nimport { makeAssemblyHook } from '@kb-labs/plugin-runtime';\nimport { createCorrelatedLogger } from '@kb-labs/shared-http';\nimport type { IHostStore } from '@kb-labs/gateway-contracts';\nimport type { IDocumentDatabase } from '@kb-labs/core-platform/adapters';\nimport { HostStore } from '@kb-labs/gateway-core';\nimport {\n UsersStore,\n CredentialsStore,\n MembershipsStore,\n SessionsStore,\n InvitesStore,\n loadIdentityProviders,\n createPasswordPolicy,\n createUserAuthService,\n createStubPDP,\n createTenantResolver,\n createRateLimiter,\n ensureBootstrapAdmin,\n ensureBootstrapCliCredentials,\n AuthService,\n OAuthStateStore,\n} from '@kb-labs/gateway-auth';\nimport type { IKVStore } from '@kb-labs/core-platform/adapters';\nimport { createRegistry } from '@kb-labs/core-registry';\nimport { loadGatewayConfig } from './config.js';\nimport { createServer, type UserAuthServerDeps } from './server.js';\nimport { HostRegistry } from './hosts/registry.js';\nimport { registerPressureLimits } from './pressure/index.js';\nimport type { WebhookManifestEntry } from './webhook/router.js';\n\nexport async function bootstrap(repoRoot: string = process.cwd()): Promise<void> {\n // 1. Initialize platform (loads .env + adapters from kb.config.json)\n await createServiceBootstrap({ appId: 'gateway', repoRoot, assemblyHook: makeAssemblyHook() });\n\n const logger = createCorrelatedLogger(platform.logger, {\n serviceId: 'gateway',\n logsSource: 'gateway',\n layer: 'gateway',\n service: 'bootstrap',\n operation: 'gateway.bootstrap',\n });\n logger.info('Platform initialized', { repoRoot });\n\n // 2. Load gateway config — reads platform baseline + project layer +\n // `.kb/overlays/*.jsonc`. Use the resolved roots from core-runtime\n // (which honour KB_PROJECT_ROOT and the platform.dir override) rather\n // than process.cwd() — in installed mode the gateway process is\n // spawned with cwd at the platform root, and we MUST not conflate\n // that with the project root.\n const config = await loadGatewayConfig(getProjectRoot() ?? repoRoot, getPlatformRoot());\n logger.info('Gateway config loaded', {\n port: config.port,\n upstreams: Object.keys(config.upstreams),\n projectRoot: getProjectRoot() ?? repoRoot,\n platformRoot: getPlatformRoot(),\n configProviderIds: config.auth?.providers ? Object.keys(config.auth.providers) : [],\n });\n\n // 3. Create persistent host store backed by the platform document database.\n // Falls back to an in-memory implementation so user auth works without a\n // configured adapter (dev / CI environments with no external DB).\n // The same code runs on sqlite locally and on postgres/mongo in prod — the\n // gateway has no business knowing which driver is wired underneath.\n let hostStore: IHostStore | undefined;\n const configuredDocs = platform.getAdapter<IDocumentDatabase>('documentDatabase');\n const docs: IDocumentDatabase = configuredDocs ?? createInMemoryDocumentDatabase();\n if (configuredDocs) {\n hostStore = new HostStore(docs);\n logger.info('Host store: documentDatabase-backed (persistent)');\n } else {\n hostStore = new HostStore(docs);\n logger.warn('documentDatabase: in-memory fallback (data lost on restart)');\n logger.warn('Host store: in-memory (hosts will be lost on restart)');\n }\n\n // 3b. User auth infrastructure (ADR-0020). Always available — uses in-memory\n // documentDatabase when no persistent adapter is configured.\n let userAuth: UserAuthServerDeps | undefined;\n {\n // Auth config with explicit defaults (config.auth is optional, fields have zod defaults\n // only when the auth section is present and parsed; here we apply our own fallbacks).\n // Env vars allow E2E CI to override TTLs and cookie security without touching the config\n // file (e.g. AUTH_ACCESS_TTL_SEC=5 for session-lifecycle tests, AUTH_COOKIE_SECURE=false\n // for HTTP-only CI environments).\n const accessTtlSec =\n config.auth?.sessionAccessTtlSec ??\n (process.env.AUTH_ACCESS_TTL_SEC ? parseInt(process.env.AUTH_ACCESS_TTL_SEC, 10) : 900);\n const refreshTtlSec =\n config.auth?.sessionRefreshTtlSec ??\n (process.env.AUTH_REFRESH_TTL_SEC\n ? parseInt(process.env.AUTH_REFRESH_TTL_SEC, 10)\n : 30 * 24 * 3600);\n const graceWindowMs = (config.auth?.refreshGraceWindowSec ?? 5) * 1000;\n const bcryptCost = config.auth?.bcryptCost ?? 12;\n // AUTH_COOKIE_SECURE=false disables Secure flag for HTTP-only CI environments.\n // In production (HTTPS) leave unset or set to true.\n const cookieSecure =\n config.auth?.cookieSecure ??\n (process.env.AUTH_COOKIE_SECURE === 'false' ? false : true);\n const tenantPattern = config.tenants?.pattern ?? '{tenant}.kblabs.ru';\n const bootstrapTenantId =\n config.auth?.bootstrap?.tenantId ??\n process.env.GATEWAY_BOOTSTRAP_TENANT_ID ??\n 'kblabs-cloud';\n\n const users = new UsersStore(docs);\n const credentials = new CredentialsStore(docs);\n const memberships = new MembershipsStore(docs);\n const sessions = new SessionsStore(docs, {\n refreshTtlMs: refreshTtlSec * 1000,\n graceWindowMs,\n });\n const invites = new InvitesStore(docs);\n\n // Identity providers are loaded from config (ADR-0020, DD-3). An\n // empty/absent `auth.providers` registers the built-in email-password\n // door; configured providers (built-in `oidc` or third-party packages)\n // load through the same factory path. Fail-fast on any load error.\n const providers = await loadIdentityProviders(config.auth?.providers, {\n users,\n credentials,\n tenantId: bootstrapTenantId,\n bcryptCost,\n logger,\n });\n\n const passwordPolicy = createPasswordPolicy({\n minLength: config.auth?.passwordPolicy?.minLength ?? 8,\n maxLength: config.auth?.passwordPolicy?.maxLength ?? 256,\n hibpEnabled: config.auth?.passwordPolicy?.hibpEnabled ?? true,\n });\n\n const pdp = createStubPDP({ memberships });\n\n const tenantResolver = createTenantResolver({ pattern: tenantPattern });\n\n const userAuthService = createUserAuthService({\n users,\n credentials,\n memberships,\n sessions,\n invites,\n providers,\n passwordPolicy,\n jwtConfig: { secret: process.env.GATEWAY_JWT_SECRET ?? 'dev-insecure-secret-change-me' },\n accessTtlSec,\n refreshTtlSec,\n bcryptCost,\n });\n\n // Seed bootstrap admin account (step 1.14). Idempotent.\n const adminEmail =\n config.auth?.bootstrap?.adminEmail ?? process.env.GATEWAY_BOOTSTRAP_ADMIN_EMAIL;\n const adminPassword = process.env.GATEWAY_BOOTSTRAP_ADMIN_PASSWORD;\n await ensureBootstrapAdmin({\n bootstrap:\n adminEmail && adminPassword\n ? { adminEmail, adminPassword, tenantId: bootstrapTenantId }\n : undefined,\n users,\n credentials,\n memberships,\n bcryptCost,\n logger,\n }).catch((err) => {\n logger.warn('Bootstrap admin seed failed (non-fatal)', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n // AUTH_INVITE_TTL_MS env var overrides config (used in E2E to test short-lived invites).\n const inviteTtlMs = process.env.AUTH_INVITE_TTL_MS\n ? parseInt(process.env.AUTH_INVITE_TTL_MS, 10)\n : (config.auth?.inviteTtlMs ?? 7 * 24 * 60 * 60 * 1000);\n\n // Rate limiter — uses kvStore if available; falls back to in-memory.\n // In-memory is sufficient for single-process deployments (E2E, dev) and\n // ensures rate limiting is always active. Production deployments with a\n // persistent kvStore get cross-restart counters automatically.\n const kv = platform.getAdapter<IKVStore>('kvStore') ?? createInMemoryKVStore();\n const rateLimiter = createRateLimiter(kv);\n if (!platform.getAdapter<IKVStore>('kvStore')) {\n logger.warn('kvStore adapter not configured — auth rate limiting using in-memory KV (counters reset on restart)');\n }\n\n // AUTH_LOGIN_RATE_LIMIT_PER_IP / AUTH_LOGIN_RATE_LIMIT_PER_EMAIL env vars override\n // config (used in E2E where many specs call /auth/login from the same IP in rapid\n // succession — the production defaults of 10/m and 5/m would trigger false 429s).\n const loginPerIpPerMinute = process.env.AUTH_LOGIN_RATE_LIMIT_PER_IP\n ? parseInt(process.env.AUTH_LOGIN_RATE_LIMIT_PER_IP, 10)\n : (config.auth?.rateLimit?.loginPerIpPerMinute ?? 10);\n const loginPerEmailPerMinute = process.env.AUTH_LOGIN_RATE_LIMIT_PER_EMAIL\n ? parseInt(process.env.AUTH_LOGIN_RATE_LIMIT_PER_EMAIL, 10)\n : (config.auth?.rateLimit?.loginPerEmailPerMinute ?? 5);\n\n // OAuth state store (ADR-0020, DD-5). Shares the same KV as the rate\n // limiter via a namespaced key prefix. The redirect/OAuth routes register\n // only when this is present.\n const oauthState = new OAuthStateStore(kv);\n\n // Step 4b shared-KV requirement: in a multi-process / HA deployment the\n // callback may land on a different worker than the one that minted the\n // state, so an in-memory KV silently breaks OAuth. Warn when a redirect\n // provider is configured against a non-shared KV.\n const hasRedirectProvider = providers.list().some((p) => p.kind === 'redirect');\n if (hasRedirectProvider && !platform.getAdapter<IKVStore>('kvStore')) {\n logger.warn(\n 'OAuth requires a shared kvStore (Redis) in multi-process/HA; in-memory state is per-process and callbacks may land on a different worker',\n );\n }\n\n userAuth = {\n userAuthService,\n users,\n sessions,\n invites,\n providers,\n pdp,\n tenantResolver,\n cookieSecure,\n accessTtlSec,\n refreshTtlSec,\n inviteTtlMs,\n rateLimiter,\n authRateLimit: { loginPerIpPerMinute, loginPerEmailPerMinute },\n oauthState,\n };\n\n logger.info('User auth infrastructure initialised', {\n tenantPattern,\n bootstrapTenantId,\n cookieSecure,\n persistent: !!configuredDocs,\n });\n }\n\n // 4. Create host registry with cache + store\n // Capture once so registry and server share the exact same cache instance.\n const cache = platform.cache;\n const registry = new HostRegistry(cache, hostStore);\n\n // 5. Restore persisted hosts into cache (best-effort — cache may be unavailable on cold start)\n let restoredCount = 0;\n try {\n restoredCount = await registry.restore();\n } catch (error) {\n logDiagnosticEvent(platform.logger, {\n domain: 'registry',\n event: 'gateway.hosts.restore',\n level: 'error',\n reasonCode: 'registry_restore_failed',\n message: 'Failed to restore gateway host registry',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n evidence: {\n persistentStore: !!hostStore,\n },\n });\n // Non-fatal: gateway can start without restored state; hosts will re-register on reconnect\n }\n if (restoredCount > 0) {\n logger.info('Restored hosts from store', { count: restoredCount });\n }\n\n // 5b. Discover plugin manifests for webhook route registration.\n // Uses snapshot().manifests — PluginBrief from listPlugins() lacks manifest/pluginRoot.\n // Graceful: failure disables webhook routes but does not block gateway startup.\n let webhookManifests: WebhookManifestEntry[] = [];\n try {\n const projectRoot = getProjectRoot() ?? repoRoot;\n const platformRoot = getPlatformRoot();\n const pluginRegistry = await createRegistry({\n root: projectRoot,\n platformRoot: platformRoot !== projectRoot ? platformRoot : undefined,\n cache: { ttlMs: 600_000, adapter: cache },\n });\n const snapshot = pluginRegistry.snapshot();\n webhookManifests = snapshot.manifests\n .filter((entry) => (entry.manifest.webhooks?.handlers?.length ?? 0) > 0)\n .map((entry) => ({\n pluginId: entry.pluginId,\n manifest: entry.manifest,\n pluginRoot: entry.pluginRoot,\n }));\n if (webhookManifests.length > 0) {\n logger.info('Webhook manifests discovered', { count: webhookManifests.length });\n }\n } catch (err) {\n logger.warn('Webhook manifest discovery failed — webhook routes disabled', {\n error: err instanceof Error ? err.message : String(err),\n });\n webhookManifests = [];\n }\n\n // 6. Build JWT config — secret required; no fallback in production.\n const DEV_JWT_SECRET = 'dev-insecure-secret-change-me';\n const jwtSecret = process.env.GATEWAY_JWT_SECRET;\n const isProduction = process.env.NODE_ENV === 'production';\n if (!jwtSecret && isProduction) {\n throw new Error(\n 'GATEWAY_JWT_SECRET must be set in production. ' +\n 'Generate one with: node -e \"console.log(require(\\'crypto\\').randomBytes(64).toString(\\'hex\\'))\"',\n );\n }\n if (!jwtSecret) {\n logger.warn('GATEWAY_JWT_SECRET not set — using insecure default (dev only, never use in production!)');\n }\n const jwtConfig = { secret: jwtSecret ?? DEV_JWT_SECRET };\n\n // 7. Auto-provision the CLI's first credential for non-local installs (#271).\n // Opt-in via config.auth.bootstrap.provisionCliCredentials (set by kb-create\n // for --yes/server-mode installs). Mints a fixed-handle machine service\n // account in-process (no HTTP round-trip, so MACHINE_REGISTER never applies)\n // and writes ~/.kb/credentials.json so `kb` commands work with zero manual\n // `kb auth login`. Idempotent — see ensureBootstrapCliCredentials.\n if (config.auth?.bootstrap?.provisionCliCredentials === true) {\n const bootstrapAuthService = new AuthService(cache, jwtConfig);\n await ensureBootstrapCliCredentials({\n enabled: true,\n authService: bootstrapAuthService,\n gatewayUrl: `http://127.0.0.1:${config.port}`,\n logger,\n }).catch((err: unknown) => {\n logger.warn('Bootstrap CLI credentials provisioning failed (non-fatal)', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }\n\n // 8. Register HTTP pressure-control limits (ADR-0056). No-op when\n // `gateway.pressure` is absent or disabled in config.\n if (platform.hasResourceBroker) {\n registerPressureLimits(platform.resourceBroker, config.pressure, platform.logger);\n } else {\n logger.warn('Resource broker unavailable — pressure control disabled');\n }\n\n // 9. Get service transport from platform adapter.\n // Configured via platform.adapters.serviceTransport in kb.config.json.\n // kb-create installs @kb-labs/adapters-service-transport-http by default\n // and writes adapterOptions.serviceTransport.services with TCP URLs.\n const serviceTransport = platform.getAdapter<IServiceTransport>('serviceTransport');\n if (!serviceTransport) {\n throw new Error(\n 'Gateway requires the serviceTransport adapter. ' +\n 'Configure it in kb.config.json:\\n' +\n ' \"adapters\": { \"serviceTransport\": \"@kb-labs/adapters-service-transport-http\" },\\n' +\n ' \"adapterOptions\": { \"serviceTransport\": { \"services\": { \"rest\": { \"url\": \"http://127.0.0.1:5050\" }, ... } } }',\n );\n }\n\n // 10. Create server with injected registry, transport and optional user auth deps\n const server = await createServer(config, cache, platform.logger, jwtConfig, registry, serviceTransport, userAuth, webhookManifests);\n\n // 11. Listen\n const bindHost = config.host ?? '0.0.0.0';\n\n // Safety guardrail (B-023): a platform with auth disabled must never be\n // reachable off the local machine. If auth is off, the bind host MUST be a\n // loopback address — otherwise refuse to start with a clear, actionable error.\n if (config.auth?.enabled === false && !isLoopbackHost(bindHost)) {\n throw new Error(\n `Refusing to start: auth is disabled but the gateway binds to \"${bindHost}\" ` +\n `(not loopback). A no-auth platform reachable on the network grants full ` +\n `access to anyone. Either set gateway.auth.enabled = true, or bind to ` +\n `127.0.0.1 (gateway.host) for solo/local use.`,\n );\n }\n\n // The gateway is the network's entry point — not a target in the transport\n // map — so it reads the offset directly (edge service). Internal routing to\n // upstreams already shifts via the transport. KB_NET_OFFSET is a LOCAL\n // mechanism (parallel environments on one host); 0 in cloud/k8s.\n const netOffset = Number(process.env.KB_NET_OFFSET) || 0;\n const listenPort = config.port + netOffset;\n const address = await server.listen({ port: listenPort, host: bindHost });\n logger.info('Gateway listening', { address, authEnabled: config.auth?.enabled !== false });\n\n // 10. Graceful shutdown\n const shutdown = async (signal: string) => {\n logger.warn('Received shutdown signal', { signal });\n await platform.shutdown();\n await server.close();\n logger.info('Gateway shutdown complete');\n process.exit(0);\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n}\n\n/**\n * True when the bind host is a loopback address (only reachable from the local\n * machine). Used by the auth-disabled startup guardrail (B-023).\n */\nexport function isLoopbackHost(host: string): boolean {\n const h = host.trim().toLowerCase();\n return (\n h === '127.0.0.1' ||\n h === 'localhost' ||\n h === '::1' ||\n h === '[::1]' ||\n h.startsWith('127.')\n );\n}\n","import { bootstrap } from './bootstrap.js';\n\n// process.cwd() = workspace root when launched via `node ./infra/kb-labs-gateway/.../dist/index.js`\nbootstrap(process.cwd()).catch((error) => {\n console.error('Failed to start gateway:', error);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/auth/tokens.ts","../src/auth/middleware.ts","../src/auth/user-cookies.ts","../src/auth/routes.ts","../src/auth/user-auth-middleware.ts","../src/auth/oauth-return-to.ts","../src/auth/oauth-routes.ts","../src/auth/user-routes.ts","../src/execute/execution-registry.ts","../src/clients/subscription-registry.ts","../src/execute/errors.ts","../src/execute/retry-executor.ts","../src/execute/routes.ts","../src/llm/routes.ts","../src/telemetry/routes.ts","../src/platform/routes.ts","../src/docs/routes.ts","../src/hosts/registry.ts","../src/hosts/ws-handler.ts","../src/clients/ws-handler.ts","../src/ws/pump.ts","../src/ws/gateway-ws.ts","../src/observability/collector.ts","../src/internal/routes.ts","../src/pressure/resolve.ts","../src/pressure/register-limits.ts","../src/pressure/hooks.ts","../src/webhook/secret-store.ts","../src/webhook/provision.ts","../src/webhook/admin-routes.ts","../src/webhook/idempotency-store.ts","../src/webhook/auth.ts","../src/webhook/router.ts","../src/server.ts","../src/bootstrap.ts","../src/index.ts"],"names":["PERMISSIONS","getCookies","accessTtl","refreshTtl","AuthError","result","response","platform","cacheKey","randomUUID","logDiagnosticEvent","HELLO_TIMEOUT_MS","send","randomBytes","AuthService","createCorrelatedLogger"],"mappings":"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","file":"index.js","sourcesContent":["import { loadEffectiveConfig } from '@kb-labs/core-config';\nimport { GatewayConfigSchema, type GatewayConfig } from '@kb-labs/gateway-contracts';\n\n/**\n * Gateway config resolution.\n *\n * Delegates the entire layering (platform baseline ← project layer ←\n * `.kb/overlays/*.jsonc` from `kb-dev ensure --scenario`) to\n * `@kb-labs/core-config :: loadEffectiveConfig`. This file does one job:\n * pluck the `gateway` section out of the merged result and validate it.\n */\nexport async function loadGatewayConfig(repoRoot: string, platformRoot?: string): Promise<GatewayConfig> {\n const merged = await loadEffectiveConfig(repoRoot, { platformRoot });\n const gateway = (merged?.data as { gateway?: unknown } | undefined)?.gateway;\n if (gateway && typeof gateway === 'object' && !Array.isArray(gateway)) {\n return GatewayConfigSchema.parse(gateway);\n }\n return GatewayConfigSchema.parse({});\n}\n","import type { ICache } from '@kb-labs/core-platform';\nimport type { AuthContext } from '@kb-labs/gateway-contracts';\nimport { AuthService, type JwtConfig } from '@kb-labs/gateway-auth';\n\n/**\n * Resolve a Bearer token to an AuthContext.\n *\n * Priority:\n * 1. JWT verification (machine tokens issued via /auth/token).\n * 2. Host-registry opaque token (issued by /hosts/register, stored in cache\n * as host:token:{uuid}). These are runtime-issued tokens for WebSocket agents,\n * distinct from the removed static pre-seeded config tokens.\n */\nexport async function resolveToken(\n token: string,\n cache: ICache,\n jwtConfig: JwtConfig,\n): Promise<AuthContext | null> {\n const authService = new AuthService(cache, jwtConfig);\n\n // Try JWT first (tokens issued via /auth/token).\n const jwtContext = await authService.verify(token);\n if (jwtContext) {return jwtContext;}\n\n // Fallback: host-registry opaque token (issued by /hosts/register).\n // Permissions default to ['host:connect'] for backward compatibility.\n const hostEntry = await cache.get<{ hostId: string; namespaceId: string; permissions?: string[] }>(\n `host:token:${token}`,\n );\n if (hostEntry) {\n return {\n type: 'machine',\n userId: hostEntry.hostId,\n namespaceId: hostEntry.namespaceId,\n tier: 'free',\n permissions: hostEntry.permissions ?? ['host:connect'],\n };\n }\n\n return null;\n}\n\nexport function extractBearerToken(authHeader: string | undefined): string | null {\n if (!authHeader) {return null;}\n const match = authHeader.match(/^Bearer\\s+(.+)$/i);\n return match ? (match[1] ?? null) : null;\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { ICache } from '@kb-labs/core-platform';\nimport type { AuthContext } from '@kb-labs/gateway-contracts';\nimport type { JwtConfig } from '@kb-labs/gateway-auth';\nimport { PERMISSIONS } from '@kb-labs/core-contracts';\nimport { resolveToken, extractBearerToken } from './tokens.js';\n\n/**\n * Deterministic identity used when auth is disabled (solo/local mode). All\n * requests run as this single local admin so namespaced data and audit logs\n * stay coherent, and enabling auth later does not invalidate existing data.\n */\nexport const LOCAL_ADMIN_CONTEXT: AuthContext = {\n type: 'machine',\n userId: 'local-admin',\n namespaceId: 'local',\n tier: 'enterprise',\n permissions: Object.values(PERMISSIONS),\n};\n\n// Routes that don't require auth (handle their own auth internally)\nconst PUBLIC_ROUTES = new Set([\n '/health',\n '/health/adapters',\n '/ready',\n // Studio SPA shell (index.html) — the login page itself. There is no\n // session yet when a browser first hits this, so it can't be gated.\n // Exact match only (not a prefix) so it doesn't swallow unrelated routes.\n '/',\n // Module Federation manifest — static, non-sensitive metadata describing\n // available Studio remotes. The Studio SPA shell must be able to fetch\n // this before a user has logged in (there is no session yet to gate on).\n '/mf-manifest.json',\n '/hosts/register',\n // /hosts/connect and /clients/connect are handled at the HTTP upgrade level\n // by gateway-ws.ts (raw ws) — they never reach Fastify routing.\n // NOTE: /auth/register is NOT public — it requires MACHINE_REGISTER permission\n // (cookie-auth admin or Bearer machine with that permission).\n '/auth/token',\n '/auth/refresh',\n // User-auth public endpoints (ADR-0020, Phase 1.16).\n '/auth/login',\n // CLI-only analogues of /auth/login and the cookie user-refresh path —\n // return tokens in the body instead of cookies, see user-routes.ts.\n '/auth/login/cli',\n '/auth/refresh/cli',\n '/auth/activate',\n '/auth/providers',\n '/internal/dispatch', // has its own x-internal-secret auth\n '/internal/resolve-host', // has its own x-internal-secret auth\n]);\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n authContext?: AuthContext;\n }\n}\n\nexport function createAuthMiddleware(\n cache: ICache,\n jwtConfig: JwtConfig,\n options: { authEnabled?: boolean } = {},\n) {\n const authEnabled = options.authEnabled !== false; // default: enabled\n return async function authMiddleware(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void> {\n // Auth disabled (solo/local mode): every request runs as the local admin.\n // The startup guardrail (bootstrap) guarantees this only happens on a\n // loopback bind, so it never exposes an open platform on the network.\n if (!authEnabled) {\n request.authContext = LOCAL_ADMIN_CONTEXT;\n return;\n }\n\n const rawPath = new URL(request.url, 'http://localhost').pathname;\n const routePath = rawPath.replace(/\\/+/g, '/').replace(/\\/+$/, '') || '/';\n if (PUBLIC_ROUTES.has(routePath)) {return;}\n // Redirect/OAuth endpoints (ADR-0020, Step 4) are public — they carry no\n // Bearer token (the IdP→callback hop is a top-level browser navigation) and\n // enforce their own state/cookie binding. Prefix match covers /start and\n // /callback for every provider id.\n if (routePath.startsWith('/auth/oauth/')) {return;}\n\n // Webhook delivery routes (/webhooks/:pluginId/:event[/:instanceId]) are\n // called by external senders (GitHub, Stripe, etc.) that have no Bearer\n // token for this platform — they authenticate via their own per-webhook\n // secret/HMAC, checked inside the handler itself. This scope was\n // originally registered outside `gatewayRoutes` specifically so the old,\n // more narrowly-scoped auth hook would skip it automatically; now that\n // the hook runs globally (GHSA-75rf-rhxh-2p52 fix) it needs an explicit\n // bypass here instead. Distinct from the admin routes under\n // /api/v1/webhooks/*, which remain fully auth-gated.\n if (routePath.startsWith('/webhooks/')) {return;}\n\n // Static Module Federation widget bundles proxied through to rest-api\n // (/plugins/@scope/name/widgets/*) — plain JS/CSS files the Studio SPA\n // shell needs to load widgets, with no user data and no side effects.\n // Same category as /mf-manifest.json above.\n if (routePath.startsWith('/plugins/')) {return;}\n\n // Studio's own static bundle (/studio/assets/*.js, etc.) — the SPA shell\n // itself, needed before a user has logged in. Same category as\n // /mf-manifest.json and /plugins/*/widgets/* above.\n if (routePath.startsWith('/studio/')) {return;}\n\n // Bearer header takes precedence; fall back to ?access_token= for SSE\n // connections where browsers cannot set custom headers.\n const queryToken = (request.query as Record<string, string | undefined>)['access_token'];\n const token = extractBearerToken(request.headers.authorization) ?? queryToken ?? null;\n\n // Skip machine Bearer check when the request is already user-authenticated\n // via cookie AND no explicit Bearer token was provided.\n // When BOTH cookie and Bearer are present (e.g. a Playwright context that\n // accumulated session cookies while also sending machine credentials), we\n // honour the Bearer token so that machine-auth context (namespaceId, etc.)\n // is populated — critical for per-tenant rate limiting and route permissions.\n if (!token && request.userAuthContext) {return;}\n\n if (!token) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Missing Authorization header' });\n }\n\n const authContext = await resolveToken(token, cache, jwtConfig);\n if (!authContext) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid token' });\n }\n\n request.authContext = authContext;\n };\n}\n","/**\n * @module @kb-labs/gateway-app/auth/user-cookies\n *\n * Canonical cookie names + setter / clearer helpers for the user-auth\n * flow (ADR-0020).\n *\n * The triple:\n * - `kb_access` — HttpOnly, holds the access JWT. Path `/`. TTL = access TTL.\n * - `kb_refresh` — HttpOnly, holds the refresh JWT. Path `/api/auth/refresh`.\n * TTL = refresh TTL.\n * - `kb_csrf` — non-HttpOnly so Studio JS can read it and echo via\n * X-CSRF-Token. Path `/`. TTL = refresh TTL (matches the\n * longest-lived cookie so it survives access rotation).\n *\n * No `Domain` attribute — cookies are origin-scoped to `{tenant}.kblabs.ru`,\n * structurally preventing cross-tenant leakage.\n *\n * Production sets `Secure` and `SameSite=Strict`. Dev (cookieSecure=false)\n * drops `Secure` so http://localhost works without a cert.\n */\n\nimport type { FastifyReply } from 'fastify';\n\nexport const COOKIE_ACCESS = 'kb_access';\nexport const COOKIE_REFRESH = 'kb_refresh';\nexport const COOKIE_CSRF = 'kb_csrf';\nexport const COOKIE_OAUTH_STATE = 'kb_oauth_state';\n\nexport const REFRESH_COOKIE_PATH = '/api/auth/refresh';\nexport const OAUTH_COOKIE_PATH = '/api/auth/oauth';\n\nexport interface CookieOptions {\n /** False in dev (http://localhost), true in prod (https) — set Secure flag. */\n cookieSecure: boolean;\n}\n\nexport interface SetSessionCookiesInput {\n accessToken: string;\n accessTtlSec: number;\n refreshToken: string;\n refreshTtlSec: number;\n csrfToken: string;\n}\n\nconst baseAttrs = (cookieSecure: boolean, ttlSec: number) => ({\n httpOnly: true,\n secure: cookieSecure,\n sameSite: 'strict' as const,\n maxAge: ttlSec,\n});\n\n/**\n * Write all three session cookies on the reply.\n *\n * The `kb_csrf` cookie is non-HttpOnly — the SPA must be able to read\n * it via document.cookie and submit it via X-CSRF-Token. Its `maxAge`\n * matches the refresh TTL so a long-running session doesn't lose CSRF\n * cover between access rotations.\n */\nexport const setSessionCookies = (\n reply: FastifyReply,\n input: SetSessionCookiesInput,\n opts: CookieOptions,\n): void => {\n reply.setCookie(COOKIE_ACCESS, input.accessToken, {\n ...baseAttrs(opts.cookieSecure, input.accessTtlSec),\n path: '/',\n });\n reply.setCookie(COOKIE_REFRESH, input.refreshToken, {\n ...baseAttrs(opts.cookieSecure, input.refreshTtlSec),\n path: REFRESH_COOKIE_PATH,\n });\n reply.setCookie(COOKIE_CSRF, input.csrfToken, {\n // CSRF cookie is NON-HttpOnly so JS can read it.\n httpOnly: false,\n secure: opts.cookieSecure,\n sameSite: 'strict' as const,\n maxAge: input.refreshTtlSec,\n path: '/',\n });\n};\n\n/**\n * The OAuth state cookie binds the browser that *started* a flow to the\n * one that *finishes* it (defence against state-fixation / login CSRF).\n *\n * It MUST be `SameSite=Lax`, NOT Strict: the IdP→callback hop is a\n * cross-site top-level navigation, and a Strict cookie would not be sent\n * on it, breaking the binding. Lax still blocks cross-site sub-resource\n * sends, which is all we need here. Scoped to the OAuth path so it never\n * rides along with normal API calls.\n */\nexport const setOAuthStateCookie = (\n reply: FastifyReply,\n state: string,\n opts: CookieOptions,\n ttlSec: number,\n): void => {\n reply.setCookie(COOKIE_OAUTH_STATE, state, {\n httpOnly: true,\n secure: opts.cookieSecure,\n sameSite: 'lax' as const,\n maxAge: ttlSec,\n path: OAUTH_COOKIE_PATH,\n });\n};\n\nexport const clearOAuthStateCookie = (reply: FastifyReply, opts: CookieOptions): void => {\n reply.clearCookie(COOKIE_OAUTH_STATE, {\n secure: opts.cookieSecure,\n sameSite: 'lax' as const,\n path: OAUTH_COOKIE_PATH,\n });\n};\n\nexport const clearSessionCookies = (reply: FastifyReply, opts: CookieOptions): void => {\n const common = { secure: opts.cookieSecure, sameSite: 'strict' as const };\n reply.clearCookie(COOKIE_ACCESS, { ...common, path: '/' });\n reply.clearCookie(COOKIE_REFRESH, { ...common, path: REFRESH_COOKIE_PATH });\n reply.clearCookie(COOKIE_CSRF, { ...common, path: '/' });\n};\n","/**\n * Auth routes — machine-client endpoints for agent registration and token management.\n *\n * POST /auth/register — register new agent, get clientId + clientSecret\n * (gated behind MACHINE_REGISTER permission; see gate below)\n * POST /auth/token — exchange credentials for JWT pair\n * POST /auth/refresh — rotate refresh token (machine body path); user cookie\n * path is handled first if userRefreshFn is provided\n *\n * NOTE: GET /auth/me is NOT registered here — it lives in registerUserAuthRoutes\n * because it must handle both user-cookie and machine-Bearer contexts in one handler.\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type { AuthService, IPolicyDecisionPoint } from '@kb-labs/gateway-auth';\nimport {\n RegisterRequestSchema,\n TokenRequestSchema,\n RefreshRequestSchema,\n} from '@kb-labs/gateway-contracts';\nimport { PERMISSIONS } from '@kb-labs/core-contracts';\nimport { COOKIE_REFRESH } from './user-cookies.js';\n\nexport interface MachineAuthRoutesUserExt {\n /** Called when a user refresh cookie is detected in POST /auth/refresh.\n * Must write the reply and return true; return false to fall through to\n * the machine body-refresh path. */\n userRefreshFn: (request: FastifyRequest, reply: FastifyReply) => Promise<boolean>;\n /** PDP for checking MACHINE_REGISTER permission on cookie-authenticated admin users. */\n pdp: IPolicyDecisionPoint;\n}\n\nexport function registerAuthRoutes(\n app: FastifyInstance,\n authService: AuthService,\n userExt?: MachineAuthRoutesUserExt,\n): void {\n // Register new agent.\n // Requires MACHINE_REGISTER permission. Auth checks:\n // - Anonymous (no cookie, no Bearer) → 401 from machine-auth middleware\n // - Cookie-auth user without permission → 403 (PDP check below)\n // - Cookie-auth admin with MACHINE_REGISTER → 200\n // - Bearer-auth machine with machine:register in JWT permissions → 200\n app.post('/auth/register', { schema: { tags: ['Auth'], summary: 'Register new agent and get credentials' } }, async (request, reply) => {\n // Gate behind MACHINE_REGISTER permission.\n // Two auth paths: cookie-authenticated user (userAuthContext) or Bearer machine (authContext).\n const userCtx = request.userAuthContext;\n const machineCtx = request.authContext;\n\n if (userCtx && userExt?.pdp) {\n // Cookie-authenticated user — check via PDP.\n const decision = await userExt.pdp.check(\n { userId: userCtx.userId, tenantId: userCtx.tenantId, type: 'user' },\n PERMISSIONS.MACHINE_REGISTER,\n );\n if (!decision.allow) {\n return reply.code(403).send({ error: 'Forbidden', message: `Permission denied: ${PERMISSIONS.MACHINE_REGISTER}` });\n }\n } else if (machineCtx) {\n // Bearer-authenticated machine — check permissions embedded in JWT.\n if (!machineCtx.permissions.includes(PERMISSIONS.MACHINE_REGISTER)) {\n return reply.code(403).send({ error: 'Forbidden', message: `Permission denied: ${PERMISSIONS.MACHINE_REGISTER}` });\n }\n } else {\n // No auth context at all (should have been caught by middleware, but guard defensively).\n return reply.code(401).send({ error: 'Unauthorized', message: 'Authentication required' });\n }\n\n const parsed = RegisterRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const { name, capabilities, publicKey, handle, email } = parsed.data;\n try {\n const result = await authService.register({ name, capabilities, publicKey, handle, email });\n return reply.code(200).send(result);\n } catch (err) {\n if (err instanceof Error && (err as NodeJS.ErrnoException).code === 'HANDLE_TAKEN') {\n return reply.code(409).send({ error: 'Conflict', message: err.message });\n }\n throw err;\n }\n });\n\n // Issue token pair (machine credentials → JWT pair).\n app.post('/auth/token', { schema: { tags: ['Auth'], summary: 'Issue JWT token pair' } }, async (request, reply) => {\n const parsed = TokenRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const tokens = await authService.issueTokens(parsed.data.clientId, parsed.data.clientSecret);\n if (!tokens) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid credentials' });\n }\n\n return reply.send(tokens);\n });\n\n // Refresh token pair.\n // If a user refresh cookie is detected AND userExt.userRefreshFn is provided,\n // the user path is handled first. Otherwise, falls back to machine body refresh.\n app.post('/auth/refresh', { schema: { tags: ['Auth'], summary: 'Refresh JWT token pair (machine or user)' } }, async (request, reply) => {\n // User cookie refresh — handled by the user-auth subsystem if wired.\n const cookies = (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies;\n const refreshCookie = cookies?.[COOKIE_REFRESH];\n if (refreshCookie && userExt) {\n const handled = await userExt.userRefreshFn(request, reply);\n if (handled) {return;}\n }\n\n // Machine body refresh (existing logic).\n const parsed = RefreshRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const tokens = await authService.refreshTokens(parsed.data.refreshToken);\n if (!tokens) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid or expired refresh token' });\n }\n\n return reply.send(tokens);\n });\n}\n","/**\n * @module @kb-labs/gateway-app/auth/user-auth-middleware\n *\n * Fastify onRequest hook for cookie-based user authentication\n * (ADR-0020, Phase 1.16).\n *\n * Runs BEFORE the existing machine-token middleware. Also accepts a user\n * access token via `Authorization: Bearer` when no `kb_access` cookie is\n * present — this is how the CLI (which has nowhere to hold a cookie) carries\n * a human session obtained from `POST /auth/login/cli`. User and machine\n * access tokens are disambiguated by an explicit `type` claim (`'user'` vs.\n * a machine `TokenType`), so a machine Bearer token presented here simply\n * fails `verifyUserAccessToken` and falls through to the machine middleware\n * — see the Bearer branch below.\n *\n * Four outcomes:\n *\n * - **No `kb_access` cookie, no Bearer token** — middleware is a no-op.\n * Downstream (Bearer-based machine auth) takes over.\n * - **Cookie or Bearer present, valid, user active in correct tenant** —\n * sets `request.userAuthContext` with `{ type, userId, tenantId,\n * familyId }` and lets the request through.\n * - **Cookie present but invalid in any way** — returns 401 WITHOUT\n * falling through to machine auth. A tampered cookie must not\n * silently bypass into the Bearer path.\n * - **Bearer token present but not a valid user token** (wrong `type`,\n * bad signature, expired) — falls through silently (no 401) so a\n * genuine machine Bearer token still reaches the machine middleware.\n * Only a cookie failure is a hard stop; an absent/invalid Bearer value\n * must not block the machine-auth path from getting its own chance.\n *\n * What this middleware enforces:\n *\n * - **CD-1**: `users.getById(userId).status === 'active'`. The PDP\n * does not see this; without an explicit check a disabled user\n * keeps acting for up to one access TTL.\n * - **Cross-tenant guard**: `payload.tenantId ===\n * tenantResolver(req.host)`. A cookie from tenant A presented on\n * tenant B's subdomain is rejected.\n */\n\nimport type { FastifyRequest, FastifyReply, FastifyError } from 'fastify';\nimport type { UsersStore, JwtConfig, TenantResolver } from '@kb-labs/gateway-auth';\nimport { verifyUserAccessToken } from '@kb-labs/gateway-auth';\nimport { COOKIE_ACCESS } from './user-cookies.js';\nimport { extractBearerToken } from './tokens.js';\n\nexport interface UserAuthContext {\n type: 'user';\n userId: string;\n tenantId: string;\n familyId: string;\n}\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n userAuthContext?: UserAuthContext;\n }\n}\n\nexport interface UserAuthMiddlewareDeps {\n users: UsersStore;\n tenantResolver: TenantResolver;\n jwtConfig: JwtConfig;\n}\n\nconst sendUnauthorized = (reply: FastifyReply, message: string) =>\n reply.code(401).send({ error: 'Unauthorized', message });\n\nexport const createUserAuthMiddleware = (deps: UserAuthMiddlewareDeps) => {\n return async function userAuthMiddleware(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<void | FastifyError> {\n const cookies = (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies;\n const cookieToken = cookies?.[COOKIE_ACCESS];\n const bearerToken = cookieToken ? undefined : extractBearerToken(request.headers.authorization);\n const token = cookieToken ?? bearerToken;\n if (!token) {\n // No user cookie, no Bearer token — let machine middleware handle it.\n return;\n }\n\n const payload = await verifyUserAccessToken(token, deps.jwtConfig);\n if (!payload) {\n if (cookieToken) {\n // A tampered/expired cookie must not silently fall through.\n return sendUnauthorized(reply, 'Invalid session');\n }\n // Bearer token present but not a valid user token (e.g. a machine\n // JWT, which carries a different `type` claim) — fall through so\n // the machine middleware gets a chance to verify it instead.\n return;\n }\n\n // Cross-tenant guard. The cookie alone doesn't tell us \"which\n // tenant origin\" the browser thinks it's on — we re-derive from\n // Host so a stolen cookie cannot be presented on another tenant.\n //\n // Guard fires only when the Host resolves to a known tenant. When\n // resolvedTenant is null (localhost, raw IP, development, E2E), the\n // request is not subdomain-routed and we cannot enforce per-tenant\n // isolation — let it through. An attacker cannot fake a legitimate\n // tenant subdomain without also controlling DNS / TLS, so the guard\n // only needs to activate when the resolver returns a concrete slug.\n const hostHeader = request.headers['host'];\n const resolvedTenant = deps.tenantResolver.resolve(\n typeof hostHeader === 'string' ? hostHeader : undefined,\n );\n if (resolvedTenant !== null && resolvedTenant !== payload.tenantId) {\n return sendUnauthorized(reply, 'Tenant mismatch');\n }\n\n // CD-1: explicit user.status check on every request. Without this\n // a disabled user keeps acting for the remaining access TTL.\n const user = await deps.users.getById(payload.userId);\n if (!user || user.status !== 'active') {\n return sendUnauthorized(reply, 'Session no longer valid');\n }\n\n request.userAuthContext = {\n type: 'user',\n userId: payload.userId,\n tenantId: payload.tenantId,\n familyId: payload.familyId,\n };\n };\n};\n","/**\n * @module @kb-labs/gateway-app/auth/oauth-return-to\n *\n * Open-redirect guard for the OAuth flow (ADR-0020, Step 4b).\n *\n * `returnTo` is attacker-influenceable (it rides in the `/start` query\n * string). After a successful callback we redirect the now-authenticated\n * browser to it, so it MUST be a same-origin relative path — never an\n * absolute or protocol-relative URL that could bounce the user to a\n * phishing origin.\n *\n * Whitelist: a path that starts with a single `/` not followed by another\n * `/` or a `\\` (browsers normalise `/\\` to `//`, i.e. protocol-relative).\n * Anything else collapses to `/`.\n */\n\n// Starts with '/', and the next char (if any) is not '/' or '\\'.\nconst SAFE_RELATIVE_PATH = /^\\/(?![/\\\\])/;\n\nexport function validateReturnTo(raw: unknown): string {\n if (typeof raw !== 'string' || raw.length === 0) {\n return '/';\n }\n if (!SAFE_RELATIVE_PATH.test(raw)) {\n return '/';\n }\n return raw;\n}\n","/**\n * @module @kb-labs/gateway-app/auth/oauth-routes\n *\n * HTTP routes for the redirect/OAuth identity flow (ADR-0020, Step 4 + 4b).\n *\n * GET /auth/oauth/:id/start — mint an opaque `state`, persist the flow\n * context in KV, set a SameSite=Lax state\n * cookie, then 302 to the upstream IdP.\n * GET /auth/oauth/:id/callback — verify the state (KV + cookie binding +\n * one-shot consume + cross-tenant + mix-up\n * guards), run the provider through\n * userAuthService.login (DD-6), set the\n * session cookies, then 302 to returnTo.\n *\n * Security invariants (Step 4b):\n * - **Open-redirect guard**: returnTo is validated to a same-origin\n * relative path (validateReturnTo); anything else collapses to '/'.\n * - **State-cookie binding**: the query `state` must equal the value in\n * the Lax state cookie — defends against login-CSRF / state fixation.\n * - **One-shot state**: OAuthStateStore.consume deletes on read, so a\n * replayed callback cannot be processed twice.\n * - **Cross-tenant guard**: the tenant the callback Host resolves to must\n * match the tenant the state was minted for.\n * - **Mix-up guard**: the provider is taken from the KV state, not the\n * URL — and the URL :id must match it.\n * - **Per-IP rate-limit**: both /start and /callback are throttled (via a\n * preHandler barrier) before any KV / provider work to blunt floods.\n * - Secrets (code / id_token / session) are never logged.\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type {\n ProviderRegistry,\n TenantResolver,\n OAuthStateStore,\n RateLimiter,\n SessionResult,\n} from '@kb-labs/gateway-auth';\nimport { AuthError, issueCsrfToken } from '@kb-labs/gateway-auth';\nimport type { IRedirectIdentityProvider } from '@kb-labs/core-contracts';\nimport type { UserAuthServiceForRoutes } from './user-routes.js';\nimport { validateReturnTo } from './oauth-return-to.js';\nimport {\n setSessionCookies,\n setOAuthStateCookie,\n clearOAuthStateCookie,\n COOKIE_OAUTH_STATE,\n type CookieOptions,\n} from './user-cookies.js';\n\n/** State cookie / KV TTL — abandoned flows self-clean after this window. */\nconst OAUTH_STATE_TTL_SEC = 10 * 60;\n\nexport interface OAuthRouteDeps {\n userAuthService: UserAuthServiceForRoutes;\n providers: ProviderRegistry;\n tenantResolver: TenantResolver;\n oauthState: OAuthStateStore;\n cookieOpts: CookieOptions;\n /** Optional limiter; per-IP callback throttling is skipped when absent. */\n rateLimiter?: RateLimiter;\n /** Max callbacks per IP per minute. Default 60 when a limiter is present. */\n oauthCallbackPerIpPerMinute?: number;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction getCookies(request: FastifyRequest): Record<string, string | undefined> {\n return (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies ?? {};\n}\n\n/** Builds the absolute callback URL from the request Host (nginx-set in prod). */\nfunction callbackUrl(request: FastifyRequest, id: string, secure: boolean): string {\n const host = typeof request.headers.host === 'string' ? request.headers.host : 'localhost';\n const proto = secure ? 'https' : 'http';\n return `${proto}://${host}/api/auth/oauth/${id}/callback`;\n}\n\nfunction isRedirectProvider(\n p: ReturnType<ProviderRegistry['get']>,\n): p is IRedirectIdentityProvider {\n return !!p && p.kind === 'redirect';\n}\n\nfunction accessTtl(result: SessionResult): number {\n return result.access.expiresInSec;\n}\nfunction refreshTtl(result: SessionResult): number {\n return result.refresh.expiresInSec;\n}\n\n// ── Registrar ───────────────────────────────────────────────────────────────────\n\nexport function registerOAuthRoutes(app: FastifyInstance, deps: OAuthRouteDeps): void {\n const { userAuthService, providers, tenantResolver, oauthState, cookieOpts, rateLimiter } = deps;\n const perIpPerMinute = deps.oauthCallbackPerIpPerMinute ?? 60;\n\n /**\n * Per-IP rate-limit barrier (Step 4b). Runs as a `preHandler` BEFORE any\n * KV / provider work on both `/start` and `/callback`, so a flood from one\n * source costs ~0 beyond the counter bump. `bucket` keeps the two routes on\n * independent counters. A no-op when no limiter is wired (tests / dev).\n */\n function rateLimitGate(bucket: string) {\n return async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {\n if (!rateLimiter) {\n return;\n }\n const r = await rateLimiter.check(`rl:oauth:${bucket}:ip:${request.ip}`, {\n max: perIpPerMinute,\n windowMs: 60_000,\n });\n if (!r.allowed) {\n reply.header('Retry-After', String(r.retryAfterSec));\n await reply\n .code(429)\n .send({ error: 'Too Many Requests', message: 'Rate limit exceeded', retryAfterSec: r.retryAfterSec });\n }\n };\n }\n\n /** Clear the state cookie and bounce to the login page with an error flag. */\n function failCallback(reply: FastifyReply): FastifyReply {\n clearOAuthStateCookie(reply, cookieOpts);\n return reply.redirect('/login?error=oauth', 302);\n }\n\n // ── GET /auth/oauth/:id/start ─────────────────────────────────────────────────\n app.get<{ Params: { id: string }; Querystring: { returnTo?: string } }>(\n '/auth/oauth/:id/start',\n {\n schema: { tags: ['Auth'], summary: 'Begin a redirect/OAuth login flow' },\n preHandler: rateLimitGate('start'),\n },\n async (request, reply) => {\n const { id } = request.params;\n const provider = providers.get(id);\n if (!isRedirectProvider(provider)) {\n return reply.code(400).send({ error: 'Bad Request', message: 'Unknown or non-redirect provider' });\n }\n\n // Tenant is derived from Host (authoritative in subdomain deployments).\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const tenantId = tenantResolver.resolve(host) ?? '';\n\n const returnTo = validateReturnTo(request.query?.returnTo);\n const state = issueCsrfToken();\n const redirectUri = callbackUrl(request, id, cookieOpts.cookieSecure);\n\n const startResult = await provider.startAuthorization({ state, redirectUri });\n\n await oauthState.put(state, {\n providerId: id,\n tenantId,\n returnTo,\n session: startResult.session,\n createdAt: Date.now(),\n });\n\n setOAuthStateCookie(reply, state, cookieOpts, OAUTH_STATE_TTL_SEC);\n return reply.redirect(startResult.redirectUrl, 302);\n },\n );\n\n // ── GET /auth/oauth/:id/callback ───────────────────────────────────────────────\n app.get<{ Params: { id: string }; Querystring: { state?: string; code?: string; error?: string } }>(\n '/auth/oauth/:id/callback',\n {\n schema: { tags: ['Auth'], summary: 'Complete a redirect/OAuth login flow' },\n preHandler: rateLimitGate('cb'),\n },\n async (request, reply) => {\n const { id } = request.params;\n const { state, code, error } = request.query ?? {};\n\n // IdP signalled an error (user denied consent, etc.) — never touch the\n // provider; just bounce back to login.\n if (error) {\n return failCallback(reply);\n }\n\n // State-cookie binding: the query state must echo the Lax cookie value.\n const cookieState = getCookies(request)[COOKIE_OAUTH_STATE];\n if (!state || !cookieState || state !== cookieState) {\n return failCallback(reply);\n }\n\n // One-shot consume — unknown / forged / replayed states resolve to null.\n const record = await oauthState.consume(state);\n if (!record) {\n return failCallback(reply);\n }\n\n // Mix-up guard: the URL :id must match the provider that minted the state.\n if (record.providerId !== id) {\n return failCallback(reply);\n }\n\n // Cross-tenant guard: the callback Host must resolve to the same tenant\n // the state was minted for (when the Host is subdomain-routed at all).\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const callbackTenant = tenantResolver.resolve(host);\n if (callbackTenant !== null && callbackTenant !== record.tenantId) {\n return failCallback(reply);\n }\n\n // The provider is the source of truth from the KV record (not the URL).\n const provider = providers.get(record.providerId);\n if (!isRedirectProvider(provider)) {\n return failCallback(reply);\n }\n\n const redirectUri = callbackUrl(request, record.providerId, cookieOpts.cookieSecure);\n\n try {\n // DD-6: reuse the standard login path. The provider's authenticate()\n // receives the callback bundle and resolves it to an email; the service\n // does email→user→session→tokens exactly as for password login.\n const result = await userAuthService.login(\n {\n providerId: record.providerId,\n input: { code, state, session: record.session, redirectUri },\n },\n record.tenantId,\n { ip: request.ip, userAgent: request.headers['user-agent'] as string | undefined },\n );\n\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n\n clearOAuthStateCookie(reply, cookieOpts);\n return reply.redirect(record.returnTo, 302);\n } catch (err) {\n if (err instanceof AuthError) {\n return failCallback(reply);\n }\n throw err;\n }\n },\n );\n}\n","/**\n * @module @kb-labs/gateway-app/auth/user-routes\n *\n * HTTP route registrar for the user-auth flow (ADR-0020, Phase 1.16).\n *\n * Endpoints registered here:\n * GET /auth/me (user cookie or machine Bearer)\n * GET /auth/providers\n * POST /auth/login\n * POST /auth/login/cli (CLI-only: returns tokens in body, never sets cookies)\n * POST /auth/refresh/cli (CLI-only: body refreshToken, returns tokens in body)\n * POST /auth/logout\n * GET /auth/permissions\n * POST /auth/activate\n * POST /auth/password/change\n * GET /auth/sessions\n * POST /auth/sessions/revoke-all (before /:fam/revoke to avoid param capture)\n * POST /auth/sessions/:fam/revoke\n * POST /auth/invites\n * POST /auth/invites/:id/revoke\n * GET /auth/invites\n * GET /auth/users\n * POST /auth/users/:id/disable\n * POST /auth/users/:id/enable\n *\n * NOTE: POST /auth/refresh is NOT registered here. Instead,\n * createUserRefreshFn() returns a handler that registerAuthRoutes() wires\n * as its `userExt.userRefreshFn` option — avoiding duplicate route registration.\n *\n * Security invariants:\n * - All state-mutating cookie-auth endpoints validate CSRF (double-submit).\n * - Admin endpoints check PDP via PERMISSIONS enum (CD-7).\n * - /auth/me never returns role/group fields.\n * - /auth/login/cli and /auth/refresh/cli exist ONLY so a non-browser\n * client (the CLI) can obtain a Bearer-usable user token — they must\n * NEVER call setSessionCookies(). Mixing the two response shapes on one\n * route was deliberately avoided (see /auth/login/cli below) so \"does\n * this route ever put a token in a JSON body\" stays a static, greppable\n * question instead of depending on request shape.\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type {\n UsersStore,\n SessionsStore,\n InvitesStore,\n ProviderRegistry,\n IPolicyDecisionPoint,\n JwtConfig,\n SessionResult,\n RateLimiter,\n TenantResolver,\n OAuthStateStore,\n} from '@kb-labs/gateway-auth';\nimport { registerOAuthRoutes } from './oauth-routes.js';\nimport { AuthError, verifyCsrfToken } from '@kb-labs/gateway-auth';\nimport { PERMISSIONS } from '@kb-labs/core-contracts';\nimport type { UserAuthContext } from './user-auth-middleware.js';\nimport {\n setSessionCookies,\n clearSessionCookies,\n COOKIE_REFRESH,\n COOKIE_CSRF,\n type CookieOptions,\n} from './user-cookies.js';\n\nexport type { UserAuthContext };\n\n// ── Service interface (matches createUserAuthService return type) ──────────────\n\n/**\n * Minimal interface for the UserAuthService used by user-routes.\n *\n * Mirrors the actual return type of createUserAuthService from gateway-auth.\n * login() takes (input: LoginInput, tenantId, deviceCtx) — three separate args.\n * refresh() / logout() take the full refresh JWT string (service verifies internally).\n * activate() takes { activationToken, password, deviceCtx }.\n */\nexport interface UserAuthServiceForRoutes {\n login(\n input: { providerId: string; input: unknown },\n tenantId: string,\n deviceCtx: { ip?: string; userAgent?: string },\n ): Promise<SessionResult>;\n refresh(refreshToken: string): Promise<SessionResult>;\n logout(refreshToken: string): Promise<void>;\n changePassword(input: {\n userId: string;\n currentFamilyId: string;\n currentPassword: string;\n newPassword: string;\n }): Promise<void>;\n activate(input: {\n activationToken: string;\n password: string;\n deviceCtx: { ip?: string; userAgent?: string };\n }): Promise<SessionResult>;\n}\n\nexport interface UserAuthRouteDeps {\n userAuthService: UserAuthServiceForRoutes;\n users: UsersStore;\n sessions: SessionsStore;\n invites: InvitesStore;\n providers: ProviderRegistry;\n pdp: IPolicyDecisionPoint;\n /** Resolves the tenant from the Host header — used to prevent tenantId bypass via body. */\n tenantResolver: TenantResolver;\n cookieOpts: CookieOptions;\n accessTtlSec: number;\n refreshTtlSec: number;\n inviteTtlMs: number;\n jwtConfig: JwtConfig;\n /** Fixed-window rate limiter for login/activate endpoints. Optional — rate limiting\n * is silently skipped when absent (e.g. unit tests without IKVStore). */\n rateLimiter?: RateLimiter;\n /** Rate limit thresholds (defaults applied when rateLimiter is present). */\n authRateLimit?: {\n loginPerIpPerMinute: number;\n loginPerEmailPerMinute: number;\n };\n /** OAuth state store. When present, the redirect/OAuth routes are registered. */\n oauthState?: OAuthStateStore;\n /** Per-IP callback rate-limit for the OAuth callback (defaults applied when set). */\n oauthCallbackPerIpPerMinute?: number;\n}\n\n// ── Cookie helpers ────────────────────────────────────────────────────────────\n\nfunction getCookies(request: FastifyRequest): Record<string, string | undefined> {\n return (request as FastifyRequest & { cookies?: Record<string, string | undefined> }).cookies ?? {};\n}\n\n// ── Auth/CSRF helpers ─────────────────────────────────────────────────────────\n\n/** Returns the UserAuthContext or sends 401 and returns null. */\nfunction requireUser(request: FastifyRequest, reply: FastifyReply): UserAuthContext | null {\n const ctx = request.userAuthContext;\n if (!ctx) {\n void reply.code(401).send({ error: 'Unauthorized', message: 'No active user session' });\n return null;\n }\n return ctx;\n}\n\n/**\n * Validates double-submit CSRF token.\n * Returns true if valid; sends 403 and returns false otherwise.\n */\nfunction checkCsrf(request: FastifyRequest, reply: FastifyReply): boolean {\n const cookieVal = getCookies(request)[COOKIE_CSRF];\n const headerVal = request.headers['x-csrf-token'];\n const headerStr = typeof headerVal === 'string' ? headerVal : undefined;\n if (!verifyCsrfToken(cookieVal, headerStr)) {\n void reply.code(403).send({ error: 'Forbidden', message: 'CSRF token mismatch' });\n return false;\n }\n return true;\n}\n\n// ── Cookie TTL helpers ────────────────────────────────────────────────────────\n\n/** Derives MaxAge for access cookie from SessionResult. */\nfunction accessTtl(result: SessionResult): number {\n return result.access.expiresInSec;\n}\n\n/** Derives MaxAge for refresh cookie from SessionResult. */\nfunction refreshTtl(result: SessionResult): number {\n return result.refresh.expiresInSec;\n}\n\n// ── User refresh handler factory ──────────────────────────────────────────────\n\n/**\n * Creates the user-cookie refresh handler for POST /auth/refresh.\n *\n * Pass this as `userExt.userRefreshFn` to `registerAuthRoutes()`. Returns\n * true if the cookie was present and the response has been sent. Returns\n * false (no response sent) if there is no refresh cookie, letting the\n * machine body-refresh path take over.\n */\nexport function createUserRefreshFn(\n deps: Pick<UserAuthRouteDeps, 'userAuthService' | 'cookieOpts'>,\n): (request: FastifyRequest, reply: FastifyReply) => Promise<boolean> {\n const { userAuthService, cookieOpts } = deps;\n\n return async function userRefreshFn(\n request: FastifyRequest,\n reply: FastifyReply,\n ): Promise<boolean> {\n const refreshCookie = getCookies(request)[COOKIE_REFRESH];\n if (!refreshCookie) {return false;}\n\n try {\n const result = await userAuthService.refresh(refreshCookie);\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n void reply.send({ ok: true });\n return true;\n } catch (err) {\n if (err instanceof AuthError) {\n clearSessionCookies(reply, cookieOpts);\n void reply.code(401).send({ error: 'Unauthorized', message: 'Session expired or revoked' });\n return true;\n }\n throw err;\n }\n };\n}\n\n// ── Login rate-limit helpers (shared by /auth/login and /auth/login/cli) ──────\n//\n// The CLI login route deliberately reuses the exact same rate-limit keys\n// (rl:login:ip:*, rl:login:email:*) as the browser login route — both\n// represent the same brute-force surface against the same password store,\n// and an attacker must not be able to bypass one route's limit by switching\n// to the other.\n\ninterface LoginRateLimitCfg {\n loginPerIpPerMinute: number;\n loginPerEmailPerMinute: number;\n}\n\n/** Peek (non-incrementing) gate, called before the bcrypt-cost login attempt. */\nasync function peekLoginRateLimit(\n reply: FastifyReply,\n ip: string,\n emailNorm: string,\n rateLimiter: RateLimiter,\n cfg: LoginRateLimitCfg,\n): Promise<boolean> {\n const [ipPeek, emailPeek] = await Promise.all([\n rateLimiter.peek(`rl:login:ip:${ip}`, { max: cfg.loginPerIpPerMinute, windowMs: 60_000 }),\n rateLimiter.peek(`rl:login:email:${emailNorm}`, { max: cfg.loginPerEmailPerMinute, windowMs: 60_000 }),\n ]);\n if (!ipPeek.allowed || !emailPeek.allowed) {\n const retryAfter = !ipPeek.allowed ? ipPeek.retryAfterSec : (!emailPeek.allowed ? emailPeek.retryAfterSec : 60);\n reply.header('Retry-After', String(retryAfter));\n void reply.code(429).send({ error: 'Too Many Requests', message: 'Rate limit exceeded', retryAfterSec: retryAfter });\n return false;\n }\n return true;\n}\n\n/** Increments the failure counters after a failed login attempt; returns false if this trips the limit (429 already sent). */\nasync function recordLoginFailure(\n reply: FastifyReply,\n ip: string,\n emailNorm: string,\n rateLimiter: RateLimiter,\n cfg: LoginRateLimitCfg,\n): Promise<boolean> {\n const [ipResult, emailResult] = await Promise.all([\n rateLimiter.check(`rl:login:ip:${ip}`, { max: cfg.loginPerIpPerMinute, windowMs: 60_000 }),\n rateLimiter.check(`rl:login:email:${emailNorm}`, { max: cfg.loginPerEmailPerMinute, windowMs: 60_000 }),\n ]);\n if (!ipResult.allowed || !emailResult.allowed) {\n const retryAfter = !ipResult.allowed ? ipResult.retryAfterSec : (!emailResult.allowed ? emailResult.retryAfterSec : 60);\n reply.header('Retry-After', String(retryAfter));\n void reply.code(429).send({ error: 'Too Many Requests', message: 'Rate limit exceeded', retryAfterSec: retryAfter });\n return false;\n }\n return true;\n}\n\n// ── Route registrar ───────────────────────────────────────────────────────────\n\nexport function registerUserAuthRoutes(app: FastifyInstance, deps: UserAuthRouteDeps): void {\n const { userAuthService, users, sessions, invites, providers, pdp, tenantResolver, cookieOpts, inviteTtlMs, rateLimiter, authRateLimit, oauthState, oauthCallbackPerIpPerMinute } = deps;\n // Apply config defaults so the rest of the handler can use them without null-checks.\n const authRateLimitCfg = { loginPerIpPerMinute: 10, loginPerEmailPerMinute: 5, ...authRateLimit };\n\n // Redirect/OAuth routes are only registered when an OAuth state store is wired\n // (DD-5). Without a (shared) KV-backed store there is nowhere to hold the\n // per-attempt `state` binding, so the flow is simply unavailable.\n if (oauthState) {\n registerOAuthRoutes(app, {\n userAuthService,\n providers,\n tenantResolver,\n oauthState,\n cookieOpts,\n rateLimiter,\n oauthCallbackPerIpPerMinute,\n });\n }\n\n // ── GET /auth/me ────────────────────────────────────────────────────────────\n // Handles both user cookie auth and machine Bearer auth. User takes precedence.\n // NOTE: Removed from registerAuthRoutes to avoid duplicate route registration.\n app.get('/auth/me', {\n schema: { tags: ['Auth'], summary: 'Get profile for the authenticated caller' },\n }, async (request, reply) => {\n // User cookie auth (takes precedence)\n if (request.userAuthContext) {\n const { userId, tenantId } = request.userAuthContext;\n const user = await users.getById(userId);\n if (!user) {\n return reply.code(404).send({ error: 'Not found', message: 'User record not found' });\n }\n // Never expose role/group fields — return minimal public fields only.\n return reply.send({ userId: user.userId, email: user.email, tenantId });\n }\n\n // Machine Bearer auth (includes LOCAL_ADMIN, injected when auth.enabled=false —\n // see B-023). Studio's PublicUser type (studio/app/src/auth/auth-provider.tsx)\n // requires `email`/`tenantId`; a machine context has neither concept, so we\n // derive Studio-displayable stand-ins from userId/namespaceId rather than\n // omitting the fields — omitting them broke Studio's header/status bar under\n // `--local` installs, where every request runs as this machine context.\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Not authenticated' });\n }\n return reply.send({\n userId: auth.userId,\n namespaceId: auth.namespaceId,\n email: auth.userId,\n tenantId: auth.namespaceId,\n });\n });\n\n // ── GET /auth/providers ─────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES in middleware.ts).\n app.get('/auth/providers', {\n schema: { tags: ['Auth'], summary: 'List registered identity providers' },\n }, async (_request, reply) => {\n return reply.send({ providers: providers.list() });\n });\n\n // ── POST /auth/login ────────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES). Rate-limited per-IP + per-email via fixed-window counter.\n app.post<{ Body: { email?: string; password?: string; providerId?: string; tenantId?: string } }>('/auth/login', {\n schema: { tags: ['Auth'], summary: 'Login with email/password (sets session cookies)' },\n }, async (request, reply) => {\n const { email, password, providerId, tenantId: bodyTenantId } = request.body ?? {};\n if (typeof email !== 'string' || !email) {\n return reply.code(400).send({ error: 'Bad Request', message: 'email is required' });\n }\n if (typeof password !== 'string' || !password) {\n return reply.code(400).send({ error: 'Bad Request', message: 'password is required' });\n }\n\n // Derive tenantId — Host header is authoritative (set by nginx in production).\n // bodyTenantId is accepted only as a fallback when the Host doesn't resolve to\n // a valid tenant (e.g. direct gateway access: localhost:4000, CI without nginx).\n // This prevents tenant isolation bypass via body in subdomain deployments.\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const hostTenant = tenantResolver.resolve(host);\n const tenantId = hostTenant ?? bodyTenantId ?? '';\n\n // Rate-limit GATE (peek, non-incrementing) BEFORE invoking the provider,\n // which runs a bcrypt compare (~300ms CPU at cost 12). Once the per-IP or\n // per-email failure window is exhausted we reject here, so a flood of\n // requests past the limit costs ~0 CPU instead of one bcrypt each. The\n // counter is only INCREMENTED on an actual auth failure (catch block\n // below) — successful logins never count, so legitimate users are never\n // throttled.\n if (rateLimiter) {\n const emailNorm = email.toLowerCase().trim();\n if (!(await peekLoginRateLimit(reply, request.ip, emailNorm, rateLimiter, authRateLimitCfg))) {\n return;\n }\n }\n\n try {\n const result = await userAuthService.login(\n { providerId: providerId ?? 'email-password', input: { email, password } },\n tenantId,\n { ip: request.ip, userAgent: request.headers['user-agent'] as string | undefined },\n );\n\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n\n return reply.send({ ok: true });\n } catch (err) {\n // CD-8: always return identical shape regardless of failure reason.\n if (err instanceof AuthError) {\n // Rate-limit only on failed authentication attempts. Counting only\n // failures prevents false positives for legitimate users while still\n // protecting against brute-force attacks.\n if (rateLimiter) {\n const emailNorm = email.toLowerCase().trim();\n if (!(await recordLoginFailure(reply, request.ip, emailNorm, rateLimiter, authRateLimitCfg))) {\n return;\n }\n }\n return reply.code(401).send({ error: 'invalid_credentials' });\n }\n throw err;\n }\n });\n\n // ── POST /auth/login/cli ────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES). CLI-only analogue of /auth/login: same\n // credential check, same shared rate-limit keys, but returns the token\n // pair in the JSON body instead of setting cookies — a CLI process has\n // nowhere to store a cookie. Deliberately a separate route rather than a\n // flag on /auth/login (see module docblock) so this route's shape is\n // statically \"always tokens in body, never cookies,\" not conditional.\n app.post<{ Body: { email?: string; password?: string; providerId?: string; tenantId?: string } }>('/auth/login/cli', {\n schema: { tags: ['Auth'], summary: 'Login with email/password (CLI: returns tokens in body)' },\n }, async (request, reply) => {\n const { email, password, providerId, tenantId: bodyTenantId } = request.body ?? {};\n if (typeof email !== 'string' || !email) {\n return reply.code(400).send({ error: 'Bad Request', message: 'email is required' });\n }\n if (typeof password !== 'string' || !password) {\n return reply.code(400).send({ error: 'Bad Request', message: 'password is required' });\n }\n\n const host = typeof request.headers.host === 'string' ? request.headers.host : '';\n const hostTenant = tenantResolver.resolve(host);\n const tenantId = hostTenant ?? bodyTenantId ?? '';\n\n if (rateLimiter) {\n const emailNorm = email.toLowerCase().trim();\n if (!(await peekLoginRateLimit(reply, request.ip, emailNorm, rateLimiter, authRateLimitCfg))) {\n return;\n }\n }\n\n try {\n const result = await userAuthService.login(\n { providerId: providerId ?? 'email-password', input: { email, password } },\n tenantId,\n { ip: request.ip, userAgent: request.headers['user-agent'] as string | undefined },\n );\n\n return reply.send({\n accessToken: result.access.token,\n refreshToken: result.refresh.token,\n expiresIn: accessTtl(result),\n tenantId,\n });\n } catch (err) {\n if (err instanceof AuthError) {\n if (rateLimiter) {\n const emailNorm = email.toLowerCase().trim();\n if (!(await recordLoginFailure(reply, request.ip, emailNorm, rateLimiter, authRateLimitCfg))) {\n return;\n }\n }\n return reply.code(401).send({ error: 'invalid_credentials' });\n }\n throw err;\n }\n });\n\n // ── POST /auth/refresh/cli ──────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES) — the refresh token in the body is the proof of\n // identity, same as the machine body-refresh path in routes.ts. CLI-only\n // analogue of the cookie-based user refresh (createUserRefreshFn below):\n // takes the refresh token as a plain body field instead of a cookie, and\n // returns the new pair in the body instead of Set-Cookie.\n app.post<{ Body: { refreshToken?: string } }>('/auth/refresh/cli', {\n schema: { tags: ['Auth'], summary: 'Refresh a CLI session token pair' },\n }, async (request, reply) => {\n const { refreshToken } = request.body ?? {};\n if (typeof refreshToken !== 'string' || !refreshToken) {\n return reply.code(400).send({ error: 'Bad Request', message: 'refreshToken is required' });\n }\n\n try {\n const result = await userAuthService.refresh(refreshToken);\n return reply.send({\n accessToken: result.access.token,\n refreshToken: result.refresh.token,\n expiresIn: accessTtl(result),\n });\n } catch (err) {\n if (err instanceof AuthError) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'Invalid or expired refresh token' });\n }\n throw err;\n }\n });\n\n // ── POST /auth/logout ───────────────────────────────────────────────────────\n // Cookie-auth, CSRF required.\n app.post('/auth/logout', {\n schema: { tags: ['Auth'], summary: 'Logout and clear session cookies' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const refreshCookie = getCookies(request)[COOKIE_REFRESH];\n if (refreshCookie) {\n // The service verifies the token internally — just pass it through.\n await userAuthService.logout(refreshCookie).catch(() => {});\n }\n\n clearSessionCookies(reply, cookieOpts);\n return reply.send({ ok: true });\n });\n\n // ── GET /auth/permissions ───────────────────────────────────────────────────\n // Cookie-auth. Returns the caller's effective permissions via PDP (CD-3).\n app.get('/auth/permissions', {\n schema: { tags: ['Auth'], summary: 'List permissions for the authenticated user' },\n }, async (request, reply) => {\n // User cookie auth takes precedence — enumerate via PDP for per-user RBAC.\n if (request.userAuthContext) {\n const ctx = request.userAuthContext;\n const permissions = await pdp.enumeratePermissions({\n userId: ctx.userId,\n tenantId: ctx.tenantId,\n type: 'user',\n });\n return reply.send({ permissions });\n }\n\n // Machine Bearer auth (including LOCAL_ADMIN when auth is disabled).\n // Permissions are already embedded in the machine AuthContext.\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized', message: 'No active session' });\n }\n return reply.send({ permissions: auth.permissions });\n });\n\n // ── POST /auth/activate ─────────────────────────────────────────────────────\n // Public (in PUBLIC_ROUTES). Creates user from invite + auto-logs in.\n app.post<{ Body: { token?: string; password?: string } }>('/auth/activate', {\n schema: { tags: ['Auth'], summary: 'Activate invite and create account (auto-login)' },\n }, async (request, reply) => {\n const { token, password } = request.body ?? {};\n if (typeof token !== 'string' || !token) {\n return reply.code(400).send({ error: 'Bad Request', message: 'token is required' });\n }\n if (typeof password !== 'string' || !password) {\n return reply.code(400).send({ error: 'Bad Request', message: 'password is required' });\n }\n\n try {\n const result = await userAuthService.activate({\n activationToken: token,\n password,\n deviceCtx: {\n ip: request.ip,\n userAgent: request.headers['user-agent'] as string | undefined,\n },\n });\n\n setSessionCookies(reply, {\n accessToken: result.access.token,\n accessTtlSec: accessTtl(result),\n refreshToken: result.refresh.token,\n refreshTtlSec: refreshTtl(result),\n csrfToken: result.csrf,\n }, cookieOpts);\n\n return reply.send({ ok: true });\n } catch (err) {\n if (err instanceof AuthError) {\n const code = (err as AuthError).code;\n if (code === 'unknown_invite') {\n // 401 Unauthorized: token not found (garbage, never issued, or swept by TTL).\n // Use error:'invalid_invite' so the activate-page shows the user-friendly\n // \"This invite link is invalid or expired\" message (same as 422 path).\n return reply.code(401).send({ error: 'invalid_invite', message: 'Invalid or expired invite' });\n }\n if (code === 'invalid_invite') {\n // 422 Unprocessable Entity: the token was found but is expired or already consumed.\n // The client (activate-page) maps error:'invalid_invite' to the\n // user-friendly \"This invite link is invalid or expired\" message.\n return reply.code(422).send({ error: 'invalid_invite', message: 'Invalid or expired invite' });\n }\n return reply.code(400).send({ error: 'Bad Request', message: err.message });\n }\n throw err;\n }\n });\n\n // ── POST /auth/password/change ──────────────────────────────────────────────\n // Cookie-auth, CSRF required.\n app.post<{ Body: { currentPassword?: string; newPassword?: string } }>('/auth/password/change', {\n schema: { tags: ['Auth'], summary: 'Change password (revokes all other sessions)' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const { currentPassword, newPassword } = request.body ?? {};\n if (!currentPassword || !newPassword) {\n return reply.code(400).send({\n error: 'Bad Request',\n message: 'currentPassword and newPassword are required',\n });\n }\n\n try {\n await userAuthService.changePassword({\n userId: ctx.userId,\n currentFamilyId: ctx.familyId,\n currentPassword,\n newPassword,\n });\n return reply.send({ ok: true });\n } catch (err) {\n if (err instanceof AuthError) {\n const code = (err as AuthError).code;\n if (code === 'invalid_current_password') {\n return reply.code(400).send({ error: 'Bad Request', message: 'Current password is incorrect' });\n }\n if (code === 'weak_password') {\n return reply.code(400).send({ error: 'Bad Request', message: err.message });\n }\n }\n throw err;\n }\n });\n\n // ── GET /auth/sessions ──────────────────────────────────────────────────────\n // Cookie-auth. Lists all session families for the authenticated user.\n app.get('/auth/sessions', {\n schema: { tags: ['Auth'], summary: 'List active sessions for the authenticated user' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n\n const families = await sessions.listFamiliesByUser(ctx.userId);\n return reply.send({\n sessions: families.map((f) => ({\n familyId: f.familyId,\n createdAt: f.createdAt,\n lastUsedAt: f.lastUsedAt,\n userAgent: f.userAgent,\n ipFirst: f.ipFirst,\n isCurrent: f.familyId === ctx.familyId,\n })),\n });\n });\n\n // ── POST /auth/sessions/revoke-all ──────────────────────────────────────────\n // Registered BEFORE /:fam/revoke to prevent param capture.\n // Cookie-auth, CSRF required.\n app.post('/auth/sessions/revoke-all', {\n schema: { tags: ['Auth'], summary: 'Revoke all sessions except the current one' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n await sessions.revokeAllUserSessionsExcept(ctx.userId, ctx.familyId);\n return reply.send({ ok: true });\n });\n\n // ── POST /auth/sessions/:fam/revoke ─────────────────────────────────────────\n // Cookie-auth, CSRF required.\n app.post<{ Params: { fam: string } }>('/auth/sessions/:fam/revoke', {\n schema: { tags: ['Auth'], summary: 'Revoke a specific session family' },\n }, async (request, reply) => {\n const ctx = requireUser(request, reply);\n if (!ctx) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const { fam } = request.params;\n\n // Ownership check — only allow revoking own sessions.\n const ownFamilies = await sessions.listFamiliesByUser(ctx.userId);\n if (!ownFamilies.some((f) => f.familyId === fam)) {\n return reply.code(404).send({ error: 'Not found', message: 'Session not found' });\n }\n\n await sessions.revokeFamily(fam);\n return reply.send({ ok: true });\n });\n\n // ── Admin permission helper ───────────────────────────────────────────────\n\n /** Checks the given permission; sends 401 or 403 and returns false on failure. */\n async function requirePermission(\n request: FastifyRequest,\n reply: FastifyReply,\n permission: string,\n ): Promise<boolean> {\n const ctx = requireUser(request, reply);\n if (!ctx) {return false;}\n\n const decision = await pdp.check(\n { userId: ctx.userId, tenantId: ctx.tenantId, type: 'user' },\n permission,\n );\n\n if (!decision.allow) {\n void reply.code(403).send({ error: 'Forbidden', message: `Permission denied: ${permission}` });\n return false;\n }\n return true;\n }\n\n // ── POST /auth/invites ──────────────────────────────────────────────────────\n app.post<{ Body: { email?: string; groupId?: string; ttlMs?: number } }>('/auth/invites', {\n schema: { tags: ['Auth'], summary: 'Create an invite for a new user (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.INVITES_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n const { email, groupId, ttlMs: bodyTtlMs } = request.body ?? {};\n if (!email || !groupId) {\n return reply.code(400).send({ error: 'Bad Request', message: 'email and groupId are required' });\n }\n\n // Allow callers to specify a custom TTL (e.g., short-lived invites for testing\n // AUTH-14). If not provided or invalid, fall back to the server default.\n const effectiveTtlMs =\n typeof bodyTtlMs === 'number' && bodyTtlMs > 0 ? bodyTtlMs : inviteTtlMs;\n\n const result = await invites.createInvite({\n email,\n tenantId: ctx.tenantId,\n groupId: groupId as 'tenant-admin' | 'tenant-member',\n createdBy: ctx.userId,\n ttlMs: effectiveTtlMs,\n });\n\n const host = typeof request.headers.host === 'string' ? request.headers.host : 'localhost';\n const protocol = cookieOpts.cookieSecure ? 'https' : 'http';\n const activationUrl = `${protocol}://${host}/activate?token=${result.activationToken}`;\n\n return reply.code(201).send({ inviteId: result.inviteId, activationUrl });\n });\n\n // ── POST /auth/invites/:id/revoke ────────────────────────────────────────────\n app.post<{ Params: { id: string } }>('/auth/invites/:id/revoke', {\n schema: { tags: ['Auth'], summary: 'Revoke a pending invite (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.INVITES_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n // Tenant-ownership guard: only revoke invites belonging to the admin's\n // tenant. Without this an admin of tenant A could revoke tenant B's invite\n // by guessing the id. 404 to avoid cross-tenant existence leakage.\n const invite = await invites.findById(request.params.id);\n if (!invite || invite.tenantId !== ctx.tenantId) {\n return reply.code(404).send({ error: 'Not found', message: 'Invite not found' });\n }\n\n await invites.revoke(request.params.id);\n return reply.send({ ok: true });\n });\n\n // ── GET /auth/invites ────────────────────────────────────────────────────────\n app.get('/auth/invites', {\n schema: { tags: ['Auth'], summary: 'List invites for the tenant (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.INVITES_READ))) {return;}\n\n const ctx = request.userAuthContext!;\n const all = await invites.listByTenant(ctx.tenantId);\n return reply.send({ invites: all });\n });\n\n // ── GET /auth/users ──────────────────────────────────────────────────────────\n app.get('/auth/users', {\n schema: { tags: ['Auth'], summary: 'List users for the tenant (admin only)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.USERS_READ))) {return;}\n\n const ctx = request.userAuthContext!;\n const all = await users.listByTenant(ctx.tenantId);\n return reply.send({\n users: all.map((u) => ({\n userId: u.userId,\n email: u.email,\n tenantId: u.tenantId,\n status: u.status,\n })),\n });\n });\n\n // ── POST /auth/users/:id/disable ────────────────────────────────────────────\n // CD-1: user-auth-middleware checks user.status on every request, so this\n // takes effect immediately without waiting for token expiry.\n app.post<{ Params: { id: string } }>('/auth/users/:id/disable', {\n schema: { tags: ['Auth'], summary: 'Disable a user account (immediate via CD-1)' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.USERS_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n const { id } = request.params;\n const target = await users.getById(id);\n // Tenant-ownership guard: an admin may only act on users in their own\n // tenant. requirePermission only proves \"you are an admin of ctx.tenantId\",\n // not that the target belongs there. Return 404 (not 403) so we don't leak\n // the existence of users in other tenants.\n if (!target || target.tenantId !== ctx.tenantId) {\n return reply.code(404).send({ error: 'Not found', message: 'User not found' });\n }\n\n await users.setStatus(id, 'disabled');\n await sessions.revokeAllUserSessions(id);\n\n return reply.send({ ok: true });\n });\n\n // ── POST /auth/users/:id/enable ─────────────────────────────────────────────\n app.post<{ Params: { id: string } }>('/auth/users/:id/enable', {\n schema: { tags: ['Auth'], summary: 'Re-enable a disabled user account' },\n }, async (request, reply) => {\n if (!(await requirePermission(request, reply, PERMISSIONS.USERS_WRITE))) {return;}\n if (!checkCsrf(request, reply)) {return;}\n\n const ctx = request.userAuthContext!;\n const { id } = request.params;\n const target = await users.getById(id);\n // Tenant-ownership guard (see /disable). 404 to avoid cross-tenant leakage.\n if (!target || target.tenantId !== ctx.tenantId) {\n return reply.code(404).send({ error: 'Not found', message: 'User not found' });\n }\n\n await users.setStatus(id, 'active');\n return reply.send({ ok: true });\n });\n}\n","/**\n * @module gateway-app/execute/execution-registry\n *\n * Tracks active executions with AbortController for cancellation.\n *\n * Lifecycle:\n * 1. POST /execute → registry.register(executionId, ...) → AbortSignal\n * 2. POST /execute/:id/cancel → registry.cancel(executionId, reason) → abort()\n * 3. Execution completes or aborted → registry.remove(executionId)\n *\n * Also supports host disconnect: cancelByHost() aborts all executions\n * dispatched to a host that went offline.\n */\n\nimport type { CancellationReason } from '@kb-labs/core-contracts';\n\nexport interface ActiveExecution {\n executionId: string;\n requestId: string;\n namespaceId: string;\n hostId: string;\n pluginId: string;\n handlerRef: string;\n controller: AbortController;\n startedAt: number;\n cancelledReason?: CancellationReason;\n}\n\nexport class ExecutionRegistry {\n private executions = new Map<string, ActiveExecution>();\n\n /** Register a new execution. Returns AbortSignal to wire into the dispatch. */\n register(entry: Omit<ActiveExecution, 'controller' | 'startedAt'>): AbortSignal {\n const controller = new AbortController();\n this.executions.set(entry.executionId, {\n ...entry,\n controller,\n startedAt: Date.now(),\n });\n return controller.signal;\n }\n\n /** Cancel an execution by ID. Returns true if found and aborted. */\n cancel(executionId: string, reason: CancellationReason): boolean {\n const entry = this.executions.get(executionId);\n if (!entry) { return false; }\n if (entry.controller.signal.aborted) { return false; }\n\n entry.cancelledReason = reason;\n entry.controller.abort(reason);\n return true;\n }\n\n /** Remove a completed/cancelled execution. */\n remove(executionId: string): void {\n this.executions.delete(executionId);\n }\n\n /** Get an active execution. */\n get(executionId: string): ActiveExecution | undefined {\n return this.executions.get(executionId);\n }\n\n /** Cancel all executions dispatched to a host (on host disconnect). */\n cancelByHost(hostId: string, reason: CancellationReason): string[] {\n const cancelled: string[] = [];\n for (const entry of this.executions.values()) {\n if (entry.hostId === hostId && !entry.controller.signal.aborted) {\n entry.cancelledReason = reason;\n entry.controller.abort(reason);\n cancelled.push(entry.executionId);\n }\n }\n return cancelled;\n }\n\n /** Number of active executions. */\n get size(): number {\n return this.executions.size;\n }\n}\n\n/** Singleton — shared across Gateway process. */\nexport const executionRegistry = new ExecutionRegistry();\n","/**\n * @module gateway-app/clients/subscription-registry\n *\n * Tracks which client connections are subscribed to which executions.\n * Gateway broadcasts ExecutionEvents to all subscribers of an execution.\n *\n * Lifecycle:\n * - client sends client:subscribe → subscribe(connectionId, executionId)\n * - client sends client:unsubscribe → unsubscribe(connectionId, executionId)\n * - execution emits event → broadcast(executionId, event) → all subscribers\n * - client disconnects → removeConnection(connectionId) → cleanup\n *\n * The initiator of POST /api/v1/execute is NOT auto-subscribed here —\n * they receive events inline via ndjson stream. This registry is for\n * secondary observers joining an in-flight execution.\n */\n\nimport type { WebSocket } from '@fastify/websocket';\nimport type { ExecutionEventMessage } from '@kb-labs/gateway-contracts';\n\nexport interface ISubscriptionRegistry {\n subscribe(connectionId: string, executionId: string): void;\n unsubscribe(connectionId: string, executionId: string): void;\n getSubscribers(executionId: string): ReadonlySet<string>;\n getSubscriptions(connectionId: string): ReadonlySet<string>;\n /** Called on client disconnect. Returns executionIds that now have zero subscribers. */\n removeConnection(connectionId: string): string[];\n broadcast(executionId: string, event: ExecutionEventMessage): void;\n}\n\nexport class SubscriptionRegistry implements ISubscriptionRegistry {\n /** executionId → Set<connectionId> */\n private readonly byExecution = new Map<string, Set<string>>();\n /** connectionId → Set<executionId> */\n private readonly byConnection = new Map<string, Set<string>>();\n /** connectionId → WebSocket (for sending events) */\n private readonly sockets = new Map<string, WebSocket>();\n\n /** Register a WebSocket for a connection. Must be called before subscribe(). */\n registerSocket(connectionId: string, socket: WebSocket): void {\n this.sockets.set(connectionId, socket);\n }\n\n /** Remove a connection's socket on disconnect. */\n removeSocket(connectionId: string): void {\n this.sockets.delete(connectionId);\n }\n\n subscribe(connectionId: string, executionId: string): void {\n let executionSubs = this.byExecution.get(executionId);\n if (!executionSubs) {\n executionSubs = new Set();\n this.byExecution.set(executionId, executionSubs);\n }\n executionSubs.add(connectionId);\n\n let connectionSubs = this.byConnection.get(connectionId);\n if (!connectionSubs) {\n connectionSubs = new Set();\n this.byConnection.set(connectionId, connectionSubs);\n }\n connectionSubs.add(executionId);\n }\n\n unsubscribe(connectionId: string, executionId: string): void {\n this.byExecution.get(executionId)?.delete(connectionId);\n this.byConnection.get(connectionId)?.delete(executionId);\n\n // GC empty sets\n if (this.byExecution.get(executionId)?.size === 0) {\n this.byExecution.delete(executionId);\n }\n if (this.byConnection.get(connectionId)?.size === 0) {\n this.byConnection.delete(connectionId);\n }\n }\n\n getSubscribers(executionId: string): ReadonlySet<string> {\n return this.byExecution.get(executionId) ?? new Set();\n }\n\n getSubscriptions(connectionId: string): ReadonlySet<string> {\n return this.byConnection.get(connectionId) ?? new Set();\n }\n\n removeConnection(connectionId: string): string[] {\n const subscriptions = this.byConnection.get(connectionId);\n if (!subscriptions) {\n this.sockets.delete(connectionId);\n return [];\n }\n\n const orphaned: string[] = [];\n for (const executionId of subscriptions) {\n const subs = this.byExecution.get(executionId);\n if (subs) {\n subs.delete(connectionId);\n if (subs.size === 0) {\n this.byExecution.delete(executionId);\n orphaned.push(executionId);\n }\n }\n }\n\n this.byConnection.delete(connectionId);\n this.sockets.delete(connectionId);\n return orphaned;\n }\n\n broadcast(executionId: string, event: ExecutionEventMessage): void {\n const subscribers = this.byExecution.get(executionId);\n if (!subscribers || subscribers.size === 0) { return; }\n\n const payload = JSON.stringify(event);\n for (const connectionId of subscribers) {\n const socket = this.sockets.get(connectionId);\n if (socket && socket.readyState === socket.OPEN) {\n socket.send(payload);\n }\n }\n }\n\n get connectionCount(): number {\n return this.byConnection.size;\n }\n\n get subscriptionCount(): number {\n let total = 0;\n for (const subs of this.byExecution.values()) {\n total += subs.size;\n }\n return total;\n }\n}\n\n/** Singleton — shared across Gateway process. */\nexport const subscriptionRegistry = new SubscriptionRegistry();\n","/**\n * @module gateway-app/execute/errors\n *\n * Shared error types for execution pipeline.\n */\n\nimport type { CancellationReason } from '@kb-labs/core-contracts';\n\n/**\n * Thrown when an execution is cancelled (CC2).\n * Caught by routes.ts to emit execution:cancelled + execution:done(130).\n */\nexport class CancelledError extends Error {\n readonly reason: CancellationReason;\n\n constructor(reason: CancellationReason) {\n super(`Execution cancelled: ${reason}`);\n this.name = 'CancelledError';\n this.reason = reason;\n }\n}\n","/**\n * @module gateway-app/execute/retry-executor\n *\n * Level 2 retry wrapper for execution dispatch (CC3).\n *\n * Wraps a dispatch function with configurable retry + exponential backoff.\n * Emits execution:retry events between attempts so clients see progress.\n * Respects AbortSignal — cancels immediately, no retry after abort.\n *\n * Each attempt is raced against the AbortSignal so that a cancelled\n * execution doesn't block on a hung dispatcher call.\n */\n\nimport type { ExecutionRetryConfig, CancellationReason } from '@kb-labs/core-contracts';\nimport type { ExecutionEventMessage } from '@kb-labs/gateway-contracts';\nimport { CancelledError } from './errors.js';\n\nconst DEFAULTS: Required<ExecutionRetryConfig> = {\n maxAttempts: 1,\n initialDelayMs: 1000,\n backoffMultiplier: 2,\n maxDelayMs: 30_000,\n onlyRetryable: true,\n};\n\nexport interface RetryContext {\n executionId: string;\n requestId: string;\n signal: AbortSignal;\n config: ExecutionRetryConfig | undefined;\n /** Emit event to client stream (and WS subscribers via routes.ts). */\n write: (event: ExecutionEventMessage) => void;\n}\n\n/**\n * Execute dispatch function with retry + abort-race logic.\n *\n * - maxAttempts=1 (default) → single call, raced against signal.\n * - maxAttempts>1 → retry loop with backoff, each attempt raced against signal.\n */\nexport async function executeWithRetry<T>(\n ctx: RetryContext,\n dispatch: () => Promise<T>,\n): Promise<T> {\n const cfg = { ...DEFAULTS, ...ctx.config };\n const maxAttempts = Math.max(1, cfg.maxAttempts);\n\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n if (ctx.signal.aborted) {\n throw new CancelledError(ctx.signal.reason as CancellationReason);\n }\n\n try {\n return await raceAbort(ctx.signal, dispatch());\n } catch (err) {\n // Cancellation is never retried\n if (err instanceof CancelledError) { throw err; }\n\n lastError = err instanceof Error ? err : new Error(String(err));\n\n // Last attempt — propagate error\n if (attempt >= maxAttempts) { break; }\n\n // Check if error is retryable\n const classified = classifyError(err);\n if (cfg.onlyRetryable && !classified.retryable) { break; }\n\n // Backoff delay\n const delay = Math.min(\n cfg.initialDelayMs * Math.pow(cfg.backoffMultiplier, attempt - 1),\n cfg.maxDelayMs,\n );\n\n ctx.write({\n type: 'execution:retry',\n requestId: ctx.requestId,\n executionId: ctx.executionId,\n attempt,\n maxAttempts,\n delayMs: delay,\n error: classified.message,\n } satisfies ExecutionEventMessage);\n\n await interruptibleDelay(delay, ctx.signal);\n }\n }\n\n throw lastError ?? new Error('executeWithRetry: no attempts made');\n}\n\n// ── Internals ──\n\n/**\n * Race a promise against an AbortSignal.\n */\nfunction raceAbort<T>(signal: AbortSignal, promise: Promise<T>): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(new CancelledError(signal.reason as CancellationReason));\n }\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(new CancelledError(signal.reason as CancellationReason));\n signal.addEventListener('abort', onAbort, { once: true });\n\n promise.then(\n (v) => { signal.removeEventListener('abort', onAbort); resolve(v); },\n (e) => { signal.removeEventListener('abort', onAbort); reject(e); },\n );\n });\n}\n\n/**\n * Sleep interruptible by AbortSignal.\n */\nfunction interruptibleDelay(ms: number, signal: AbortSignal): Promise<void> {\n if (signal.aborted) {\n return Promise.reject(new CancelledError(signal.reason as CancellationReason));\n }\n\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(new CancelledError(signal.reason as CancellationReason));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\ninterface ClassifiedError {\n code: string;\n message: string;\n retryable: boolean;\n}\n\nfunction classifyError(err: unknown): ClassifiedError {\n if (!(err instanceof Error)) {\n return { code: 'UNKNOWN', message: String(err), retryable: false };\n }\n\n const msg = err.message;\n\n // Transport / network — retryable\n if (msg.includes('ECONNREFUSED') || msg.includes('ECONNRESET') ||\n msg.includes('ETIMEDOUT') || msg.includes('timed out') ||\n msg.includes('503') || msg.includes('Service Unavailable')) {\n return { code: 'TRANSPORT_ERROR', message: msg, retryable: true };\n }\n\n // Host went offline — retryable (may reconnect)\n if (msg.includes('Host not connected')) {\n return { code: 'HOST_UNAVAILABLE', message: msg, retryable: true };\n }\n\n // Everything else — not retryable\n return { code: 'HANDLER_ERROR', message: msg, retryable: false };\n}\n","/**\n * @module gateway-app/execute/routes\n *\n * POST /api/v1/execute — Execute handler via Gateway with ndjson streaming.\n * POST /api/v1/execute/:executionId/cancel — Cancel an active execution.\n *\n * Response: Transfer-Encoding: chunked, Content-Type: application/x-ndjson\n * Each line = JSON ExecutionEvent.\n *\n * Integrates:\n * CC2 — Cancellation via ExecutionRegistry + AbortController\n * CC3 — Retry via executeWithRetry (exponential backoff, retryable errors)\n * CC5 — Broadcast to WS subscribers via SubscriptionRegistry\n */\n\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport { randomUUID } from 'node:crypto';\nimport { ExecuteRequestSchema, type ExecutionEventMessage } from '@kb-labs/gateway-contracts';\nimport { logDiagnosticEvent, type ILogger } from '@kb-labs/core-platform';\nimport type { CancellationReason } from '@kb-labs/core-contracts';\nimport { globalDispatcher } from '../hosts/dispatcher.js';\nimport { executionRegistry } from './execution-registry.js';\nimport { subscriptionRegistry } from '../clients/subscription-registry.js';\nimport { executeWithRetry } from './retry-executor.js';\nimport { CancelledError } from './errors.js';\n\nexport function registerExecuteRoutes(app: FastifyInstance, logger: ILogger): void {\n /**\n * POST /api/v1/execute\n * hide: true — uses ndjson chunked streaming via reply.raw, incompatible with OpenAPI response schema\n */\n app.post('/api/v1/execute', { schema: { tags: ['Execute'], summary: 'Execute a plugin handler', hide: true } }, async (request: FastifyRequest, reply: FastifyReply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const parsed = ExecuteRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n\n const { pluginId, handlerRef, exportName, input, timeoutMs } = parsed.data;\n const executionId = randomUUID();\n const requestId = randomUUID();\n const startTime = Date.now();\n\n logger.info('Execute request received', {\n executionId,\n pluginId,\n handlerRef,\n namespaceId: auth.namespaceId,\n });\n\n // Resolve host with 'execution' capability\n const hostId = globalDispatcher.firstHostWithCapability(auth.namespaceId, 'execution');\n if (!hostId) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.execution.dispatch',\n level: 'warn',\n reasonCode: 'execution_host_unavailable',\n message: 'No execution host connected for namespace',\n outcome: 'failed',\n serviceId: 'gateway',\n evidence: {\n namespaceId: auth.namespaceId,\n pluginId,\n handlerRef,\n },\n });\n return reply.code(503).send({\n error: 'No execution host connected',\n hint: 'Ensure a RuntimeServer is running and connected to Gateway',\n namespaceId: auth.namespaceId,\n });\n }\n\n // Register in execution registry (CC2)\n const signal = executionRegistry.register({\n executionId,\n requestId,\n namespaceId: auth.namespaceId,\n hostId,\n pluginId,\n handlerRef,\n });\n\n // Auto-cancel on client disconnect.\n // reply.raw 'close' fires when connection drops before response finishes.\n // Check writableFinished to distinguish mid-stream disconnect from normal completion.\n reply.raw.on('close', () => {\n if (!reply.raw.writableFinished && !signal.aborted) {\n executionRegistry.cancel(executionId, 'disconnect');\n }\n });\n\n // Hijack response for ndjson streaming\n reply.raw.writeHead(200, {\n 'Content-Type': 'application/x-ndjson',\n 'Transfer-Encoding': 'chunked',\n 'Cache-Control': 'no-cache',\n 'X-Execution-Id': executionId,\n });\n // Flush headers immediately so the client can see X-Execution-Id before any events\n reply.raw.flushHeaders();\n\n // Write typed event to initiator ndjson stream + broadcast to WS subscribers (CC5)\n const writeEvent = (event: ExecutionEventMessage): void => {\n const payload = JSON.stringify(event) + '\\n';\n if (!reply.raw.writableEnded) {\n reply.raw.write(payload);\n }\n subscriptionRegistry.broadcast(executionId, event);\n };\n\n try {\n // Dispatch with retry + abort-race (CC2 + CC3)\n // TODO: read retry config from platform config when available\n const result = await executeWithRetry(\n { executionId, requestId, signal, config: undefined, write: writeEvent },\n () => globalDispatcher.call(\n auth.namespaceId,\n hostId,\n 'execution',\n 'execute',\n [{ pluginId, handlerRef, exportName, input, executionId, requestId, timeoutMs }],\n ),\n );\n\n writeEvent({\n type: 'execution:done',\n requestId,\n executionId,\n exitCode: 0,\n durationMs: Date.now() - startTime,\n metadata: { result: result as Record<string, unknown> },\n });\n } catch (err) {\n if (err instanceof CancelledError) {\n writeEvent({\n type: 'execution:cancelled',\n requestId,\n executionId,\n reason: err.reason ?? 'user',\n durationMs: Date.now() - startTime,\n });\n\n writeEvent({\n type: 'execution:done',\n requestId,\n executionId,\n exitCode: 130,\n durationMs: Date.now() - startTime,\n });\n } else {\n const message = err instanceof Error ? err.message : String(err);\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.execution.dispatch',\n level: 'error',\n reasonCode: 'execution_dispatch_failed',\n message: 'Gateway execution dispatch failed',\n outcome: 'failed',\n error: err instanceof Error ? err : new Error(String(err)),\n serviceId: 'gateway',\n evidence: {\n namespaceId: auth.namespaceId,\n executionId,\n requestId,\n pluginId,\n handlerRef,\n hostId,\n },\n });\n\n writeEvent({\n type: 'execution:error',\n requestId,\n executionId,\n code: 'EXECUTION_FAILED',\n message,\n retryable: false,\n });\n\n writeEvent({\n type: 'execution:done',\n requestId,\n executionId,\n exitCode: 1,\n durationMs: Date.now() - startTime,\n });\n }\n } finally {\n executionRegistry.remove(executionId);\n if (!reply.raw.writableEnded) {\n reply.raw.end();\n }\n }\n });\n\n /**\n * POST /api/v1/execute/:executionId/cancel\n */\n app.post('/api/v1/execute/:executionId/cancel', { schema: { tags: ['Execute'], summary: 'Cancel an active execution' } }, async (request: FastifyRequest, reply: FastifyReply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const { executionId } = request.params as { executionId: string };\n const body = request.body as { reason?: string } | undefined;\n const reason = (body?.reason ?? 'user') as CancellationReason;\n\n const execution = executionRegistry.get(executionId);\n if (!execution) {\n return reply.code(404).send({ error: 'Execution not found or already completed' });\n }\n\n if (execution.namespaceId !== auth.namespaceId) {\n return reply.code(403).send({ error: 'Forbidden — execution belongs to another namespace' });\n }\n\n const cancelled = executionRegistry.cancel(executionId, reason);\n\n logger.info('Cancel request processed', {\n executionId,\n reason,\n cancelled,\n namespaceId: auth.namespaceId,\n });\n\n return reply.code(cancelled ? 200 : 409).send({\n executionId,\n status: cancelled ? 'cancelled' : 'already_cancelled',\n reason,\n });\n });\n}\n","/**\n * @module AI Gateway — OpenAI-compatible LLM endpoint.\n *\n * Exposes `POST /api/v1/llm/chat/completions` using OpenAI ChatCompletion format.\n * Model field is a tier abstraction (small/medium/large) — never a literal model name.\n * All calls go through the platform LLM chain: QueuedLLM → AnalyticsLLM → LLMRouter → adapter.\n */\nimport type { FastifyInstance } from 'fastify';\nimport { platform } from '@kb-labs/core-runtime';\nimport type {\n ILLM,\n ILogger,\n LLMMessage,\n LLMToolCallOptions,\n LLMTool,\n ILLMRouter,\n LLMTier,\n} from '@kb-labs/core-platform';\nimport {\n ChatCompletionRequestSchema,\n type ChatCompletionRequest,\n type ChatCompletionResponse,\n type ChatCompletionChunk,\n} from '@kb-labs/gateway-contracts';\n\n// ── Tier resolution ───────────────────────────────────────────────────────\n\nfunction isLLMRouter(llm: ILLM): llm is ILLM & ILLMRouter {\n return typeof (llm as any).resolveAdapter === 'function';\n}\n\n/**\n * Resolve tier to a concrete ILLM adapter via LLMRouter.\n * If no router (single-adapter setup), returns platform.llm directly.\n */\nasync function resolveLLMForTier(tier: LLMTier): Promise<ILLM | undefined> {\n const llm = platform.llm;\n if (!llm) {return undefined;}\n\n if (isLLMRouter(llm)) {\n const binding = await llm.resolveAdapter({ tier });\n return binding.adapter;\n }\n\n // Single adapter — ignore tier, return as-is\n return llm;\n}\n\n// ── Route registration ────────────────────────────────────────────────────\n\n/**\n * Register AI Gateway routes on the given Fastify scope.\n * The scope is expected to have the auth middleware already applied.\n */\nexport function registerLLMGatewayRoutes(app: FastifyInstance, logger: ILogger): void {\n // hide: true — can stream SSE (text/event-stream), incompatible with OpenAPI response schema\n app.post('/api/v1/llm/chat/completions', { schema: { tags: ['LLM'], summary: 'OpenAI-compatible chat completions', hide: true } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const parsed = ChatCompletionRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({\n error: {\n message: 'Bad Request',\n type: 'invalid_request_error',\n code: null,\n param: null,\n },\n issues: parsed.error.issues,\n });\n }\n\n const req = parsed.data;\n const requestId = `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n // Resolve tier to LLM adapter\n const llm = await resolveLLMForTier(req.model);\n if (!llm) {\n return reply.code(503).send({\n error: {\n message: `LLM not available for tier \"${req.model}\"`,\n type: 'server_error',\n code: null,\n param: null,\n },\n });\n }\n\n logger.info('AI Gateway request', {\n requestId,\n tier: req.model,\n stream: req.stream,\n messageCount: req.messages.length,\n hasTools: !!req.tools?.length,\n tenantId: auth.namespaceId,\n });\n\n try {\n if (req.stream) {\n return await handleStreamingRequest(reply, llm, req, requestId, logger);\n }\n return await handleCompletionRequest(reply, llm, req, requestId);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error('AI Gateway error', error, { requestId, tier: req.model });\n return reply.code(500).send({\n error: {\n message: 'Internal server error',\n type: 'server_error',\n code: null,\n param: null,\n },\n });\n }\n });\n}\n\n// ── Non-streaming handler ─────────────────────────────────────────────────\n\nasync function handleCompletionRequest(\n reply: any,\n llm: ILLM,\n req: ChatCompletionRequest,\n requestId: string,\n) {\n const messages = toILLMMessages(req);\n const startTime = Date.now();\n const hasTools = req.tools && req.tools.length > 0;\n\n if (hasTools && llm.chatWithTools) {\n const tools = toILLMTools(req.tools!);\n const options: LLMToolCallOptions = {\n temperature: req.temperature,\n maxTokens: req.max_tokens,\n stop: normalizeStop(req.stop),\n tools,\n toolChoice: req.tool_choice as LLMToolCallOptions['toolChoice'],\n };\n\n const result = await llm.chatWithTools(messages, options);\n\n const toolCalls = result.toolCalls?.map((tc) => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.name,\n arguments: typeof tc.input === 'string' ? tc.input : JSON.stringify(tc.input),\n },\n }));\n\n const finishReason =\n result.stopReason === 'tool_use'\n ? ('tool_calls' as const)\n : result.stopReason === 'max_tokens'\n ? ('length' as const)\n : ('stop' as const);\n\n const response: ChatCompletionResponse = {\n id: requestId,\n object: 'chat.completion',\n created: Math.floor(startTime / 1000),\n model: req.model,\n choices: [\n {\n index: 0,\n message: {\n role: 'assistant',\n content: result.content || null,\n ...(toolCalls?.length ? { tool_calls: toolCalls } : {}),\n },\n finish_reason: finishReason,\n },\n ],\n usage: {\n prompt_tokens: result.usage.promptTokens,\n completion_tokens: result.usage.completionTokens,\n total_tokens: result.usage.promptTokens + result.usage.completionTokens,\n },\n };\n\n return reply.code(200).send(response);\n }\n\n // No tools — use simple complete()\n const systemPrompt = messages.find((m) => m.role === 'system')?.content;\n const userMessages = messages.filter((m) => m.role !== 'system');\n const prompt = userMessages.map((m) => m.content).join('\\n\\n');\n\n const result = await llm.complete(prompt, {\n systemPrompt,\n temperature: req.temperature,\n maxTokens: req.max_tokens,\n stop: normalizeStop(req.stop),\n });\n\n const response: ChatCompletionResponse = {\n id: requestId,\n object: 'chat.completion',\n created: Math.floor(startTime / 1000),\n model: req.model,\n choices: [\n {\n index: 0,\n message: { role: 'assistant', content: result.content },\n finish_reason: 'stop',\n },\n ],\n usage: {\n prompt_tokens: result.usage.promptTokens,\n completion_tokens: result.usage.completionTokens,\n total_tokens: result.usage.promptTokens + result.usage.completionTokens,\n },\n };\n\n return reply.code(200).send(response);\n}\n\n// ── Streaming handler ─────────────────────────────────────────────────────\n\nasync function handleStreamingRequest(\n reply: any,\n llm: ILLM,\n req: ChatCompletionRequest,\n requestId: string,\n logger: ILogger,\n) {\n const created = Math.floor(Date.now() / 1000);\n\n reply.raw.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'X-Request-Id': requestId,\n });\n reply.raw.flushHeaders();\n\n const writeChunk = (chunk: ChatCompletionChunk): void => {\n if (!reply.raw.writableEnded) {\n reply.raw.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n };\n\n const writeDone = (): void => {\n if (!reply.raw.writableEnded) {\n reply.raw.write('data: [DONE]\\n\\n');\n reply.raw.end();\n }\n };\n\n try {\n // Initial role chunk\n writeChunk({\n id: requestId,\n object: 'chat.completion.chunk',\n created,\n model: req.model,\n choices: [{ index: 0, delta: { role: 'assistant' }, finish_reason: null }],\n });\n\n // Stream text from LLM\n const systemPrompt = req.messages.find((m) => m.role === 'system')?.content;\n const userMessages = req.messages.filter((m) => m.role !== 'system');\n const prompt = userMessages.map((m) => m.content).join('\\n\\n');\n\n for await (const text of llm.stream(prompt, {\n systemPrompt,\n temperature: req.temperature,\n maxTokens: req.max_tokens,\n stop: normalizeStop(req.stop),\n })) {\n writeChunk({\n id: requestId,\n object: 'chat.completion.chunk',\n created,\n model: req.model,\n choices: [{ index: 0, delta: { content: text }, finish_reason: null }],\n });\n }\n\n // Finish chunk\n writeChunk({\n id: requestId,\n object: 'chat.completion.chunk',\n created,\n model: req.model,\n choices: [{ index: 0, delta: {}, finish_reason: 'stop' }],\n });\n\n writeDone();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error('AI Gateway stream error', error, { requestId });\n if (!reply.raw.writableEnded) {\n reply.raw.write(\n `data: ${JSON.stringify({ error: { message: error.message, type: 'server_error' } })}\\n\\n`,\n );\n reply.raw.end();\n }\n }\n\n return reply;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction toILLMMessages(req: ChatCompletionRequest): LLMMessage[] {\n return req.messages.map((m) => {\n const msg: LLMMessage = { role: m.role, content: m.content };\n if (m.tool_call_id) {msg.toolCallId = m.tool_call_id;}\n if (m.tool_calls) {\n msg.toolCalls = m.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n input: safeJsonParse(tc.function.arguments),\n }));\n }\n return msg;\n });\n}\n\nfunction toILLMTools(tools: NonNullable<ChatCompletionRequest['tools']>): LLMTool[] {\n return tools.map((t) => ({\n name: t.function.name,\n description: t.function.description ?? '',\n inputSchema: t.function.parameters ?? {},\n }));\n}\n\nfunction normalizeStop(stop: string | string[] | undefined): string[] | undefined {\n if (!stop) {return undefined;}\n return Array.isArray(stop) ? stop : [stop];\n}\n\nfunction safeJsonParse(str: string): unknown {\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n","/**\n * @module Telemetry Ingestion — unified event collection endpoint.\n *\n * Exposes `POST /telemetry/v1/ingest` for external products to send events.\n * Events are written to platform analytics via IAnalytics.track().\n * Auth required — tenantId extracted from auth context.\n */\nimport type { FastifyInstance } from 'fastify';\nimport { platform } from '@kb-labs/core-runtime';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport {\n TelemetryIngestRequestSchema,\n type TelemetryIngestResponse,\n} from '@kb-labs/gateway-contracts';\n\n/**\n * Register telemetry ingestion routes on the given Fastify scope.\n * The scope is expected to have the auth middleware already applied.\n */\nexport function registerTelemetryRoutes(app: FastifyInstance, logger: ILogger): void {\n app.post('/telemetry/v1/ingest', { schema: { tags: ['Telemetry'], summary: 'Ingest telemetry events' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const parsed = TelemetryIngestRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({\n error: 'Bad Request',\n issues: parsed.error.issues,\n });\n }\n\n const analytics = platform.analytics;\n if (!analytics) {\n return reply.code(503).send({\n error: 'Analytics adapter not configured',\n });\n }\n\n const { events } = parsed.data;\n let accepted = 0;\n let rejected = 0;\n const errors: Array<{ index: number; message: string }> = [];\n\n for (let i = 0; i < events.length; i++) {\n const event = events[i]!;\n try {\n await analytics.track(event.type, {\n // Source attribution — who sent this event\n _source: event.source,\n _tenantId: auth.namespaceId,\n _ts: event.timestamp ?? new Date().toISOString(),\n // Tags as flat properties for indexing\n ...event.tags,\n // Free-form payload\n ...event.payload,\n });\n accepted++;\n } catch (err) {\n rejected++;\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ index: i, message });\n logger.warn('Telemetry event rejected', {\n index: i,\n type: event.type,\n source: event.source,\n error: message,\n });\n }\n }\n\n logger.info('Telemetry ingest', {\n tenantId: auth.namespaceId,\n accepted,\n rejected,\n totalEvents: events.length,\n });\n\n const response: TelemetryIngestResponse = {\n accepted,\n rejected,\n ...(errors.length > 0 ? { errors } : {}),\n };\n\n return reply.code(accepted > 0 ? 200 : 422).send(response);\n });\n}\n","/**\n * @module Unified Platform API — single dispatch for any adapter.\n *\n * Route: POST /platform/v1/{adapter}/{method}\n *\n * Provides a single entry point for all platform adapters (LLM, Cache,\n * VectorStore, Analytics, Storage, Embeddings, etc.). Adapter and method\n * come from URL params; arguments come from the request body.\n *\n * Security: only methods explicitly listed in ALLOWED_METHODS are callable.\n */\nimport type { FastifyInstance } from 'fastify';\nimport { platform } from '@kb-labs/core-runtime';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport {\n PlatformCallRequestSchema,\n type PlatformCallResponse,\n} from '@kb-labs/gateway-contracts';\n\n// ── Method allowlist ──────────────────────────────────────────────────────\n// Only methods listed here are callable via the Platform API.\n// Internal/lifecycle methods (setSource, shutdown, etc.) are NOT exposed.\n// Intentionally static — new methods must be added here explicitly;\n// dynamic derivation from the adapter list would bypass security review.\n\nconst ALLOWED_METHODS: Record<string, Set<string>> = {\n llm: new Set(['complete', 'stream', 'chatWithTools']),\n cache: new Set(['get', 'set', 'delete', 'clear']),\n vectorStore: new Set(['search', 'upsert', 'delete', 'count']),\n analytics: new Set(['track', 'identify', 'flush', 'getEvents', 'getStats', 'getDailyStats']),\n embeddings: new Set(['embed']),\n storage: new Set(['read', 'write', 'delete', 'list', 'exists']),\n eventBus: new Set(['publish', 'subscribe']),\n documentDatabase: new Set([\n 'find', 'findById', 'count',\n 'insertOne', 'insertMany',\n 'updateOne', 'updateMany', 'updateById',\n 'deleteMany', 'deleteById',\n 'bulkWrite',\n 'ensureCollection',\n 'ping',\n ]),\n kvStore: new Set([\n 'get', 'getMany',\n 'set', 'setMany', 'setIfNotExists',\n 'delete', 'exists',\n 'cas', 'incr',\n 'ttl', 'expire', 'persist',\n 'ping',\n ]),\n};\n\n// ── Adapter resolution ────────────────────────────────────────────────────\n\nfunction resolveAdapter(name: string): unknown | undefined {\n // Map URL param to platform property\n const adapterMap: Record<string, () => unknown> = {\n llm: () => platform.llm,\n cache: () => platform.cache,\n analytics: () => platform.analytics,\n vectorStore: () => platform.vectorStore,\n embeddings: () => platform.embeddings,\n storage: () => platform.storage,\n eventBus: () => platform.eventBus,\n documentDatabase: () => platform.documentDatabase,\n kvStore: () => platform.kvStore,\n };\n\n const getter = adapterMap[name];\n return getter ? getter() : undefined;\n}\n\n// ── Streaming detection ───────────────────────────────────────────────────\n\nfunction isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n Symbol.asyncIterator in (value as object)\n );\n}\n\n// ── Route registration ────────────────────────────────────────────────────\n\nexport function registerPlatformRoutes(app: FastifyInstance, logger: ILogger): void {\n // hide: true — can return SSE (text/event-stream) for streaming adapter calls, incompatible with OpenAPI response schema\n app.post<{ Params: { adapter: string; method: string } }>(\n '/platform/v1/:adapter/:method',\n { schema: { tags: ['Platform'], summary: 'Invoke a platform adapter method', hide: true } },\n async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const { adapter: adapterName, method: methodName } = request.params;\n\n // 1. Check adapter is in allowlist\n const allowedMethods = ALLOWED_METHODS[adapterName];\n if (!allowedMethods) {\n return reply.code(404).send({\n ok: false,\n error: { message: `Unknown adapter: \"${adapterName}\"`, code: 'ADAPTER_NOT_FOUND' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 2. Check method is allowed\n if (!allowedMethods.has(methodName)) {\n return reply.code(403).send({\n ok: false,\n error: { message: `Method \"${methodName}\" not allowed on adapter \"${adapterName}\"`, code: 'METHOD_NOT_ALLOWED' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 3. Resolve adapter instance\n const adapter = resolveAdapter(adapterName);\n if (!adapter) {\n return reply.code(503).send({\n ok: false,\n error: { message: `Adapter \"${adapterName}\" not configured`, code: 'ADAPTER_UNAVAILABLE' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 4. Check method exists on adapter\n const method = (adapter as Record<string, unknown>)[methodName];\n if (typeof method !== 'function') {\n return reply.code(501).send({\n ok: false,\n error: { message: `Method \"${methodName}\" not implemented on adapter \"${adapterName}\"`, code: 'METHOD_NOT_IMPLEMENTED' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n // 5. Parse args\n const parsed = PlatformCallRequestSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({\n ok: false,\n error: { message: 'Invalid request body', code: 'VALIDATION_ERROR' },\n durationMs: 0,\n } satisfies PlatformCallResponse);\n }\n\n const { args } = parsed.data;\n\n logger.info('Platform API call', {\n adapter: adapterName,\n method: methodName,\n argCount: args.length,\n tenantId: auth.namespaceId,\n });\n\n // 6. Execute\n const startTime = Date.now();\n\n try {\n const result = method.apply(adapter, args);\n\n // Handle async results\n const resolved = result instanceof Promise ? await result : result;\n\n // 7. Detect streaming response (e.g., llm.stream)\n if (isAsyncIterable(resolved)) {\n reply.raw.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n reply.raw.flushHeaders();\n\n for await (const chunk of resolved) {\n if (!reply.raw.writableEnded) {\n const data = typeof chunk === 'string' ? chunk : JSON.stringify(chunk);\n reply.raw.write(`data: ${data}\\n\\n`);\n }\n }\n\n if (!reply.raw.writableEnded) {\n reply.raw.write('data: [DONE]\\n\\n');\n reply.raw.end();\n }\n\n return reply;\n }\n\n // 8. Regular response\n const durationMs = Date.now() - startTime;\n return reply.code(200).send({\n ok: true,\n result: resolved,\n durationMs,\n } satisfies PlatformCallResponse);\n } catch (err) {\n const durationMs = Date.now() - startTime;\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error('Platform API error', error, {\n adapter: adapterName,\n method: methodName,\n tenantId: auth.namespaceId,\n });\n return reply.code(502).send({\n ok: false,\n error: { message: error.message, code: 'ADAPTER_ERROR' },\n durationMs,\n } satisfies PlatformCallResponse);\n }\n },\n );\n}\n","/**\n * @module gateway-app/docs/routes\n * Aggregated OpenAPI documentation endpoints.\n *\n * GET /openapi-merged.json — merged spec from all upstream services\n * GET /docs-all — Swagger UI pointing at the merged spec\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport { mergeOpenAPISpecs } from '@kb-labs/core-registry';\nimport type { ICache, IServiceTransport } from '@kb-labs/core-platform';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\n\nconst MERGED_CACHE_KEY = '__gateway_merged_openapi';\nconst MERGED_CACHE_TTL = 30_000; // 30 second cache\n\nexport function registerAggregatedDocsRoutes(\n app: FastifyInstance,\n config: GatewayConfig,\n serviceTransport: IServiceTransport,\n cache?: ICache,\n): void {\n const upstreamServiceIds = Object.values(config.upstreams).map((u) => u.serviceId);\n\n // Merged OpenAPI spec from all upstreams\n app.get('/openapi-merged.json', async (_req, reply) => {\n // Try cache first\n if (cache) {\n try {\n const hit = await cache.get<Record<string, unknown>>(MERGED_CACHE_KEY);\n if (hit) {\n return reply.send(hit);\n }\n } catch { /* cache miss */ }\n }\n\n // Fetch all upstream specs in parallel via transport\n const results = await Promise.allSettled(\n upstreamServiceIds.map((serviceId) =>\n serviceTransport.call(serviceId, {\n path: '/openapi.json',\n signal: AbortSignal.timeout(3000),\n }).then((r) => r.payload),\n ),\n );\n\n const specs = results\n .filter((r): r is PromiseFulfilledResult<unknown> => r.status === 'fulfilled')\n .map((r) => r.value);\n\n const merged = mergeOpenAPISpecs(specs as Parameters<typeof mergeOpenAPISpecs>[0]);\n\n // Cache result\n if (cache) {\n try {\n await cache.set(MERGED_CACHE_KEY, merged as unknown as Record<string, unknown>, MERGED_CACHE_TTL);\n } catch { /* cache write failure is non-critical */ }\n }\n\n return reply.send(merged);\n });\n\n // Second Swagger UI pointing at merged spec\n // Registered last so /docs (gateway-native) is already bound at this point\n app.register(async function docsAll(scope) {\n const swaggerUi = await import('@fastify/swagger-ui');\n await scope.register(swaggerUi.default ?? swaggerUi, {\n routePrefix: '/docs-all',\n uiConfig: {\n url: '/openapi-merged.json',\n docExpansion: 'list',\n deepLinking: true,\n },\n });\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport type { ICache } from '@kb-labs/core-platform';\nimport type { HostDescriptor, HostRegistration, IHostStore } from '@kb-labs/gateway-contracts';\n\nexport interface HostRegisterResult {\n descriptor: HostDescriptor;\n machineToken: string;\n}\n\n/**\n * Host Registry — coordinates cache (hot) and store (cold) layers.\n *\n * - Cache: online/offline status, connections, heartbeat (transient)\n * - Store: host descriptors, tokens (durable, survives restarts)\n *\n * Write path: store.save() + cache.set()\n * Read path: cache.get() ?? store.get() → cache warm\n */\nconst DEFAULT_RECONNECT_GRACE_MS = 10_000;\n\nexport class HostRegistry {\n private readonly graceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly reconnectGraceMs: number;\n\n constructor(\n private readonly cache: ICache,\n private readonly store?: IHostStore,\n options?: { reconnectGraceMs?: number },\n ) {\n this.reconnectGraceMs = options?.reconnectGraceMs ?? DEFAULT_RECONNECT_GRACE_MS;\n }\n\n /**\n * Restore hosts from persistent store into cache on startup.\n * All restored hosts start as offline — live status comes from WS connections.\n *\n * Also resets any stale online/reconnecting hosts in cache to offline,\n * since no WebSocket connections survive a Gateway restart.\n */\n async restore(): Promise<number> {\n // 1. Reset stale hosts in cache (covers Redis cache surviving restarts)\n await this.resetStaleHosts();\n\n // 2. Restore from store if available\n if (!this.store) {return 0;}\n const hosts = await this.store.listAll();\n for (const host of hosts) {\n const offline = { ...host, status: 'offline' as const, connections: [] as string[] };\n const cacheKey = this.hostKey(host.namespaceId, host.hostId);\n await this.cache.set(cacheKey, offline);\n await this.store.save(offline);\n await this.addToIndex(host.namespaceId, host.hostId);\n }\n return hosts.length;\n }\n\n /**\n * Reset all hosts in cache to offline.\n * Called on startup — no WS connections exist yet, so nothing should be online.\n * Uses namespace index maintained in cache to discover all namespaces.\n */\n private async resetStaleHosts(): Promise<void> {\n const namespaces = await this.cache.get<string[]>('host:namespaces') ?? ['default'];\n for (const ns of namespaces) {\n const hostIds = await this.cache.get<string[]>(`host:index:${ns}`) ?? [];\n for (const hostId of hostIds) {\n const host = await this.cache.get<HostDescriptor>(this.hostKey(ns, hostId));\n if (host && (host.status === 'online' || host.status === 'reconnecting')) {\n await this.cache.set(this.hostKey(ns, hostId), {\n ...host, status: 'offline', connections: [],\n });\n }\n }\n }\n }\n\n async register(reg: HostRegistration): Promise<HostRegisterResult> {\n const hostId = `host_${randomUUID().replace(/-/g, '').slice(0, 24)}`;\n const machineToken = randomUUID();\n const now = Date.now();\n\n const descriptor: HostDescriptor = {\n hostId,\n name: reg.name,\n namespaceId: reg.namespaceId,\n capabilities: reg.capabilities,\n status: 'offline',\n lastSeen: now,\n connections: [],\n hostType: reg.hostType,\n createdAt: now,\n updatedAt: now,\n };\n\n // Persist to store (durable)\n if (this.store) {\n await this.store.save(descriptor);\n await this.store.saveToken(machineToken, hostId, reg.namespaceId);\n }\n\n // Write to cache (hot)\n await this.cache.set(this.hostKey(reg.namespaceId, hostId), descriptor);\n await this.cache.set(this.tokenKey(machineToken), { hostId, namespaceId: reg.namespaceId });\n await this.addToIndex(reg.namespaceId, hostId);\n\n return { descriptor, machineToken };\n }\n\n async setOnline(hostId: string, namespaceId: string, connectionId: string): Promise<void> {\n const host = await this.getFromCache(hostId, namespaceId);\n if (!host) {return;}\n\n // Cancel grace timer if reconnecting\n const graceKey = `${namespaceId}:${hostId}`;\n const graceTimer = this.graceTimers.get(graceKey);\n if (graceTimer) {\n clearTimeout(graceTimer);\n this.graceTimers.delete(graceKey);\n }\n\n const updated = {\n ...host,\n status: 'online' as const,\n lastSeen: Date.now(),\n connections: [connectionId],\n };\n await this.cache.set(this.hostKey(namespaceId, hostId), updated);\n if (this.store) {await this.store.save(updated);}\n }\n\n async setOffline(hostId: string, namespaceId: string, connectionId: string): Promise<void> {\n const host = await this.getFromCache(hostId, namespaceId);\n if (!host) {return;}\n const connections = host.connections.filter((c) => c !== connectionId);\n\n if (connections.length > 0) {\n // Other connections still active — stay online\n await this.cache.set(this.hostKey(namespaceId, hostId), {\n ...host, status: 'online', lastSeen: Date.now(), connections,\n });\n return;\n }\n\n // Last connection gone — enter grace period (reconnecting)\n const reconnecting = {\n ...host, status: 'reconnecting' as const, lastSeen: Date.now(), connections: [] as string[],\n };\n await this.cache.set(this.hostKey(namespaceId, hostId), reconnecting);\n if (this.store) {await this.store.save(reconnecting);}\n\n // Cancel any existing grace timer for this host\n const graceKey = `${namespaceId}:${hostId}`;\n const existing = this.graceTimers.get(graceKey);\n if (existing) {clearTimeout(existing);}\n\n // After grace period, mark truly offline\n this.graceTimers.set(graceKey, setTimeout(async () => {\n this.graceTimers.delete(graceKey);\n const current = await this.getFromCache(hostId, namespaceId);\n if (current?.status === 'reconnecting') {\n const offline = { ...current, status: 'offline' as const, lastSeen: Date.now() };\n await this.cache.set(this.hostKey(namespaceId, hostId), offline);\n if (this.store) {await this.store.save(offline);}\n }\n }, this.reconnectGraceMs));\n }\n\n async heartbeat(hostId: string, namespaceId: string): Promise<void> {\n const host = await this.getFromCache(hostId, namespaceId);\n if (!host) {return;}\n await this.cache.set(this.hostKey(namespaceId, hostId), { ...host, lastSeen: Date.now() });\n }\n\n async get(hostId: string, namespaceId: string): Promise<HostDescriptor | null> {\n // Try cache first (hot)\n const cached = await this.cache.get<HostDescriptor>(this.hostKey(namespaceId, hostId));\n if (cached) {return cached;}\n\n // Fall through to store (cold)\n if (!this.store) {return null;}\n const stored = await this.store.get(hostId, namespaceId);\n if (!stored) {return null;}\n\n // Warm cache\n await this.cache.set(this.hostKey(namespaceId, hostId), { ...stored, status: 'offline', connections: [] });\n await this.addToIndex(namespaceId, hostId);\n return { ...stored, status: 'offline', connections: [] };\n }\n\n async resolveToken(token: string): Promise<{ hostId: string; namespaceId: string } | null> {\n // Try cache first\n const cached = await this.cache.get<{ hostId: string; namespaceId: string }>(this.tokenKey(token));\n if (cached) {return cached;}\n\n // Fall through to store\n if (!this.store) {return null;}\n const stored = await this.store.resolveToken(token);\n if (!stored) {return null;}\n\n // Warm cache\n await this.cache.set(this.tokenKey(token), stored);\n return stored;\n }\n\n async list(namespaceId: string): Promise<HostDescriptor[]> {\n // Use store as authoritative source if available\n if (this.store) {\n const persisted = await this.store.list(namespaceId);\n // Enrich with live status from cache\n return Promise.all(\n persisted.map(async (host) => {\n const cached = await this.cache.get<HostDescriptor>(this.hostKey(namespaceId, host.hostId));\n return cached ?? { ...host, status: 'offline' as const, connections: [] };\n }),\n );\n }\n\n // Fallback: cache-only (no store)\n const indexKey = `host:index:${namespaceId}`;\n const hostIds = (await this.cache.get<string[]>(indexKey)) ?? [];\n const results = await Promise.all(\n hostIds.map((id) => this.cache.get<HostDescriptor>(this.hostKey(namespaceId, id))),\n );\n return results.filter((h): h is HostDescriptor => h !== null);\n }\n\n async deregister(hostId: string, namespaceId: string): Promise<boolean> {\n if (this.store) {\n const deleted = await this.store.delete(hostId, namespaceId);\n await this.cache.delete(this.hostKey(namespaceId, hostId));\n await this.removeFromIndex(namespaceId, hostId);\n return deleted;\n }\n // No persistent store — cache is the source of truth.\n const exists = !!(await this.cache.get<HostDescriptor>(this.hostKey(namespaceId, hostId)));\n await this.cache.delete(this.hostKey(namespaceId, hostId));\n await this.removeFromIndex(namespaceId, hostId);\n return exists;\n }\n\n async ensureRegistered(\n hostId: string,\n namespaceId: string,\n name: string,\n capabilities: HostDescriptor['capabilities'] = [],\n ): Promise<void> {\n const existing = await this.get(hostId, namespaceId);\n if (existing) {\n if (capabilities.length > 0 && JSON.stringify(existing.capabilities) !== JSON.stringify(capabilities)) {\n const updated = { ...existing, capabilities, updatedAt: Date.now() };\n if (this.store) {await this.store.save(updated);}\n await this.cache.set(this.hostKey(namespaceId, hostId), updated);\n }\n return;\n }\n\n const now = Date.now();\n const descriptor: HostDescriptor = {\n hostId,\n name,\n namespaceId,\n capabilities,\n status: 'offline',\n lastSeen: now,\n connections: [],\n createdAt: now,\n updatedAt: now,\n };\n\n if (this.store) {await this.store.save(descriptor);}\n await this.cache.set(this.hostKey(namespaceId, hostId), descriptor);\n await this.addToIndex(namespaceId, hostId);\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private hostKey(namespaceId: string, hostId: string): string {\n return `host:registry:${namespaceId}:${hostId}`;\n }\n\n private tokenKey(token: string): string {\n return `host:token:${token}`;\n }\n\n private async getFromCache(hostId: string, namespaceId: string): Promise<HostDescriptor | null> {\n return this.cache.get<HostDescriptor>(this.hostKey(namespaceId, hostId));\n }\n\n private async addToIndex(namespaceId: string, hostId: string): Promise<void> {\n const indexKey = `host:index:${namespaceId}`;\n const hostIds = (await this.cache.get<string[]>(indexKey)) ?? [];\n if (!hostIds.includes(hostId)) {\n await this.cache.set(indexKey, [...hostIds, hostId]);\n }\n // Track namespace for resetStaleHosts()\n const nsKey = 'host:namespaces';\n const namespaces = (await this.cache.get<string[]>(nsKey)) ?? [];\n if (!namespaces.includes(namespaceId)) {\n await this.cache.set(nsKey, [...namespaces, namespaceId]);\n }\n }\n\n private async removeFromIndex(namespaceId: string, hostId: string): Promise<void> {\n const indexKey = `host:index:${namespaceId}`;\n const hostIds = (await this.cache.get<string[]>(indexKey)) ?? [];\n await this.cache.set(indexKey, hostIds.filter((id) => id !== hostId));\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { WebSocket } from 'ws';\n\ninterface WsRequest {\n headers: { authorization?: string };\n url?: string;\n}\nimport { logDiagnosticEvent, type ICache, type ILogger } from '@kb-labs/core-platform';\nimport {\n HelloMessageSchema,\n AdapterCallMessageSchema,\n AdapterNameSchema,\n HostCapabilitySchema,\n SUPPORTED_PROTOCOL_VERSIONS,\n type HostCapability,\n type OutboundMessage,\n} from '@kb-labs/gateway-contracts';\nimport { AdaptiveBuffer } from '@kb-labs/gateway-core';\nimport { getClientByHostId, type JwtConfig } from '@kb-labs/gateway-auth';\nimport { HostRegistry } from './registry.js';\nimport { extractBearerToken, resolveToken } from '../auth/tokens.js';\nimport { globalDispatcher } from './dispatcher.js';\nimport { executionRegistry } from '../execute/execution-registry.js';\n\nconst HELLO_TIMEOUT_MS = 5_000;\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst HEARTBEAT_GRACE_MS = 10_000;\n\nfunction send(ws: WebSocket, msg: OutboundMessage): void {\n ws.send(JSON.stringify(msg));\n}\n\nexport function createWsHandler(\n cache: ICache,\n jwtConfig: JwtConfig,\n logger: ILogger,\n hostRegistry?: HostRegistry,\n) {\n const registry = hostRegistry ?? new HostRegistry(cache);\n const buffer = new AdaptiveBuffer(cache);\n\n return async function wsHandler(\n socket: WebSocket,\n request: WsRequest,\n ): Promise<void> {\n // 1. Auth — machine token required\n const token = extractBearerToken(request.headers.authorization);\n if (!token) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.auth',\n level: 'warn',\n reasonCode: 'websocket_auth_failed',\n message: 'Host WebSocket connection missing authorization token',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n });\n socket.close(1008, 'Missing Authorization header');\n return;\n }\n\n // 2. Start buffering hello BEFORE async auth to prevent race condition.\n // Client may send hello during await resolveToken — capture it immediately.\n let resolveHello!: (raw: Buffer) => void;\n let rejectHello!: (err: Error) => void;\n const helloRawPromise = new Promise<Buffer>((res, rej) => {\n resolveHello = res;\n rejectHello = rej;\n });\n // Consume rejection so early-return paths (e.g. token rejected before the\n // socket.once('close') listener fires) don't leak an unhandledRejection,\n // which BulkTransferHelper's process-wide uncaughtException handler would\n // escalate into process.exit(1), killing the gateway.\n helloRawPromise.catch(() => { /* awaited below or intentionally discarded */ });\n const helloTimeout = setTimeout(() => {\n socket.close(1008, 'Hello timeout');\n rejectHello(new Error('Hello timeout'));\n }, HELLO_TIMEOUT_MS);\n socket.once('message', (raw) => {\n clearTimeout(helloTimeout);\n resolveHello(raw as Buffer);\n });\n socket.once('close', () => {\n clearTimeout(helloTimeout);\n rejectHello(new Error('Socket closed before hello'));\n });\n\n const tokenEntry = await resolveToken(token, cache, jwtConfig);\n if (!tokenEntry || tokenEntry.type !== 'machine') {\n clearTimeout(helloTimeout);\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.auth',\n level: 'warn',\n reasonCode: 'websocket_auth_failed',\n message: 'Host WebSocket machine token rejected',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n });\n socket.close(1008, 'Invalid machine token');\n return;\n }\n\n const { userId: hostId, namespaceId } = tokenEntry;\n const connectionId = randomUUID();\n const sessionId = randomUUID();\n\n // 3. Process buffered hello (may already be resolved if client was fast)\n let protocolVersion: string | null = null;\n let helloCaps: string[] = [];\n\n const protocolVersions: readonly string[] = SUPPORTED_PROTOCOL_VERSIONS;\n\n try {\n const helloRaw = await helloRawPromise;\n const msg = HelloMessageSchema.parse(JSON.parse(helloRaw.toString()));\n\n if (!protocolVersions.includes(msg.protocolVersion)) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'websocket_protocol_unsupported',\n message: 'Host WebSocket protocol version is unsupported',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n protocolVersion: msg.protocolVersion,\n supportedVersions: [...SUPPORTED_PROTOCOL_VERSIONS],\n },\n });\n send(socket, {\n type: 'negotiate',\n supportedVersions: [...SUPPORTED_PROTOCOL_VERSIONS],\n });\n socket.close(1008, 'Unsupported protocol version');\n return;\n }\n\n protocolVersion = msg.protocolVersion;\n helloCaps = msg.capabilities ?? [];\n } catch (error) {\n const isTimeout = error instanceof Error && error.message === 'Hello timeout';\n if (isTimeout) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'websocket_hello_timeout',\n message: 'Host WebSocket hello timed out',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: { hostId, namespaceId },\n });\n } else if (!(error instanceof Error && error.message === 'Socket closed before hello')) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'websocket_handshake_invalid',\n message: 'Host WebSocket hello message is invalid',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: { hostId, namespaceId },\n });\n socket.close(1008, 'Invalid hello message');\n }\n return;\n }\n\n if (!protocolVersion) {return;}\n\n // 3. Resolve capabilities for dispatcher routing.\n //\n // Priority order:\n // 1. AuthStore clientRecord (JWT-registered via /auth/register) — authoritative\n // 2. HostRegistry descriptor (registered via /hosts/register) — authoritative\n // 3. Hello-message capabilities (static/dev tokens with no registry entry) — validated\n const clientRecord = await getClientByHostId(cache, hostId);\n const registryCaps: HostCapability[] = (clientRecord?.capabilities ?? []).flatMap((c) => {\n const r = HostCapabilitySchema.safeParse(c);\n return r.success ? [r.data] : [];\n });\n\n let capabilities: HostCapability[];\n if (clientRecord) {\n // JWT-registered host: use AuthStore capabilities only\n capabilities = registryCaps;\n } else {\n // Check HostRegistry for machine-token-registered hosts (/hosts/register)\n let existingDescriptor = null;\n try {\n existingDescriptor = await registry.get(hostId, namespaceId);\n } catch (err) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.handshake',\n level: 'warn',\n reasonCode: 'registry_lookup_failed',\n message: 'Failed to look up host descriptor from registry, falling back to hello capabilities',\n outcome: 'failed',\n error: err instanceof Error ? err : new Error(String(err)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: { hostId, namespaceId },\n });\n }\n if (existingDescriptor && existingDescriptor.capabilities.length > 0) {\n capabilities = existingDescriptor.capabilities.flatMap((c) => {\n const r = HostCapabilitySchema.safeParse(c);\n return r.success ? [r.data] : [];\n });\n } else {\n // Static/dev token with no registry entry: accept validated hello capabilities\n capabilities = helloCaps.flatMap((c) => {\n const r = HostCapabilitySchema.safeParse(c);\n return r.success ? [r.data] : [];\n });\n }\n }\n\n await registry.ensureRegistered(hostId, namespaceId, clientRecord?.name ?? hostId, capabilities);\n\n // 4. Set online + register in dispatcher (with capabilities for routing) + send connected\n await registry.setOnline(hostId, namespaceId, connectionId);\n globalDispatcher.registerConnection(hostId, namespaceId, socket, capabilities);\n\n send(socket, {\n type: 'connected',\n protocolVersion,\n hostId,\n sessionId,\n });\n\n // 4. Flush buffered calls\n const buffered = await buffer.flush(hostId);\n for (const call of buffered) {\n send(socket, {\n type: 'call',\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n args: call.args,\n trace: { traceId: call.requestId, spanId: randomUUID() },\n });\n }\n\n // 5. Heartbeat watchdog\n let lastHeartbeat = Date.now();\n const heartbeatWatchdog = setInterval(async () => {\n const elapsed = Date.now() - lastHeartbeat;\n if (elapsed > HEARTBEAT_INTERVAL_MS + HEARTBEAT_GRACE_MS) {\n // Mark as degraded (don't close — allow recovery)\n const host = await registry.get(hostId, namespaceId);\n if (host && host.status !== 'degraded') {\n await cache.set(`host:registry:${namespaceId}:${hostId}`, {\n ...host,\n status: 'degraded',\n });\n }\n }\n }, HEARTBEAT_INTERVAL_MS);\n\n // 6. Message handler\n socket.on('message', async (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as { type: string; requestId?: string };\n\n switch (msg.type) {\n case 'heartbeat':\n lastHeartbeat = Date.now();\n await registry.heartbeat(hostId, namespaceId);\n send(socket, { type: 'ack' });\n break;\n\n case 'chunk':\n case 'result':\n case 'error':\n globalDispatcher.handleInbound(msg as { type: string; requestId?: string; data?: unknown; error?: unknown });\n break;\n\n case 'adapter:call':\n void handleAdapterCall(msg, socket, hostId, namespaceId);\n break;\n }\n } catch (error) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.message',\n level: 'warn',\n reasonCode: 'websocket_message_invalid',\n message: 'Host WebSocket message is malformed',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n },\n });\n }\n });\n\n // 7. Disconnect cleanup\n socket.on('close', async () => {\n clearInterval(heartbeatWatchdog);\n globalDispatcher.removeConnection(hostId, namespaceId);\n\n // Cancel all executions dispatched to this host (CC2)\n const cancelled = executionRegistry.cancelByHost(hostId, 'disconnect');\n if (cancelled.length > 0) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.ws.disconnect',\n level: 'warn',\n reasonCode: 'execution_dispatch_failed',\n message: 'Host disconnected and active executions were cancelled',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n cancelledExecutions: cancelled.length,\n },\n });\n }\n\n await registry.setOffline(hostId, namespaceId, connectionId);\n });\n };\n\n /**\n * Handle adapter:call from Host — forward to REST API for platform service execution.\n * Flow: Host → WS adapter:call → Gateway → HTTP POST /api/v1/internal/adapter-call → REST API\n *\n * @see ADR-0051: Bidirectional Gateway Protocol\n */\n async function handleAdapterCall(\n msg: Record<string, unknown>,\n socket: WebSocket,\n hostId: string,\n namespaceId: string,\n ): Promise<void> {\n const requestId = msg['requestId'] as string;\n\n // 1. Validate message schema\n const parsed = AdapterCallMessageSchema.safeParse(msg);\n if (!parsed.success) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.adapter-call',\n level: 'warn',\n reasonCode: 'websocket_message_invalid',\n message: 'Host adapter call message is invalid',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n requestId,\n },\n });\n send(socket, {\n type: 'adapter:error',\n requestId: requestId ?? 'unknown',\n error: { code: 'INVALID_MESSAGE', message: parsed.error.message, retryable: false },\n });\n return;\n }\n\n const call = parsed.data;\n\n // 2. Validate adapter is in allowlist\n const adapterCheck = AdapterNameSchema.safeParse(call.adapter);\n if (!adapterCheck.success) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.adapter-call',\n level: 'warn',\n reasonCode: 'adapter_call_rejected',\n message: 'Host adapter call rejected by gateway allowlist',\n outcome: 'failed',\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n },\n });\n send(socket, {\n type: 'adapter:error',\n requestId: call.requestId,\n error: { code: 'ADAPTER_CALL_REJECTED', message: `Adapter not allowed: ${call.adapter}`, retryable: false },\n });\n return;\n }\n\n // 3. Forward to REST API\n const restApiUrl = process.env.REST_API_URL ?? 'http://localhost:5050';\n const internalSecret = process.env.GATEWAY_INTERNAL_SECRET ?? '';\n\n try {\n const response = await fetch(`${restApiUrl}/api/v1/internal/adapter-call`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-internal-secret': internalSecret,\n },\n body: JSON.stringify({\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n args: call.args,\n context: {\n ...call.context,\n namespaceId,\n hostId,\n },\n }),\n });\n\n const body = await response.json() as {\n ok: boolean;\n result?: unknown;\n error?: { code: string; message: string; retryable: boolean; details?: unknown };\n };\n\n if (body.ok) {\n send(socket, {\n type: 'adapter:response',\n requestId: call.requestId,\n result: body.result,\n });\n } else {\n send(socket, {\n type: 'adapter:error',\n requestId: call.requestId,\n error: body.error ?? { code: 'ADAPTER_ERROR', message: 'Unknown error', retryable: false },\n });\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.hosts.adapter-call',\n level: 'error',\n reasonCode: 'adapter_bridge_unavailable',\n message: 'Gateway could not reach REST adapter bridge',\n outcome: 'failed',\n error: err instanceof Error ? err : new Error(String(err)),\n serviceId: 'gateway',\n route: '/hosts/connect',\n evidence: {\n hostId,\n namespaceId,\n requestId: call.requestId,\n adapter: call.adapter,\n method: call.method,\n restApiUrl,\n },\n });\n send(socket, {\n type: 'adapter:error',\n requestId: call.requestId,\n error: { code: 'ADAPTER_CALL_TIMEOUT', message: `REST API unreachable: ${message}`, retryable: true },\n });\n }\n }\n}\n","/**\n * @module gateway-app/clients/ws-handler\n *\n * WebSocket handler for observer clients (CLI, Studio, IDE).\n * Endpoint: GET /clients/connect (requires Bearer JWT)\n *\n * Supports:\n * - client:subscribe — start receiving events for an executionId\n * - client:unsubscribe — stop receiving events\n * - client:cancel — cancel an execution (proxied to ExecutionRegistry)\n *\n * Auth: same Bearer JWT as HTTP endpoints (user or machine token, NOT host machine token).\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { WebSocket } from 'ws';\n\ninterface WsRequest {\n headers: { authorization?: string };\n url?: string;\n}\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { CancellationReason } from '@kb-labs/core-contracts';\nimport {\n ClientHelloSchema,\n ClientSubscribeSchema,\n ClientUnsubscribeSchema,\n ClientCancelSchema,\n CLIENT_PROTOCOL_VERSION,\n type ClientOutboundMessage,\n} from '@kb-labs/gateway-contracts';\nimport { type JwtConfig } from '@kb-labs/gateway-auth';\nimport { extractBearerToken, resolveToken } from '../auth/tokens.js';\nimport { executionRegistry } from '../execute/execution-registry.js';\nimport { subscriptionRegistry } from './subscription-registry.js';\n\nconst HELLO_TIMEOUT_MS = 5_000;\n\nfunction send(ws: WebSocket, msg: ClientOutboundMessage): void {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nexport function createClientWsHandler(cache: ICache, jwtConfig: JwtConfig, logger: ILogger) {\n return async function clientWsHandler(\n socket: WebSocket,\n request: WsRequest,\n ): Promise<void> {\n // 1. Auth — Bearer JWT required (user or machine token)\n const queryToken = new URL(request.url ?? '/', 'http://localhost').searchParams.get('access_token');\n const token = extractBearerToken(request.headers.authorization)\n ?? queryToken\n ?? null;\n\n if (!token) {\n socket.close(1008, 'Missing Authorization');\n return;\n }\n\n const authContext = await resolveToken(token, cache, jwtConfig);\n if (!authContext) {\n socket.close(1008, 'Invalid token');\n return;\n }\n\n const connectionId = randomUUID();\n\n // 2. Wait for client:hello (with timeout)\n let helloDone = false;\n\n await new Promise<void>((resolve, reject) => {\n const helloTimeout = setTimeout(() => {\n if (!helloDone) {\n helloDone = true;\n socket.close(1008, 'Hello timeout');\n reject(new Error('Hello timeout'));\n }\n }, HELLO_TIMEOUT_MS);\n\n socket.once('message', (raw) => {\n if (helloDone) { return; }\n helloDone = true;\n clearTimeout(helloTimeout);\n\n try {\n const msg = ClientHelloSchema.parse(JSON.parse(raw.toString()));\n void msg; // clientVersion logged below if needed\n resolve();\n } catch {\n socket.close(1008, 'Invalid hello message');\n reject(new Error('Invalid client:hello'));\n }\n });\n }).catch(() => {\n // socket already closed\n });\n\n if (!helloDone || socket.readyState !== socket.OPEN) { return; }\n\n // 3. Register connection\n subscriptionRegistry.registerSocket(connectionId, socket);\n\n send(socket, {\n type: 'client:connected',\n protocolVersion: CLIENT_PROTOCOL_VERSION,\n connectionId,\n });\n\n logger.debug('Client connected', { connectionId, namespaceId: authContext.namespaceId });\n\n // 4. Message handler\n socket.on('message', (raw) => {\n let parsed: { type: string };\n try {\n parsed = JSON.parse(raw.toString()) as { type: string };\n } catch {\n send(socket, {\n type: 'client:error',\n code: 'INVALID_MESSAGE',\n message: 'Malformed JSON',\n });\n return;\n }\n\n switch (parsed.type) {\n case 'client:subscribe': {\n const result = ClientSubscribeSchema.safeParse(parsed);\n if (!result.success) {\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: 'Invalid subscribe message' });\n return;\n }\n const { executionId } = result.data;\n\n // Verify execution exists and belongs to this namespace\n const execution = executionRegistry.get(executionId);\n if (!execution) {\n send(socket, { type: 'client:error', code: 'EXECUTION_NOT_FOUND', message: `Execution ${executionId} not found`, executionId });\n return;\n }\n if (execution.namespaceId !== authContext.namespaceId) {\n send(socket, { type: 'client:error', code: 'FORBIDDEN', message: 'Execution belongs to another namespace', executionId });\n return;\n }\n\n subscriptionRegistry.subscribe(connectionId, executionId);\n break;\n }\n\n case 'client:unsubscribe': {\n const result = ClientUnsubscribeSchema.safeParse(parsed);\n if (!result.success) {\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: 'Invalid unsubscribe message' });\n return;\n }\n subscriptionRegistry.unsubscribe(connectionId, result.data.executionId);\n break;\n }\n\n case 'client:cancel': {\n const result = ClientCancelSchema.safeParse(parsed);\n if (!result.success) {\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: 'Invalid cancel message' });\n return;\n }\n const { executionId, reason } = result.data;\n\n const execution = executionRegistry.get(executionId);\n if (!execution) {\n send(socket, { type: 'client:error', code: 'EXECUTION_NOT_FOUND', message: `Execution ${executionId} not found`, executionId });\n return;\n }\n if (execution.namespaceId !== authContext.namespaceId) {\n send(socket, { type: 'client:error', code: 'FORBIDDEN', message: 'Execution belongs to another namespace', executionId });\n return;\n }\n\n const cancelled = executionRegistry.cancel(executionId, (reason ?? 'user') as CancellationReason);\n if (!cancelled) {\n send(socket, { type: 'client:error', code: 'CANCEL_FAILED', message: 'Execution already completed or cancelled', executionId });\n }\n break;\n }\n\n default:\n send(socket, { type: 'client:error', code: 'INVALID_MESSAGE', message: `Unknown message type: ${String(parsed.type)}` });\n }\n });\n\n // 5. Disconnect cleanup\n socket.on('close', () => {\n subscriptionRegistry.removeConnection(connectionId);\n logger.debug('Client disconnected', { connectionId });\n });\n };\n}\n","/**\n * @module gateway-app/ws/pump\n *\n * Bidirectional frame relay between a downstream client WebSocket and an\n * upstream WebSocket (opened over a Unix domain socket via the `ws+unix://`\n * scheme). Used by the gateway's WS dialer to proxy WebSocket traffic to\n * socket-bound services, which @fastify/http-proxy cannot do.\n *\n * Guarantees:\n * - client frames sent before the upstream is OPEN are buffered, then flushed\n * in order on 'open' (no lost frames);\n * - binary/text framing is preserved in both directions;\n * - close (code/reason) and error propagate to the other side exactly once.\n */\nimport type { RawData, WebSocket } from 'ws';\nimport type { ILogger } from '@kb-labs/core-platform';\n\nconst OPEN = 1; // WebSocket.OPEN\n\n/**\n * Close codes that must NOT be echoed back via close(code): 1005 (no status)\n * and 1006 (abnormal) are reserved and throw if passed to close().\n */\nfunction normalizeCloseCode(code: number | undefined): number | undefined {\n if (code === undefined || code === 1005 || code === 1006) {\n return undefined;\n }\n return code;\n}\n\nfunction safeClose(ws: WebSocket, code?: number, reason?: Buffer | string): void {\n if (ws.readyState === OPEN || ws.readyState === 0 /* CONNECTING */) {\n try {\n if (code === undefined) {\n ws.close();\n } else if (reason === undefined) {\n ws.close(code);\n } else {\n ws.close(code, reason);\n }\n } catch {\n /* already closing/closed — ignore */\n }\n }\n}\n\nexport function pumpBidirectional(client: WebSocket, upstream: WebSocket, logger: ILogger): void {\n const pending: Array<{ data: RawData; binary: boolean }> = [];\n let upstreamOpen = false;\n let closed = false;\n\n const closeBoth = (code?: number, reason?: Buffer | string): void => {\n if (closed) {\n return;\n }\n closed = true;\n safeClose(client, code, reason);\n safeClose(upstream, code, reason);\n };\n\n // client → upstream (buffer until upstream is OPEN)\n client.on('message', (data: RawData, isBinary: boolean) => {\n if (upstreamOpen && upstream.readyState === OPEN) {\n upstream.send(data, { binary: isBinary });\n } else {\n pending.push({ data, binary: isBinary });\n }\n });\n\n upstream.on('open', () => {\n upstreamOpen = true;\n for (const frame of pending) {\n if (upstream.readyState === OPEN) {\n upstream.send(frame.data, { binary: frame.binary });\n }\n }\n pending.length = 0;\n });\n\n // upstream → client\n upstream.on('message', (data: RawData, isBinary: boolean) => {\n if (client.readyState === OPEN) {\n client.send(data, { binary: isBinary });\n }\n });\n\n upstream.on('close', (code: number, reason: Buffer) => {\n closeBoth(normalizeCloseCode(code), reason);\n });\n client.on('close', (code: number, reason: Buffer) => {\n closeBoth(normalizeCloseCode(code), reason);\n });\n\n upstream.on('error', (err: Error) => {\n logger.warn('Upstream WS error', { error: err.message });\n closeBoth(1011);\n });\n client.on('error', (err: Error) => {\n logger.warn('Client WS error', { error: err.message });\n closeBoth(1011);\n });\n}\n","/**\n * @module gateway-app/ws/gateway-ws\n *\n * Unified WebSocket upgrade handler for the gateway.\n *\n * Intercepts upgrade requests BEFORE @fastify/http-proxy:\n * - Gateway-own WS paths (/hosts/connect, /clients/connect) → raw ws handlers\n * - Everything else → delegated to @fastify/http-proxy for upstream WS proxy\n *\n * This eliminates the conflict between @fastify/websocket and @fastify/http-proxy\n * which both try to attach 'upgrade' listeners and call assignSocket().\n */\n\nimport type { Server, IncomingMessage } from 'node:http';\nimport type { Duplex } from 'node:stream';\nimport { WebSocket, WebSocketServer } from 'ws';\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { JwtConfig } from '@kb-labs/gateway-auth';\nimport { createWsHandler } from '../hosts/ws-handler.js';\nimport { createClientWsHandler } from '../clients/ws-handler.js';\nimport type { HostRegistry } from '../hosts/registry.js';\nimport { pumpBidirectional } from './pump.js';\n\nconst GATEWAY_WS_PATHS = new Set(['/hosts/connect', '/clients/connect']);\n\n/**\n * A WS-enabled upstream reachable over a Unix domain socket. @fastify/http-proxy\n * cannot proxy WS upgrades over unix sockets, so the gateway dials these itself.\n */\nexport interface SocketWsUpstream {\n /** Gateway-side path prefix, e.g. \"/api/v1\". */\n prefix: string;\n /** Upstream-side prefix replacement (http-proxy rewritePrefix semantics). */\n rewritePrefix: string;\n /** Absolute unix socket path the upstream service is bound to. */\n socketPath: string;\n}\n\n/** Headers forwarded to the upstream WS handshake (auth, correlation, subprotocol). */\nconst FORWARDED_WS_HEADERS = [\n 'authorization',\n 'cookie',\n 'x-request-id',\n 'x-trace-id',\n 'sec-websocket-protocol',\n] as const;\n\n/**\n * Pick the socket upstream that owns this pathname. Matches on a path boundary\n * (exact prefix or prefix followed by \"/\"), so \"/api/v1x\" does not match \"/api/v1\".\n */\nexport function pickSocketWsUpstream(\n pathname: string,\n upstreams: SocketWsUpstream[],\n): SocketWsUpstream | undefined {\n return upstreams.find(\n (u) => pathname === u.prefix || pathname.startsWith(`${u.prefix}/`),\n );\n}\n\n/**\n * Build the `ws+unix://<socket>:<path>` URL — the only form the `ws` client\n * accepts for a unix socket (the `socketPath` option is ignored by ws). The\n * gateway prefix is rewritten to the upstream prefix, query string preserved.\n */\nexport function buildUpstreamWsUrl(\n upstream: SocketWsUpstream,\n pathname: string,\n search: string,\n): string {\n const rewritten = upstream.rewritePrefix + pathname.slice(upstream.prefix.length);\n return `ws+unix://${upstream.socketPath}:${rewritten}${search}`;\n}\n\n/** Extract the subset of request headers forwarded to the upstream WS handshake. */\nexport function forwardWsHeaders(req: IncomingMessage): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of FORWARDED_WS_HEADERS) {\n const value = req.headers[name];\n if (typeof value === 'string') {\n out[name] = value;\n }\n }\n return out;\n}\n\n/**\n * Attach gateway-own WebSocket endpoints using raw `ws` package.\n *\n * Must be called AFTER `app.ready()` (so http-proxy has registered its\n * upgrade listener) but BEFORE `app.listen()`.\n *\n * Captures all existing 'upgrade' listeners, removes them, then installs\n * a single unified handler that dispatches:\n * - Gateway WS paths → raw ws handlers\n * - All other paths → delegated to captured listeners (http-proxy)\n */\nexport function attachGatewayWs(\n server: Server,\n cache: ICache,\n jwtConfig: JwtConfig,\n logger: ILogger,\n hostRegistry?: HostRegistry,\n socketWsUpstreams: SocketWsUpstream[] = [],\n): void {\n const wss = new WebSocketServer({ noServer: true });\n const hostsHandler = createWsHandler(cache, jwtConfig, logger, hostRegistry);\n const clientsHandler = createClientWsHandler(cache, jwtConfig, logger);\n\n // Capture @fastify/http-proxy's upgrade listener(s)\n const existingListeners = server.listeners('upgrade').slice() as Array<\n (req: IncomingMessage, socket: Duplex, head: Buffer) => void\n >;\n server.removeAllListeners('upgrade');\n\n server.on('upgrade', (req: IncomingMessage, socket: Duplex, head: Buffer) => {\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n\n if (GATEWAY_WS_PATHS.has(pathname)) {\n // Gateway-own WS — handle directly with raw ws\n wss.handleUpgrade(req, socket, head, (ws) => {\n const handlerPromise = pathname === '/hosts/connect'\n ? hostsHandler(ws, req)\n : clientsHandler(ws, req);\n handlerPromise.catch((err) => {\n logger.error('Unhandled WS handler error', err instanceof Error ? err : new Error(String(err)), { pathname });\n try { ws.close(1011, 'Internal error'); } catch { /* already closed */ }\n });\n });\n return;\n }\n\n // Socket-bound upstream WS: @fastify/http-proxy can't dial unix sockets for\n // upgrades, so the gateway opens the upstream WS itself (ws+unix://) and\n // relays frames. TCP upstreams fall through to http-proxy below.\n const socketUpstream = pickSocketWsUpstream(pathname, socketWsUpstreams);\n if (socketUpstream) {\n const { search } = new URL(req.url ?? '/', 'http://localhost');\n const upstreamUrl = buildUpstreamWsUrl(socketUpstream, pathname, search);\n wss.handleUpgrade(req, socket, head, (clientWs) => {\n const upstreamWs = new WebSocket(upstreamUrl, { headers: forwardWsHeaders(req) });\n pumpBidirectional(clientWs, upstreamWs, logger);\n });\n return;\n }\n\n // Delegate to @fastify/http-proxy for TCP upstream WS proxy\n for (const listener of existingListeners) {\n listener.call(server, req, socket, head);\n }\n });\n\n logger.info('Gateway WS endpoints attached', { paths: [...GATEWAY_WS_PATHS] });\n}\n","import type { FastifyInstance, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from 'fastify';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\nimport {\n OBSERVABILITY_CONTRACT_VERSION,\n OBSERVABILITY_SCHEMA,\n CANONICAL_OBSERVABILITY_METRICS,\n type ServiceHealthStatus,\n type ObservabilityCheck,\n} from '@kb-labs/core-contracts';\nimport type { ServiceObservabilityDescribe, ServiceObservabilityHealth } from '@kb-labs/core-contracts';\nimport {\n createServiceObservabilityDescribe,\n createServiceObservabilityHealth,\n OperationMetricsTracker,\n} from '@kb-labs/shared-http';\nimport { hostname } from 'node:os';\nimport { monitorEventLoopDelay, performance } from 'node:perf_hooks';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n kbMetricsStart?: number;\n }\n}\n\ntype RouteStats = {\n count: number;\n totalDurationMs: number;\n maxDurationMs: number;\n errorCount: number;\n};\n\nfunction normalizeRoute(route: string | undefined): string {\n if (!route) {\n return 'unknown';\n }\n return route\n .split('?')[0]!\n .replace(/\\/[0-9a-fA-F-]{6,}/g, '/:id');\n}\n\nfunction metricLine(name: string, value: number, labels?: Record<string, string>): string {\n if (!labels || Object.keys(labels).length === 0) {\n return `${name} ${value}`;\n }\n const pairs = Object.entries(labels).map(([key, labelValue]) => `${key}=\"${labelValue.replace(/\"/g, '\\\\\"')}\"`);\n return `${name}{${pairs.join(',')}} ${value}`;\n}\n\nexport class GatewayObservabilityCollector {\n private readonly instanceId = `${hostname()}:${process.pid}`;\n private readonly eventLoop = monitorEventLoopDelay({ resolution: 20 });\n private readonly routeStats = new Map<string, RouteStats>();\n private readonly operationMetrics = new OperationMetricsTracker();\n private readonly startedAt = Date.now();\n private readonly dependencies;\n private lastCpuUsage = process.cpuUsage();\n private lastCpuTime = Date.now();\n private intervalId: NodeJS.Timeout | null = null;\n private activeOperations = 0;\n private requestsTotal = 0;\n private errorsTotal = 0;\n private lastSnapshot = {\n cpuPercent: 0,\n rssBytes: process.memoryUsage().rss,\n heapUsedBytes: process.memoryUsage().heapUsed,\n eventLoopLagMs: 0,\n };\n\n constructor(private readonly config: GatewayConfig) {\n this.dependencies = Object.keys(this.config.upstreams).map((serviceId) => ({\n serviceId,\n required: false,\n description: 'Gateway upstream',\n }));\n }\n\n register(server: unknown): void {\n const hookServer = server as FastifyInstance;\n this.eventLoop.enable();\n this.intervalId = setInterval(() => this.captureRuntimeSnapshot(), 10_000);\n this.captureRuntimeSnapshot();\n\n hookServer.addHook('onRequest', (request: FastifyRequest, _reply: FastifyReply, done: HookHandlerDoneFunction) => {\n request.kbMetricsStart = performance.now();\n this.activeOperations += 1;\n done();\n });\n\n hookServer.addHook('onResponse', (request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) => {\n const started = request.kbMetricsStart ?? performance.now();\n const durationMs = Math.max(performance.now() - started, 0);\n const route = `${request.method.toUpperCase()} ${normalizeRoute(request.routeOptions?.url ?? request.url)}`;\n const stats = this.routeStats.get(route) ?? {\n count: 0,\n totalDurationMs: 0,\n maxDurationMs: 0,\n errorCount: 0,\n };\n\n stats.count += 1;\n stats.totalDurationMs += durationMs;\n stats.maxDurationMs = Math.max(stats.maxDurationMs, durationMs);\n if (reply.statusCode >= 400) {\n stats.errorCount += 1;\n this.errorsTotal += 1;\n }\n this.routeStats.set(route, stats);\n this.requestsTotal += 1;\n this.activeOperations = Math.max(0, this.activeOperations - 1);\n done();\n });\n\n hookServer.addHook('onClose', (_instance: unknown, done: HookHandlerDoneFunction) => {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n this.eventLoop.disable();\n done();\n });\n }\n\n buildDescribe(): ServiceObservabilityDescribe {\n return createServiceObservabilityDescribe({\n schema: OBSERVABILITY_SCHEMA,\n contractVersion: OBSERVABILITY_CONTRACT_VERSION,\n serviceId: 'gateway',\n instanceId: this.instanceId,\n serviceType: 'gateway',\n version: '1.0.0',\n environment: process.env.NODE_ENV ?? 'development',\n startedAt: new Date(this.startedAt).toISOString(),\n dependencies: this.dependencies,\n metricsEndpoint: '/metrics',\n healthEndpoint: '/observability/health',\n logsSource: 'gateway',\n capabilities: ['httpMetrics', 'eventLoopMetrics', 'operationMetrics', 'logCorrelation'],\n metricFamilies: [...CANONICAL_OBSERVABILITY_METRICS],\n });\n }\n\n buildHealth(input: {\n status: ServiceHealthStatus;\n adapterChecks: Array<{ id: string; available: boolean; latencyMs?: number }>;\n upstreamChecks: Array<{ id: string; status: string; latencyMs?: number }>;\n }): ServiceObservabilityHealth {\n const checks: ObservabilityCheck[] = [\n ...input.adapterChecks.map((entry): ObservabilityCheck => ({\n id: `adapter:${entry.id}`,\n status: entry.available ? 'ok' : 'warn',\n latencyMs: entry.latencyMs,\n message: entry.available ? 'Adapter available' : 'Adapter unavailable',\n })),\n ...input.upstreamChecks.map((entry): ObservabilityCheck => ({\n id: `upstream:${entry.id}`,\n status: entry.status === 'up' ? 'ok' : 'warn',\n latencyMs: entry.latencyMs,\n message: entry.status === 'up' ? 'Upstream healthy' : 'Upstream unavailable',\n })),\n ];\n\n const topOperations = mergeTopOperations(\n Array.from(this.routeStats.entries())\n .sort((a, b) => b[1].count - a[1].count || b[1].maxDurationMs - a[1].maxDurationMs)\n .slice(0, 5)\n .map(([operation, stats]) => ({\n operation: `http.${operation}`,\n count: stats.count,\n avgDurationMs: stats.count > 0 ? stats.totalDurationMs / stats.count : 0,\n maxDurationMs: stats.maxDurationMs,\n errorCount: stats.errorCount,\n })),\n this.operationMetrics.getTopOperations(),\n );\n\n return createServiceObservabilityHealth({\n schema: OBSERVABILITY_SCHEMA,\n contractVersion: OBSERVABILITY_CONTRACT_VERSION,\n serviceId: 'gateway',\n instanceId: this.instanceId,\n observedAt: new Date().toISOString(),\n status: input.status,\n uptimeSec: Math.floor((Date.now() - this.startedAt) / 1000),\n metricsEndpoint: '/metrics',\n logsSource: 'gateway',\n capabilities: ['httpMetrics', 'eventLoopMetrics', 'operationMetrics', 'logCorrelation'],\n checks,\n snapshot: {\n cpuPercent: this.lastSnapshot.cpuPercent,\n rssBytes: this.lastSnapshot.rssBytes,\n heapUsedBytes: this.lastSnapshot.heapUsedBytes,\n eventLoopLagMs: this.lastSnapshot.eventLoopLagMs,\n activeOperations: this.activeOperations,\n },\n topOperations,\n state: input.status === 'healthy' ? 'active' : input.status === 'degraded' ? 'partial_observability' : 'insufficient_data',\n meta: {\n requestsTotal: this.requestsTotal,\n errorsTotal: this.errorsTotal,\n },\n });\n }\n\n async renderPrometheusMetrics(healthStatus: ServiceHealthStatus): Promise<string> {\n this.captureRuntimeSnapshot();\n\n const lines = [\n '# HELP process_cpu_percent Current process CPU usage percentage',\n '# TYPE process_cpu_percent gauge',\n metricLine('process_cpu_percent', this.lastSnapshot.cpuPercent),\n '# HELP process_rss_bytes Current process resident set size in bytes',\n '# TYPE process_rss_bytes gauge',\n metricLine('process_rss_bytes', this.lastSnapshot.rssBytes),\n '# HELP process_heap_used_bytes Current process heap used in bytes',\n '# TYPE process_heap_used_bytes gauge',\n metricLine('process_heap_used_bytes', this.lastSnapshot.heapUsedBytes),\n '# HELP process_event_loop_lag_ms Current event loop lag in milliseconds',\n '# TYPE process_event_loop_lag_ms gauge',\n metricLine('process_event_loop_lag_ms', this.lastSnapshot.eventLoopLagMs),\n '# HELP service_health_status Service health status (2=healthy, 1=degraded, 0=unhealthy)',\n '# TYPE service_health_status gauge',\n metricLine('service_health_status', healthStatus === 'healthy' ? 2 : healthStatus === 'degraded' ? 1 : 0),\n '# HELP service_restarts_total Service restart counter within current process lifetime',\n '# TYPE service_restarts_total gauge',\n metricLine('service_restarts_total', 0),\n '# HELP service_active_operations Current number of active operations',\n '# TYPE service_active_operations gauge',\n metricLine('service_active_operations', this.activeOperations),\n '# HELP http_requests_total Total number of HTTP requests',\n '# TYPE http_requests_total counter',\n '# HELP http_errors_total Total number of HTTP errors (4xx, 5xx)',\n '# TYPE http_errors_total counter',\n '# HELP http_request_duration_ms Total duration of HTTP requests grouped by route',\n '# TYPE http_request_duration_ms summary',\n '# HELP service_operation_total Total number of service operations',\n '# TYPE service_operation_total counter',\n '# HELP service_operation_duration_ms Total duration of service operations grouped by route',\n '# TYPE service_operation_duration_ms summary',\n ];\n\n for (const [route, stats] of this.routeStats.entries()) {\n const status = stats.errorCount > 0 ? 'error' : 'ok';\n lines.push(metricLine('http_requests_total', stats.count, { route }));\n lines.push(metricLine('http_errors_total', stats.errorCount, { route }));\n lines.push(metricLine('http_request_duration_ms', Number(stats.totalDurationMs.toFixed(2)), { route }));\n lines.push(metricLine('service_operation_total', stats.count, { operation: `http.${route}`, status }));\n lines.push(metricLine('service_operation_duration_ms', Number(stats.totalDurationMs.toFixed(2)), { operation: `http.${route}`, status }));\n }\n\n lines.push(...this.operationMetrics.getMetricLines());\n\n return `${lines.join('\\n')}\\n`;\n }\n\n recordOperation(operation: string, durationMs = 0, status: 'ok' | 'error' = 'ok'): void {\n this.operationMetrics.recordOperation(operation, durationMs, status);\n }\n\n observeOperation<T>(operation: string, work: () => T | Promise<T>): Promise<T> {\n return this.operationMetrics.observeOperation(operation, work);\n }\n\n private captureRuntimeSnapshot(): void {\n const currentUsage = process.cpuUsage(this.lastCpuUsage);\n const currentTime = Date.now();\n const deltaTime = Math.max(currentTime - this.lastCpuTime, 1);\n\n this.lastCpuUsage = process.cpuUsage();\n this.lastCpuTime = currentTime;\n\n const cpuTimeMs = (currentUsage.user + currentUsage.system) / 1000;\n const memory = process.memoryUsage();\n const eventLoopLagMs = Number((this.eventLoop.mean / 1_000_000).toFixed(2));\n\n this.lastSnapshot = {\n cpuPercent: Number(Math.min((cpuTimeMs / deltaTime) * 100, 100).toFixed(2)),\n rssBytes: memory.rss,\n heapUsedBytes: memory.heapUsed,\n eventLoopLagMs: Number.isFinite(eventLoopLagMs) ? eventLoopLagMs : 0,\n };\n\n this.eventLoop.reset();\n }\n}\n\nfunction mergeTopOperations(\n httpOperations: Array<{\n operation: string;\n count: number;\n avgDurationMs: number;\n maxDurationMs: number;\n errorCount: number;\n }>,\n domainOperations: Array<{\n operation: string;\n count?: number;\n avgDurationMs?: number;\n maxDurationMs?: number;\n errorCount?: number;\n }>,\n limit = 5,\n) {\n const merged = new Map<string, {\n operation: string;\n count?: number;\n avgDurationMs?: number;\n maxDurationMs?: number;\n errorCount?: number;\n }>();\n\n for (const item of [...httpOperations, ...domainOperations]) {\n const existing = merged.get(item.operation);\n if (!existing) {\n merged.set(item.operation, { ...item });\n continue;\n }\n\n const count = (existing.count ?? 0) + (item.count ?? 0);\n const totalDurationMs =\n (existing.avgDurationMs ?? 0) * (existing.count ?? 0) +\n (item.avgDurationMs ?? 0) * (item.count ?? 0);\n\n merged.set(item.operation, {\n operation: item.operation,\n count,\n avgDurationMs: count > 0 ? totalDurationMs / count : 0,\n maxDurationMs: Math.max(existing.maxDurationMs ?? 0, item.maxDurationMs ?? 0),\n errorCount: (existing.errorCount ?? 0) + (item.errorCount ?? 0),\n });\n }\n\n const ranked = Array.from(merged.values())\n .sort((a, b) => (b.count ?? 0) - (a.count ?? 0) || (b.maxDurationMs ?? 0) - (a.maxDurationMs ?? 0))\n const sliced = ranked.slice(0, limit);\n\n if (domainOperations.length === 0 || sliced.some((item) => !item.operation.startsWith('http.'))) {\n return sliced;\n }\n\n const firstDomainOperation = ranked.find((item) => !item.operation.startsWith('http.'));\n if (!firstDomainOperation) {\n return sliced;\n }\n\n return [...sliced.slice(0, Math.max(0, limit - 1)), firstDomainOperation];\n}\n","/**\n * @module @kb-labs/gateway-app/internal/routes\n * Service-to-service endpoints — NOT for external clients.\n * Auth: x-internal-secret header (GATEWAY_INTERNAL_SECRET env var).\n *\n * POST /internal/dispatch — invoke adapter method on a connected host\n * POST /internal/resolve-host — resolve hostId for namespace + strategy\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport { globalDispatcher } from '../hosts/dispatcher.js';\nimport type { HostRegistry } from '../hosts/registry.js';\nimport { getClientByHandle } from '@kb-labs/gateway-auth';\n\nexport function registerInternalRoutes(\n scope: FastifyInstance,\n internalSecret: string | undefined,\n hostRegistry: HostRegistry,\n cache?: import('@kb-labs/core-platform').ICache,\n): void {\n scope.post('/internal/dispatch', async (request, reply) => {\n const provided = request.headers['x-internal-secret'];\n if (!internalSecret || provided !== internalSecret) {\n return reply.code(403).send({ error: 'Forbidden' });\n }\n\n const body = request.body as {\n namespaceId?: string;\n hostId?: string;\n adapter?: string;\n method?: string;\n args?: unknown[];\n };\n\n if (!body.namespaceId || !body.adapter || !body.method) {\n return reply.code(400).send({ error: 'Missing required fields: namespaceId, adapter, method' });\n }\n\n const hostId = body.hostId\n ?? globalDispatcher.firstHostWithCapability(body.namespaceId, body.adapter)\n ?? globalDispatcher.firstHost(body.namespaceId);\n if (!hostId) {\n return reply.code(503).send({\n error: 'No host connected',\n namespaceId: body.namespaceId,\n });\n }\n\n try {\n const result = await globalDispatcher.call(\n body.namespaceId,\n hostId,\n body.adapter,\n body.method,\n body.args ?? [],\n );\n return { result };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes('Host not connected')) {\n return reply.code(503).send({ error: message });\n }\n return reply.code(502).send({ error: message });\n }\n });\n\n scope.get('/internal/auth/handle/:handle', async (request, reply) => {\n const provided = request.headers['x-internal-secret'];\n if (!internalSecret || provided !== internalSecret) {\n return reply.code(403).send({ error: 'Forbidden' });\n }\n if (!cache) {\n return reply.code(503).send({ error: 'Cache not available' });\n }\n const { handle } = request.params as { handle: string };\n const record = await getClientByHandle(cache, handle);\n if (!record) {\n return reply.code(404).send({ error: 'Handle not found' });\n }\n return { namespaceId: record.namespaceId, name: record.name, handle: record.handle };\n });\n\n scope.post('/internal/resolve-host', async (request, reply) => {\n const provided = request.headers['x-internal-secret'];\n if (!internalSecret || provided !== internalSecret) {\n return reply.code(403).send({ error: 'Forbidden' });\n }\n\n const body = request.body as {\n namespaceId?: string;\n target?: {\n hostId?: string;\n hostSelection?: string;\n repoFingerprint?: string;\n };\n };\n\n const namespaceId = body.namespaceId ?? 'default';\n const target = body.target ?? {};\n const strategy = (target.hostSelection ?? 'any-matching') as string;\n\n let hostId: string | undefined;\n\n if (strategy === 'pinned' && target.hostId) {\n const host = await hostRegistry.get(target.hostId, namespaceId);\n if (host?.status === 'online' || host?.status === 'reconnecting') {\n hostId = target.hostId;\n }\n } else {\n hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n }\n\n if (!hostId) {\n return reply.code(404).send({ error: 'No matching host found' });\n }\n\n return { hostId, strategy, namespaceId };\n });\n}\n","/**\n * @module pressure/resolve\n * Pure resource-id resolution for HTTP pressure control.\n *\n * Resolves an incoming request to one of three resource ids:\n * - `gateway:route:<slug>` — per-route override (highest priority)\n * - `gateway:service:<name>` — per-upstream fallback\n * - null — no pressure applies\n *\n * No broker access; no I/O. Safe to call in `onRequest` hook.\n */\n\nimport type {\n GatewayConfig,\n PressureConfig,\n PressureRouteOverride,\n} from '@kb-labs/gateway-contracts';\n\nexport type ResolvedPressure =\n | { resource: string; layer: 'route'; override: PressureRouteOverride }\n | { resource: string; layer: 'service'; upstream: string }\n | null;\n\n/**\n * Resolve a request to the resource id that should be checked against the broker.\n *\n * Order:\n * 1. perRoute overrides (first match wins by array order).\n * 2. perService — look up by upstream prefix match.\n * 3. null — pressure does not apply.\n *\n * Returns null when pressure is disabled, no upstream matches, and no route override fires.\n */\nexport function resolveResourceId(\n method: string,\n url: string,\n config: GatewayConfig,\n): ResolvedPressure {\n const pressure: PressureConfig | undefined = config.pressure;\n if (!pressure || pressure.enabled === false) {\n return null;\n }\n\n // Strip query string before prefix matching.\n const path = url.split('?')[0] ?? url;\n const upperMethod = method.toUpperCase();\n\n // 1. per-route overrides (first match wins)\n for (const override of pressure.perRoute) {\n if (!path.startsWith(override.pathPrefix)) {\n continue;\n }\n if (override.methods && override.methods.length > 0) {\n const allowed = override.methods.some(m => m.toUpperCase() === upperMethod);\n if (!allowed) { continue; }\n }\n return { resource: override.resource, layer: 'route', override };\n }\n\n // 2. per-service via upstream prefix match\n for (const [name, upstream] of Object.entries(config.upstreams)) {\n if (path.startsWith(upstream.prefix)) {\n const limits = pressure.perService[name];\n if (!limits) { return null; }\n return { resource: `gateway:service:${name}`, layer: 'service', upstream: name };\n }\n }\n\n return null;\n}\n","/**\n * @module pressure/register-limits\n * Boot-time registration of pressure limits with the platform ResourceBroker.\n *\n * Idempotent: safe to call more than once (relies on `IResourceBroker.registerLimit`\n * being a `Map.set` overwrite — see ADR-0056).\n */\n\nimport type { IResourceBroker } from '@kb-labs/core-resource-broker';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport type { PressureConfig } from '@kb-labs/gateway-contracts';\n\nexport interface RegisterPressureLimitsResult {\n perServiceRegistered: number;\n perRouteRegistered: number;\n perTenantEnabled: boolean;\n}\n\nexport function registerPressureLimits(\n broker: IResourceBroker,\n config: PressureConfig | undefined,\n logger: ILogger,\n): RegisterPressureLimitsResult {\n if (!config || config.enabled === false) {\n return { perServiceRegistered: 0, perRouteRegistered: 0, perTenantEnabled: false };\n }\n\n let perServiceRegistered = 0;\n for (const [name, limits] of Object.entries(config.perService)) {\n broker.registerLimit(`gateway:service:${name}`, limits);\n perServiceRegistered++;\n }\n\n let perRouteRegistered = 0;\n for (const override of config.perRoute) {\n broker.registerLimit(override.resource, override.limits);\n perRouteRegistered++;\n }\n\n const perTenantEnabled = config.perTenant?.enabled === true;\n\n logger.info('pressure.boot', {\n event: 'pressure.boot',\n perService: perServiceRegistered,\n perRoute: perRouteRegistered,\n perTenant: perTenantEnabled,\n });\n\n return { perServiceRegistered, perRouteRegistered, perTenantEnabled };\n}\n","/**\n * @module pressure/hooks\n * Fastify hooks that apply pressure-control via `IResourceBroker.tryAcquire`.\n *\n * Three hooks:\n * - `onRequest` (per-service / per-route) — runs before auth, returns 429 if denied.\n * - `preHandler` (per-tenant) — runs after auth, keyed by AuthContext.namespaceId.\n * - `onResponse` — releases every slot reserved during the request.\n *\n * Aborted connections are caught via `request.raw.on('close', ...)`. Idempotency\n * of `release` (core ResourceBroker guarantee) makes double-fire safe.\n *\n * SSE / WebSocket requests are skipped (long-lived connections would hold a slot\n * past `onResponse`). Detection is via the `Upgrade` header.\n */\n\nimport type { FastifyRequest, FastifyReply, onRequestHookHandler, preHandlerHookHandler, onResponseHookHandler } from 'fastify';\nimport type { IResourceBroker, TryAcquireResult } from '@kb-labs/core-resource-broker';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\nimport { resolveResourceId } from './resolve.js';\n\nimport './types.js';\n\nexport interface PressureHooksDeps {\n broker: IResourceBroker;\n logger: ILogger;\n config: GatewayConfig;\n}\n\n/**\n * Returns true if the request is a WS/SSE upgrade and must be skipped.\n */\nfunction shouldSkip(request: FastifyRequest): boolean {\n const upgrade = request.headers.upgrade;\n if (typeof upgrade === 'string' && upgrade.length > 0) { return true; }\n return false;\n}\n\n/**\n * Initialize the per-request release array and arm an `onClose` safety net.\n * Called from the very first hook that may add a release handle.\n */\nfunction armRequest(request: FastifyRequest): Array<() => Promise<void>> {\n if (!request.pressureReleases) {\n request.pressureReleases = [];\n request.raw.on('close', () => {\n void releaseAll(request);\n });\n }\n return request.pressureReleases;\n}\n\nasync function releaseAll(request: FastifyRequest): Promise<void> {\n const releases = request.pressureReleases;\n if (!releases || releases.length === 0) { return; }\n // Snapshot + clear so a second pass (close after finish) is a no-op.\n const snapshot = releases.slice();\n request.pressureReleases = [];\n for (const release of snapshot) {\n try {\n await release();\n } catch {\n // Release errors are non-fatal; broker idempotency means slot may\n // already be free. Surface via logger if we ever need it, but stay\n // silent here to avoid amplifying noise on shutdown / aborted conns.\n }\n }\n}\n\nfunction retryAfterSeconds(waitTimeMs: number | undefined): number {\n if (!waitTimeMs || waitTimeMs <= 0) { return 1; }\n return Math.max(1, Math.ceil(waitTimeMs / 1000));\n}\n\n/**\n * Per-service / per-route hook. Runs as the first thing on every request.\n */\nexport function createPressureOnRequest(deps: PressureHooksDeps): onRequestHookHandler {\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (shouldSkip(request)) { return; }\n\n const resolved = resolveResourceId(request.method, request.url, deps.config);\n if (!resolved) { return; }\n\n const acquired: TryAcquireResult = await deps.broker.tryAcquire(resolved.resource);\n\n if (!acquired.allowed) {\n const retryAfter = retryAfterSeconds(acquired.waitTimeMs);\n deps.logger.warn('pressure.rejected', {\n event: 'pressure.rejected',\n resource: resolved.resource,\n layer: resolved.layer,\n method: request.method,\n url: request.url,\n waitTimeMs: acquired.waitTimeMs,\n });\n reply\n .code(429)\n .header('Retry-After', String(retryAfter))\n .send({\n error: 'rate_limited',\n resource: resolved.resource,\n waitTimeMs: acquired.waitTimeMs ?? null,\n });\n return reply;\n }\n\n armRequest(request).push(acquired.release);\n };\n}\n\n/**\n * Per-tenant hook. Runs after auth (inside the authenticated scope), so\n * `request.authContext.namespaceId` is available. Lazily registers a\n * limit-only resource per namespace on first encounter.\n *\n * Relies on `broker.registerLimit` idempotency (core ResourceBroker uses\n * `Map.set`) — a concurrent first-request race re-registers harmlessly.\n */\nexport function createPressurePreHandler(deps: PressureHooksDeps): preHandlerHookHandler {\n const registered = new Set<string>();\n const tenantCfg = deps.config.pressure?.perTenant;\n\n return async (request: FastifyRequest, reply: FastifyReply) => {\n if (!tenantCfg || tenantCfg.enabled !== true) { return; }\n if (shouldSkip(request)) { return; }\n\n const namespaceId = request.authContext?.namespaceId;\n if (!namespaceId) { return; }\n\n const resource = `gateway:tenant:${namespaceId}`;\n if (!registered.has(namespaceId)) {\n deps.broker.registerLimit(resource, tenantCfg.limits);\n registered.add(namespaceId);\n deps.logger.debug?.('pressure.tenant.registered', {\n event: 'pressure.tenant.registered',\n namespaceId,\n });\n }\n\n const acquired = await deps.broker.tryAcquire(resource);\n if (!acquired.allowed) {\n const retryAfter = retryAfterSeconds(acquired.waitTimeMs);\n deps.logger.warn('pressure.rejected', {\n event: 'pressure.rejected',\n resource,\n layer: 'tenant',\n method: request.method,\n url: request.url,\n namespaceId,\n waitTimeMs: acquired.waitTimeMs,\n });\n reply\n .code(429)\n .header('Retry-After', String(retryAfter))\n .send({\n error: 'rate_limited',\n resource,\n waitTimeMs: acquired.waitTimeMs ?? null,\n });\n return reply;\n }\n\n armRequest(request).push(acquired.release);\n };\n}\n\n/**\n * Response hook that releases every pressure slot reserved for this request.\n */\nexport function createPressureOnResponse(): onResponseHookHandler {\n return async (request: FastifyRequest) => {\n await releaseAll(request);\n };\n}\n","/**\n * @module webhook/secret-store\n *\n * Cache-backed store for webhook delivery secrets.\n *\n * Each provisioned webhook gets a `current` secret. On rotation, the old\n * secret moves to `previous` with a 24-hour grace window — so external\n * services that cached the old secret keep working briefly after rotation.\n *\n * Cache key format:\n * `webhook:secret:{ns}:{pluginId}:{event}`\n * `webhook:secret:{ns}:{pluginId}:{event}:{instanceId}` (multi: true)\n */\n\nimport type { ICache } from '@kb-labs/core-platform';\n\nexport interface WebhookSecretEntry {\n /** Active secret for new deliveries. */\n current: string;\n /** Previous secret, still valid until `previousExpiresAt`. */\n previous?: string;\n /** Unix timestamp (ms) after which `previous` is no longer valid. */\n previousExpiresAt?: number;\n}\n\n/** Grace window for previous secret after rotation: 24 hours. */\nconst PREVIOUS_SECRET_GRACE_MS = 86_400_000;\n\nfunction cacheKey(ns: string, pluginId: string, event: string, instanceId?: string): string {\n const base = `webhook:secret:${ns}:${pluginId}:${event}`;\n return instanceId ? `${base}:${instanceId}` : base;\n}\n\nexport class WebhookSecretStore {\n constructor(private readonly cache: ICache) {}\n\n async get(ns: string, pluginId: string, event: string, instanceId?: string): Promise<WebhookSecretEntry | null> {\n return this.cache.get<WebhookSecretEntry>(cacheKey(ns, pluginId, event, instanceId));\n }\n\n async set(ns: string, pluginId: string, event: string, entry: WebhookSecretEntry, instanceId?: string): Promise<void> {\n await this.cache.set(cacheKey(ns, pluginId, event, instanceId), entry);\n }\n\n async rotate(ns: string, pluginId: string, event: string, newSecret: string, instanceId?: string): Promise<WebhookSecretEntry> {\n const existing = await this.get(ns, pluginId, event, instanceId);\n const entry: WebhookSecretEntry = { current: newSecret };\n\n if (existing) {\n entry.previous = existing.current;\n entry.previousExpiresAt = Date.now() + PREVIOUS_SECRET_GRACE_MS;\n }\n\n await this.set(ns, pluginId, event, entry, instanceId);\n return entry;\n }\n\n async delete(ns: string, pluginId: string, event: string, instanceId?: string): Promise<void> {\n await this.cache.delete(cacheKey(ns, pluginId, event, instanceId));\n }\n}\n","/**\n * @module webhook/provision\n *\n * Provisions a webhook secret for a plugin+event combination.\n *\n * On first call: generates a new secret, stores it, calls onProvision handler.\n * On subsequent calls: rotates the secret (old → previous with 24h grace window).\n *\n * onProvision failures are logged but do not abort provisioning — the secret\n * is always persisted. Callers display the secret once; it cannot be recovered.\n */\n\nimport { randomBytes } from 'node:crypto';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport type { WebhookSecretStore } from './secret-store.js';\nimport type { WebhookManifestEntry } from './router.js';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface ProvisionInput {\n namespaceId: string;\n pluginId: string;\n event: string;\n instanceId?: string;\n baseUrl: string;\n}\n\nexport interface ProvisionResult {\n url: string;\n secret: string;\n rotated: boolean;\n onProvisionCalled: boolean;\n}\n\n/** Minimal execution backend — only `execute` is needed. */\nexport interface ProvisionBackend {\n execute(input: { handlerRef: string; pluginRoot: string; input: unknown; namespaceId?: string }): Promise<unknown>;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Provision (or rotate) a webhook secret for a plugin+event.\n *\n * @throws If the pluginId/event combination is not found in `manifests`.\n */\nexport async function provisionWebhook(\n input: ProvisionInput,\n secretStore: WebhookSecretStore,\n backend: ProvisionBackend,\n manifests: WebhookManifestEntry[],\n logger: ILogger,\n): Promise<ProvisionResult> {\n const { namespaceId, pluginId, event, instanceId, baseUrl } = input;\n\n // Find the declaration\n const manifestEntry = manifests.find((m) => m.pluginId === pluginId);\n const decl = manifestEntry?.manifest.webhooks?.handlers.find((h) => h.event === event);\n\n // manifestEntry check is for TypeScript narrowing — if decl is undefined,\n // manifestEntry is also undefined (decl depends on it via optional chaining).\n if (!manifestEntry || !decl) {\n throw new Error(`webhook '${pluginId}/${event}' not found`);\n }\n\n // Check whether a secret already exists (determines rotated flag)\n const existing = await secretStore.get(namespaceId, pluginId, event, instanceId);\n const rotated = existing !== null;\n\n // Generate a new secret: 32 random bytes as hex (64 chars)\n const newSecret = randomBytes(32).toString('hex');\n\n // Store via rotate (preserves previous with 24h grace) or set (first time)\n if (rotated) {\n await secretStore.rotate(namespaceId, pluginId, event, newSecret, instanceId);\n } else {\n await secretStore.set(namespaceId, pluginId, event, { current: newSecret }, instanceId);\n }\n\n // Build webhook URL — encode pluginId so scoped names (@org/pkg → %40org%2Fpkg)\n // produce a valid single-segment path param that Fastify routes correctly.\n const url = instanceId\n ? `${baseUrl}/webhooks/${encodeURIComponent(pluginId)}/${event}/${instanceId}`\n : `${baseUrl}/webhooks/${encodeURIComponent(pluginId)}/${event}`;\n\n // Call onProvision handler if declared\n let onProvisionCalled = false;\n if (decl.onProvision) {\n try {\n await backend.execute({\n handlerRef: decl.onProvision,\n pluginRoot: manifestEntry.pluginRoot,\n namespaceId,\n input: { instanceId, secret: newSecret, url },\n });\n onProvisionCalled = true;\n } catch (err) {\n logger.error(\n 'onProvision handler failed',\n err instanceof Error ? err : new Error(String(err)),\n { pluginId, event, instanceId },\n );\n }\n }\n\n return { url, secret: newSecret, rotated, onProvisionCalled };\n}\n","/**\n * @module webhook/admin-routes\n *\n * Admin HTTP routes for webhook management. Must be registered inside an\n * authenticated scope (request.authContext is expected to be set).\n *\n * Routes:\n * POST /api/v1/webhooks/provision — provision or rotate a secret\n * GET /api/v1/webhooks[?pluginId=] — list declared webhooks\n * DELETE /api/v1/webhooks/:pluginId/:event — revoke (single-instance)\n * DELETE /api/v1/webhooks/:pluginId/:event/:instanceId — revoke (multi-instance)\n *\n * namespaceId is taken from request.authContext — callers operate on their\n * own namespace only. No cross-namespace access.\n *\n * Rate limiting: each route acquires a token at the start and releases in\n * finally after all work completes — ensures the slot is held for the full\n * duration of the operation, not just the guard check.\n */\n\nimport type { FastifyInstance } from 'fastify';\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { IResourceBroker } from '@kb-labs/core-resource-broker';\nimport { WebhookSecretStore } from './secret-store.js';\nimport { provisionWebhook, type ProvisionBackend } from './provision.js';\nimport type { WebhookManifestEntry } from './router.js';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface RegisterWebhookAdminRoutesOptions {\n cache: ICache;\n logger: ILogger;\n backend: ProvisionBackend;\n manifests: WebhookManifestEntry[];\n baseUrl: string;\n /** Rate limiter — admin routes are always rate-limited. */\n broker: IResourceBroker;\n}\n\n// ── Rate limit resources ──────────────────────────────────────────────────────\n\nconst RL_PROVISION = 'webhook-admin:provision';\nconst RL_LIST = 'webhook-admin:list';\nconst RL_REVOKE = 'webhook-admin:revoke';\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport function registerWebhookAdminRoutes(\n scope: FastifyInstance,\n options: RegisterWebhookAdminRoutesOptions,\n): void {\n const { cache, logger, backend, manifests, baseUrl, broker } = options;\n const secretStore = new WebhookSecretStore(cache);\n\n // Register per-resource rate limits.\n // Admin operations are infrequent; conservative limits prevent abuse.\n broker.registerLimit(RL_PROVISION, { requestsPerMinute: 10 });\n broker.registerLimit(RL_LIST, { requestsPerMinute: 60 });\n broker.registerLimit(RL_REVOKE, { requestsPerMinute: 10 });\n\n // ── POST /api/v1/webhooks/provision ─────────────────────────────────────────\n\n scope.post('/api/v1/webhooks/provision', async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n // Acquire rate-limit token for the FULL duration of the handler so the\n // slot is not released until all work (provisionWebhook) completes.\n const acquired = await broker.tryAcquire(RL_PROVISION);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const body = request.body as Record<string, unknown> | undefined;\n const pluginId = typeof body?.pluginId === 'string' ? body.pluginId : undefined;\n const event = typeof body?.event === 'string' ? body.event : undefined;\n const instanceId = typeof body?.instanceId === 'string' ? body.instanceId : undefined;\n\n if (!pluginId) {\n return reply.code(400).send({ error: 'Bad Request', message: 'pluginId is required' });\n }\n if (!event) {\n return reply.code(400).send({ error: 'Bad Request', message: 'event is required' });\n }\n\n try {\n const result = await provisionWebhook(\n { namespaceId: auth.namespaceId, pluginId, event, instanceId, baseUrl },\n secretStore,\n backend,\n manifests,\n logger,\n );\n\n return reply.code(200).send({\n url: result.url,\n secret: result.secret,\n rotated: result.rotated,\n });\n } catch (err) {\n if (err instanceof Error && err.message.includes('not found')) {\n return reply.code(404).send({ error: 'Not Found', message: err.message });\n }\n throw err;\n }\n } finally {\n await acquired.release();\n }\n });\n\n // ── GET /api/v1/webhooks ─────────────────────────────────────────────────────\n\n scope.get('/api/v1/webhooks', async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const acquired = await broker.tryAcquire(RL_LIST);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const query = request.query as Record<string, string | undefined>;\n const filterPluginId = query.pluginId;\n\n const webhooks: Array<{ pluginId: string; event: string; multi: boolean; provisioned: boolean }> = [];\n\n for (const entry of manifests) {\n if (filterPluginId && entry.pluginId !== filterPluginId) { continue; }\n if (!entry.manifest.webhooks?.handlers) { continue; }\n\n for (const decl of entry.manifest.webhooks.handlers) {\n // For multi webhooks the provisioned check is per-instanceId; we show false\n // at the list level since there is no shared base entry.\n const secretEntry = decl.multi\n ? null\n : await secretStore.get(auth.namespaceId, entry.pluginId, decl.event);\n\n webhooks.push({\n pluginId: entry.pluginId,\n event: decl.event,\n multi: decl.multi === true,\n provisioned: secretEntry !== null,\n });\n }\n }\n\n return reply.code(200).send({ webhooks });\n } finally {\n await acquired.release();\n }\n });\n\n // ── DELETE /api/v1/webhooks/:pluginId/:event ──────────────────────────────────\n\n scope.delete<{ Params: { pluginId: string; event: string } }>(\n '/api/v1/webhooks/:pluginId/:event',\n async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const acquired = await broker.tryAcquire(RL_REVOKE);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const { pluginId, event } = request.params;\n await secretStore.delete(auth.namespaceId, pluginId, event);\n return reply.code(204).send();\n } finally {\n await acquired.release();\n }\n },\n );\n\n // ── DELETE /api/v1/webhooks/:pluginId/:event/:instanceId ──────────────────────\n\n scope.delete<{ Params: { pluginId: string; event: string; instanceId: string } }>(\n '/api/v1/webhooks/:pluginId/:event/:instanceId',\n async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n\n const acquired = await broker.tryAcquire(RL_REVOKE);\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({ error: 'Too Many Requests' });\n }\n\n const { pluginId, event, instanceId } = request.params;\n await secretStore.delete(auth.namespaceId, pluginId, event, instanceId);\n return reply.code(204).send();\n } finally {\n await acquired.release();\n }\n },\n );\n}\n","/**\n * @module webhook/idempotency-store\n *\n * Deduplication store for webhook deliveries.\n *\n * Uses `cache.setIfNotExists` for atomic check-and-mark — safe under\n * concurrent deliveries of the same event (e.g. retry storms from GitHub).\n *\n * Key format: `webhook:idempotency:{namespaceId}:{pluginId}:{event}:{deliveryKey}`\n * TTL: 7 days — covers typical webhook retry windows.\n */\n\nimport type { ICache } from '@kb-labs/core-platform';\n\nconst IDEMPOTENCY_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport class WebhookIdempotencyStore {\n constructor(private readonly cache: ICache) {}\n\n /**\n * Check if this delivery has already been processed, and mark it atomically.\n * Keys are scoped by namespaceId to prevent cross-tenant pollution.\n *\n * @returns `true` if duplicate (already processed), `false` if first time\n */\n async checkAndMark(namespaceId: string, pluginId: string, event: string, key: string): Promise<boolean> {\n const cacheKey = `webhook:idempotency:${namespaceId}:${pluginId}:${event}:${key}`;\n const isNew = await this.cache.setIfNotExists(cacheKey, 1, IDEMPOTENCY_TTL_MS);\n return !isNew; // true = duplicate\n }\n}\n","/**\n * @module webhook/auth\n *\n * Webhook delivery authentication — three strategies:\n *\n * - `secret`: static header comparison (`timingSafeEqual`)\n * - `hmac`: HMAC-SHA256 over raw body (`timingSafeEqual`)\n * - `custom`: calls a plugin validator handler via `backend.execute`\n *\n * All strategies support a previous-secret grace window for zero-downtime\n * rotation: if the current secret doesn't match, fall back to `previous`\n * provided it hasn't expired.\n *\n * Never throws — returns `{ valid: false, reason }` on any error so the\n * caller always gets a structured result to act on.\n */\n\nimport { createHmac, timingSafeEqual, randomBytes } from 'node:crypto';\nimport type { WebhookAuthConfig } from '@kb-labs/plugin-contracts';\nimport type { WebhookSecretEntry, WebhookSecretStore } from './secret-store.js';\n\nexport type WebhookAuthResult = { valid: true } | { valid: false; reason: string };\n\nexport interface WebhookAuthRequest {\n headers: Record<string, string | string[] | undefined>;\n rawBody: Buffer;\n namespaceId: string;\n pluginId: string;\n event: string;\n instanceId?: string;\n}\n\n/** Minimal interface for execution backend — only `execute` is needed here. */\ninterface ExecutionBackend {\n execute(input: { handlerRef: string; pluginRoot: string; input: unknown }): Promise<unknown>;\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/** Extract a single header value (case-insensitive). */\nfunction getHeader(headers: Record<string, string | string[] | undefined>, name: string): string | undefined {\n const lower = name.toLowerCase();\n const value = headers[lower] ?? headers[name];\n return Array.isArray(value) ? value[0] : value;\n}\n\n/**\n * Constant-time string comparison.\n *\n * Uses HMAC over a random session key so both inputs are hashed to the same\n * fixed length (32 bytes) before comparison — eliminates length-based\n * timing side-channels that would otherwise occur when short-circuiting on\n * `a.length !== b.length`.\n */\nconst _SESSION_KEY = randomBytes(32);\n\nfunction safeEqual(a: string, b: string): boolean {\n const ha = createHmac('sha256', _SESSION_KEY).update(a).digest();\n const hb = createHmac('sha256', _SESSION_KEY).update(b).digest();\n return timingSafeEqual(ha, hb);\n}\n\nfunction isPreviousValid(entry: WebhookSecretEntry): boolean {\n return (\n entry.previous !== undefined &&\n entry.previousExpiresAt !== undefined &&\n entry.previousExpiresAt > Date.now()\n );\n}\n\n// ── Strategy implementations ──────────────────────────────────────────────────\n\nfunction verifySecret(\n header: string,\n headers: Record<string, string | string[] | undefined>,\n entry: WebhookSecretEntry,\n): boolean {\n const value = getHeader(headers, header);\n if (!value) {\n return false;\n }\n\n if (safeEqual(value, entry.current)) {\n return true;\n }\n\n if (isPreviousValid(entry) && safeEqual(value, entry.previous!)) {\n return true;\n }\n\n return false;\n}\n\nfunction computeHmac(body: Buffer, secret: string): string {\n return createHmac('sha256', secret).update(body).digest('hex');\n}\n\nfunction verifyHmac(\n header: string,\n prefix: string | undefined,\n rawBody: Buffer,\n headers: Record<string, string | string[] | undefined>,\n entry: WebhookSecretEntry,\n): boolean {\n const headerValue = getHeader(headers, header);\n if (!headerValue) {\n return false;\n }\n\n // Strip prefix if configured\n const receivedSig = prefix && headerValue.startsWith(prefix)\n ? headerValue.slice(prefix.length)\n : headerValue;\n\n const expectedCurrent = computeHmac(rawBody, entry.current);\n if (safeEqual(receivedSig, expectedCurrent)) {\n return true;\n }\n\n if (isPreviousValid(entry)) {\n const expectedPrevious = computeHmac(rawBody, entry.previous!);\n if (safeEqual(receivedSig, expectedPrevious)) {\n return true;\n }\n }\n\n return false;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport async function verifyWebhookAuth(\n authConfig: WebhookAuthConfig,\n req: WebhookAuthRequest,\n secretStore: WebhookSecretStore,\n backend?: ExecutionBackend,\n pluginRoot?: string,\n): Promise<WebhookAuthResult> {\n const entry = await secretStore.get(req.namespaceId, req.pluginId, req.event, req.instanceId);\n\n if (!entry) {\n return { valid: false, reason: 'not provisioned' };\n }\n\n switch (authConfig.type) {\n case 'secret': {\n const valid = verifySecret(authConfig.header, req.headers, entry);\n return valid ? { valid: true } : { valid: false, reason: 'invalid secret' };\n }\n\n case 'hmac': {\n const valid = verifyHmac(authConfig.header, authConfig.prefix, req.rawBody, req.headers, entry);\n return valid ? { valid: true } : { valid: false, reason: 'invalid hmac signature' };\n }\n\n case 'custom': {\n if (!backend || !pluginRoot) {\n return { valid: false, reason: 'custom validator requires backend and pluginRoot' };\n }\n try {\n // Send HMAC of the body (not the raw secret) so the validator can\n // verify without ever receiving the plaintext secret.\n const bodyHmac = createHmac('sha256', entry.current).update(req.rawBody).digest('hex');\n const result = await backend.execute({\n handlerRef: authConfig.validator,\n pluginRoot,\n input: {\n headers: req.headers,\n rawBody: req.rawBody.toString('base64'),\n bodyHmac,\n },\n }) as { valid: boolean };\n return result.valid ? { valid: true } : { valid: false, reason: 'custom validator rejected' };\n } catch {\n return { valid: false, reason: 'validator error' };\n }\n }\n }\n}\n","/**\n * @module webhook/router\n *\n * Registers Fastify routes for manifest-declared webhook handlers.\n *\n * Route patterns:\n * POST /webhooks/:pluginId/:event (single-instance)\n * POST /webhooks/:pluginId/:event/:instanceId (multi: true)\n *\n * Per-request pipeline:\n * 1. Lookup declaration → 404 if unknown pluginId/event\n * 2. x-kb-namespace header → 400 if missing\n * 3. Rate limit via IResourceBroker → 429 if denied\n * 4. Challenge response → 200 (before auth, intentional for Slack handshake)\n * 5. Idempotency dedup → 200 early if duplicate delivery\n * 6. Auth (secret / hmac / custom) → 401 on failure\n * 7. Dispatch via globalDispatcher → 200 sync / 202 async\n *\n * Security: missing auth on any declaration causes startup rejection.\n * Plugin code never runs in-process — always dispatched via globalDispatcher.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { Readable } from 'node:stream';\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport type { ManifestV3, WebhookHandlerDecl } from '@kb-labs/plugin-contracts';\nimport type { ICache, ILogger } from '@kb-labs/core-platform';\nimport type { IResourceBroker } from '@kb-labs/core-resource-broker';\nimport { globalDispatcher } from '../hosts/dispatcher.js';\nimport { WebhookSecretStore } from './secret-store.js';\nimport { WebhookIdempotencyStore } from './idempotency-store.js';\nimport { verifyWebhookAuth, type WebhookAuthRequest } from './auth.js';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface WebhookManifestEntry {\n pluginId: string;\n manifest: ManifestV3;\n pluginRoot: string;\n}\n\nexport interface RegisterWebhookRoutesOptions {\n cache: ICache;\n broker: IResourceBroker;\n logger: ILogger;\n manifests: WebhookManifestEntry[];\n baseUrl?: string;\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/** Extract a nested value by dot-separated path (e.g. 'delivery.id'). */\nfunction getByDotPath(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (!current || typeof current !== 'object') { return undefined; }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\n/** Entry in the per-plugin declaration lookup map. */\ninterface DeclEntry {\n pluginId: string;\n decl: WebhookHandlerDecl;\n pluginRoot: string;\n manifest: ManifestV3;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Register webhook routes from plugin manifests.\n *\n * @returns Number of webhook routes registered.\n * @throws If any declaration is missing an `auth` config.\n */\nexport async function registerWebhookRoutes(\n scope: FastifyInstance,\n options: RegisterWebhookRoutesOptions,\n): Promise<number> {\n const { cache, broker, logger, manifests } = options;\n\n const secretStore = new WebhookSecretStore(cache);\n const idempotencyStore = new WebhookIdempotencyStore(cache);\n\n // Build lookup maps, validate, register rate limits\n const declMap = new Map<string, DeclEntry>();\n let needsRawBody = false;\n\n for (const entry of manifests) {\n const { pluginId, manifest, pluginRoot } = entry;\n if (!manifest.webhooks?.handlers.length) { continue; }\n\n for (const decl of manifest.webhooks.handlers) {\n if (!decl.auth) {\n throw new Error(`webhook '${pluginId}/${decl.event}' has no auth config`);\n }\n\n const mapKey = `${pluginId}:${decl.event}:${decl.multi ? 'multi' : 'single'}`;\n declMap.set(mapKey, { pluginId, decl, pluginRoot, manifest });\n\n broker.registerLimit(`webhook:${pluginId}:${decl.event}`, {\n requestsPerMinute: decl.rateLimit?.requestsPerMinute ?? 60,\n });\n\n if (decl.auth.type === 'hmac' || decl.auth.type === 'custom') {\n needsRawBody = true;\n }\n }\n }\n\n if (declMap.size === 0) { return 0; }\n\n // Capture raw body for HMAC / custom auth verification.\n // NOTE: this scope must contain only webhook delivery routes — the preParsing\n // hook fires for every route registered here, buffering the body each time.\n if (needsRawBody) {\n scope.addHook('preParsing', async (_request, _reply, payload) => {\n const chunks: Buffer[] = [];\n for await (const chunk of payload) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as unknown as string));\n }\n const body = Buffer.concat(chunks);\n _request.rawBody = body;\n return Readable.from(body);\n });\n }\n\n // ── Single-instance handler ─────────────────────────────────────────────────\n // NOTE: pluginIds containing '/' (e.g. @scope/name) must be URL-encoded by\n // callers: '@scope%2Fname' → Fastify decodes back to '@scope/name' in params.\n\n scope.post<{ Params: { pluginId: string; event: string } }>(\n '/webhooks/:pluginId/:event',\n async (request, reply) => {\n const { pluginId, event } = request.params;\n const entry = declMap.get(`${pluginId}:${event}:single`);\n if (!entry) {\n return reply.code(404).send({ error: 'Webhook not found' });\n }\n\n return handleWebhook({ request, reply, entry, namespaceHeader: request.headers['x-kb-namespace'], instanceId: undefined, secretStore, idempotencyStore, broker, logger });\n },\n );\n\n // ── Multi-instance handler ──────────────────────────────────────────────────\n\n scope.post<{ Params: { pluginId: string; event: string; instanceId: string } }>(\n '/webhooks/:pluginId/:event/:instanceId',\n async (request, reply) => {\n const { pluginId, event, instanceId } = request.params;\n const entry = declMap.get(`${pluginId}:${event}:multi`);\n if (!entry) {\n return reply.code(404).send({ error: 'Webhook not found' });\n }\n\n return handleWebhook({ request, reply, entry, namespaceHeader: request.headers['x-kb-namespace'], instanceId, secretStore, idempotencyStore, broker, logger });\n },\n );\n\n return declMap.size;\n}\n\n// ── Per-request handler ───────────────────────────────────────────────────────\n\ninterface HandleWebhookArgs {\n request: FastifyRequest;\n reply: FastifyReply;\n entry: DeclEntry;\n namespaceHeader: string | string[] | undefined;\n instanceId: string | undefined;\n secretStore: WebhookSecretStore;\n idempotencyStore: WebhookIdempotencyStore;\n broker: IResourceBroker;\n logger: ILogger;\n}\n\nasync function handleWebhook({\n request,\n reply,\n entry,\n namespaceHeader,\n instanceId,\n secretStore,\n idempotencyStore,\n broker,\n logger,\n}: HandleWebhookArgs): Promise<unknown> {\n const { pluginId, decl, pluginRoot, manifest } = entry;\n\n // Step 1: Resolve namespace\n const namespaceId = Array.isArray(namespaceHeader) ? namespaceHeader[0] : namespaceHeader;\n if (!namespaceId) {\n return reply.code(400).send({ error: 'Missing required header: x-kb-namespace' });\n }\n\n // Step 2: Rate limit\n // Use the unconditional try/finally pattern: release() is a no-op when allowed=false,\n // so the finally block is safe regardless of whether the request was accepted.\n const rateResource = `webhook:${pluginId}:${decl.event}`;\n const acquired = await broker.tryAcquire(rateResource);\n\n try {\n if (!acquired.allowed) {\n const retryAfterSec = acquired.waitTimeMs ? Math.max(1, Math.ceil(acquired.waitTimeMs / 1000)) : 1;\n return reply.code(429).header('Retry-After', String(retryAfterSec)).send({\n error: 'Too Many Requests',\n retryAfterMs: acquired.waitTimeMs ?? null,\n });\n }\n\n // Step 3: Challenge (before auth — Slack-style handshake)\n if (decl.challenge && request.body) {\n const fieldValue = getByDotPath(request.body, decl.challenge.bodyPath);\n if (fieldValue === decl.challenge.value) {\n const replyValue = getByDotPath(request.body, decl.challenge.replyPath);\n // Use the last path segment as the JSON key so dot-paths like\n // 'data.token' reply with { token: value } not { 'data.token': value }.\n const replyKey = decl.challenge.replyPath.split('.').pop()!;\n return reply.code(200).send({ [replyKey]: replyValue });\n }\n }\n\n // Step 4: Auth\n // rawBody is set by the preParsing hook for hmac/custom auth types.\n // Fallback: re-serialize from parsed body for secret auth (no raw body needed).\n // Use empty Buffer for null/undefined body to avoid JSON.stringify artifacts\n // that would break HMAC verification (e.g. stringify(null) = \"null\").\n const rawBody: Buffer = request.rawBody\n ?? (request.body == null\n ? Buffer.alloc(0)\n : Buffer.from(typeof request.body === 'string' ? request.body : JSON.stringify(request.body)));\n\n const authReq: WebhookAuthRequest = {\n headers: request.headers as Record<string, string | string[] | undefined>,\n rawBody,\n namespaceId,\n pluginId,\n event: decl.event,\n instanceId,\n };\n\n const authBackend = decl.auth.type === 'custom'\n ? makeAuthBackend(namespaceId, pluginId)\n : undefined;\n\n const authResult = await verifyWebhookAuth(decl.auth, authReq, secretStore, authBackend, pluginRoot);\n if (!authResult.valid) {\n return reply.code(401).send({ error: 'Unauthorized', reason: authResult.reason });\n }\n\n // Step 5: Idempotency dedup — after auth to prevent unauthenticated callers\n // from poisoning keys and blocking legitimate deliveries (DoS vector).\n // External services that retry deliveries carry the same signature, so they\n // pass auth before hitting the dedup check.\n if (decl.idempotencyKey && request.body) {\n const deliveryKey = getByDotPath(request.body, decl.idempotencyKey);\n if (typeof deliveryKey === 'string') {\n const isDuplicate = await idempotencyStore.checkAndMark(namespaceId, pluginId, decl.event, deliveryKey);\n if (isDuplicate) {\n return reply.code(200).send({ status: 'duplicate' });\n }\n }\n }\n\n // Step 6: Build host context\n const webhookId = randomUUID();\n const hostContext = {\n host: 'webhook' as const,\n event: decl.event,\n source: request.ip,\n payload: request.body,\n namespaceId,\n webhookId,\n ...(instanceId !== undefined ? { instanceId } : {}),\n };\n\n // Step 7: Resolve execution host\n const hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n if (!hostId) {\n return reply.code(503).send({ error: 'No execution host connected' });\n }\n\n const dispatchArgs = [{\n pluginId,\n handlerRef: decl.handler,\n input: request.body,\n executionId: webhookId,\n requestId: webhookId,\n descriptor: {\n hostType: 'webhook' as const,\n hostContext,\n pluginId,\n pluginVersion: manifest.version,\n requestId: webhookId,\n permissions: decl.permissions ?? [],\n },\n }];\n\n // Step 8: Dispatch\n if (decl.async) {\n reply.code(202).send({ status: 'accepted', webhookId });\n void globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', dispatchArgs).catch((err: unknown) => {\n logger.error(\n 'Webhook async dispatch failed',\n err instanceof Error ? err : new Error(String(err)),\n { pluginId, event: decl.event, webhookId },\n );\n });\n return;\n }\n\n try {\n const result = await globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', dispatchArgs);\n return reply.code(200).send({ status: 'ok', webhookId, result });\n } catch (err) {\n logger.error(\n 'Webhook dispatch failed',\n err instanceof Error ? err : new Error(String(err)),\n { pluginId, event: decl.event, webhookId },\n );\n return reply.code(500).send({ error: 'Dispatch failed' });\n }\n } finally {\n await acquired.release();\n }\n}\n\n// ── Auth execution backend for 'custom' auth type ─────────────────────────────\n\nfunction makeAuthBackend(\n namespaceId: string,\n pluginId: string,\n): {\n execute(input: { handlerRef: string; pluginRoot: string; input: unknown }): Promise<unknown>;\n} {\n return {\n async execute({ handlerRef, pluginRoot, input }) {\n const hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n if (!hostId) { throw new Error('No execution host connected for custom auth'); }\n // Pass pluginId so the host-agent's LocalPluginResolver can find the plugin root,\n // and pluginRoot as an absolute path hint for environments that support it.\n return globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', [\n { pluginId, handlerRef, pluginRoot, input },\n ]);\n },\n };\n}\n","import Fastify from 'fastify';\nimport fastifyCookie from '@fastify/cookie';\nimport fastifyCors from '@fastify/cors';\nimport fastifyHttpProxy from '@fastify/http-proxy';\nimport { platform, getAdapterStatus } from '@kb-labs/core-runtime';\nimport {\n createCorrelatedLogger,\n createServiceReadyResponse,\n registerOpenAPI,\n} from '@kb-labs/shared-http';\nimport { logDiagnosticEvent, type ICache, type ILogger, type IServiceTransport } from '@kb-labs/core-platform';\nimport type { GatewayConfig } from '@kb-labs/gateway-contracts';\nimport { HostRegistrationSchema } from '@kb-labs/gateway-contracts';\nimport {\n AuthService,\n type JwtConfig,\n type UsersStore,\n type SessionsStore,\n type InvitesStore,\n type ProviderRegistry,\n type IPolicyDecisionPoint,\n type TenantResolver,\n type RateLimiter,\n type OAuthStateStore,\n} from '@kb-labs/gateway-auth';\nimport { createAuthMiddleware } from './auth/middleware.js';\nimport { registerAuthRoutes, type MachineAuthRoutesUserExt } from './auth/routes.js';\nimport { createUserAuthMiddleware } from './auth/user-auth-middleware.js';\nimport { registerUserAuthRoutes, createUserRefreshFn, type UserAuthServiceForRoutes } from './auth/user-routes.js';\nimport { registerExecuteRoutes } from './execute/routes.js';\nimport { registerLLMGatewayRoutes } from './llm/routes.js';\nimport { registerTelemetryRoutes } from './telemetry/routes.js';\nimport { registerPlatformRoutes } from './platform/routes.js';\nimport { registerAggregatedDocsRoutes } from './docs/routes.js';\nimport { HostRegistry } from './hosts/registry.js';\nimport { attachGatewayWs, type SocketWsUpstream } from './ws/gateway-ws.js';\nimport { GatewayObservabilityCollector } from './observability/collector.js';\nimport { randomUUID } from 'node:crypto';\nimport { registerInternalRoutes } from './internal/routes.js';\nimport {\n createPressureOnRequest,\n createPressurePreHandler,\n createPressureOnResponse,\n} from './pressure/index.js';\nimport { globalDispatcher } from './hosts/dispatcher.js';\nimport { registerWebhookAdminRoutes } from './webhook/admin-routes.js';\nimport { registerWebhookRoutes, type WebhookManifestEntry } from './webhook/router.js';\n\n/**\n * User-auth dependencies injected from bootstrap. All fields optional so\n * the server can start without a documentDatabase adapter (degraded mode).\n */\nexport interface UserAuthServerDeps {\n userAuthService: UserAuthServiceForRoutes;\n users: UsersStore;\n sessions: SessionsStore;\n invites: InvitesStore;\n providers: ProviderRegistry;\n pdp: IPolicyDecisionPoint;\n tenantResolver: TenantResolver;\n cookieSecure: boolean;\n accessTtlSec: number;\n refreshTtlSec: number;\n inviteTtlMs: number;\n rateLimiter?: RateLimiter;\n authRateLimit?: { loginPerIpPerMinute: number; loginPerEmailPerMinute: number };\n /** OAuth state store (KV-backed). When present, redirect/OAuth routes are registered. */\n oauthState?: OAuthStateStore;\n /** Per-IP callback rate-limit for the OAuth callback. */\n oauthCallbackPerIpPerMinute?: number;\n}\n\n/** Strip bearer tokens from query params before logging (prevents JWT leakage in access logs). */\nfunction redactQueryToken(url: string): string {\n return url.replace(/([?&]access_token=)[^&]*/gi, '$1[REDACTED]');\n}\n\nexport async function createServer(\n config: GatewayConfig,\n cache: ICache,\n logger: ILogger,\n jwtConfig: JwtConfig,\n registry: HostRegistry | undefined,\n serviceTransport: IServiceTransport,\n userAuth?: UserAuthServerDeps,\n webhookManifests?: WebhookManifestEntry[],\n) {\n const gatewayLogger = createCorrelatedLogger(logger, {\n serviceId: 'gateway',\n logsSource: 'gateway',\n layer: 'gateway',\n service: 'server',\n operation: 'gateway.http',\n });\n const app = Fastify({\n logger: false,\n // CD-10: gateway sits behind nginx; parse X-Forwarded-For for real client IPs.\n trustProxy: true,\n });\n\n // Cookie parsing — required by user-auth middleware and cookie-based sessions.\n await app.register(fastifyCookie);\n\n const isProduction = process.env.NODE_ENV === 'production';\n\n // OpenAPI / Swagger UI — must be registered before routes\n await registerOpenAPI(app, {\n title: 'KB Labs Gateway',\n description: 'Central API gateway — auth, LLM, telemetry, platform dispatch',\n version: '1.0.0',\n servers: [{ url: 'http://localhost:4000', description: 'Local dev' }],\n ui: !isProduction,\n });\n\n // CORS disabled at gateway level — browser clients (Studio) connect via same-origin or\n // have CORS handled at the reverse-proxy / CDN layer. Reflecting arbitrary origins\n // (origin: true) would allow any attacker site to make credentialed cross-origin requests.\n await app.register(fastifyCors, { origin: false });\n const observability = new GatewayObservabilityCollector(config);\n observability.register(app);\n\n // ── Pressure control (ADR-0056) ────────────────────────────────────\n // Registered BEFORE upstream proxies so 429 is returned before the request\n // is forwarded. No-op when `config.pressure` is absent or disabled.\n if (config.pressure && config.pressure.enabled !== false && platform.hasResourceBroker) {\n const deps = { broker: platform.resourceBroker, logger, config };\n app.addHook('onRequest', createPressureOnRequest(deps));\n app.addHook('onResponse', createPressureOnResponse());\n }\n\n app.addHook('onRequest', async (request, reply) => {\n const requestId = (request.headers['x-request-id'] as string | undefined) || request.id || randomUUID();\n const traceId = (request.headers['x-trace-id'] as string | undefined) || randomUUID();\n\n request.id = requestId;\n reply.header('X-Request-Id', requestId);\n reply.header('X-Trace-Id', traceId);\n\n const safeUrl = redactQueryToken(request.url);\n request.kbLogger = createCorrelatedLogger(logger, {\n serviceId: 'gateway',\n logsSource: 'gateway',\n layer: 'gateway',\n service: 'request',\n requestId,\n traceId,\n method: request.method,\n url: safeUrl,\n operation: 'http.request',\n });\n request.kbLogger.info(`→ ${request.method.toUpperCase()} ${safeUrl}`);\n });\n\n app.addHook('onResponse', async (request, reply) => {\n const requestLogger = request.kbLogger;\n if (!requestLogger) {\n return;\n }\n\n const safeUrl = redactQueryToken(request.url);\n requestLogger.info(`✓ ${request.method.toUpperCase()} ${safeUrl} ${reply.statusCode}`, {\n statusCode: reply.statusCode,\n });\n });\n\n // ── Auth (B-023 fix) ────────────────────────────────────────────────\n // Registered globally on `app`, BEFORE the proxy upstreams below, so it\n // actually covers proxied routes (/api/v1/*, /api/exec/*, etc.) and not\n // just the gateway's own /auth/* routes. A prior version scoped these\n // hooks inside the `gatewayRoutes` child plugin registered AFTER the\n // proxy loop — Fastify hook encapsulation meant they never ran for\n // proxied requests, and rest-api/workflow/marketplace do not enforce\n // auth themselves, so every proxied route was reachable with no token\n // at all (confirmed: garbage Bearer token still got 200 on\n // /api/v1/studio/registry). Mirrors the pressure-hook precedent above,\n // which already runs globally ahead of the proxy loop for the same reason.\n //\n // User-auth middleware runs FIRST (before machine Bearer check).\n // Validates kb_access cookie, cross-tenant guard, CD-1 status check.\n // No-op when no cookie is present — machine auth takes over.\n if (userAuth) {\n app.addHook(\n 'onRequest',\n createUserAuthMiddleware({\n users: userAuth.users,\n tenantResolver: userAuth.tenantResolver,\n jwtConfig,\n }),\n );\n }\n\n // Machine Bearer middleware — skips if userAuthContext already set by above.\n // When auth is disabled (solo/local), the middleware runs every request as\n // the local admin (B-023).\n app.addHook(\n 'onRequest',\n createAuthMiddleware(cache, jwtConfig, { authEnabled: config.auth?.enabled !== false }),\n );\n\n // ── Proxy upstreams ────────────────────────────────────────────────\n // Connection details (baseUrl, socketPath) come from IServiceTransport.\n // WS-enabled upstreams bound to a unix socket: @fastify/http-proxy can't dial\n // unix sockets for WS upgrades, so the gateway proxies those WS itself (see\n // attachGatewayWs). HTTP for the same prefix still goes through http-proxy.\n const socketWsUpstreams: SocketWsUpstream[] = [];\n\n for (const [name, upstream] of Object.entries(config.upstreams)) {\n const conn = serviceTransport.connectionInfo(upstream.serviceId);\n if (!conn) {\n throw new Error(\n `Gateway startup error: no transport config for upstream \"${name}\" (serviceId: \"${upstream.serviceId}\"). ` +\n `Configure @kb-labs/adapters-service-transport-http as adapterOptions.serviceTransport.services in kb.config.json.`,\n );\n }\n // A WS upstream on a unix socket is handled by the gateway's own dialer, not\n // by http-proxy's websocket support (which only works over TCP).\n const wsOverSocket = Boolean(upstream.websocket) && Boolean(conn.socketPath);\n if (wsOverSocket) {\n socketWsUpstreams.push({\n prefix: upstream.prefix,\n rewritePrefix: upstream.rewritePrefix ?? upstream.prefix,\n socketPath: conn.socketPath!,\n });\n }\n await app.register(fastifyHttpProxy, {\n upstream: conn.baseUrl,\n prefix: upstream.prefix,\n rewritePrefix: upstream.rewritePrefix ?? upstream.prefix,\n disableCache: true,\n // Disable http-proxy WS for socket upstreams — the gateway dialer owns it.\n websocket: wsOverSocket ? false : (upstream.websocket ?? false),\n undici: {\n // Restore 1-hour body timeout for SSE streams and large transfers.\n // undici defaults: headersTimeout=30s, bodyTimeout=300s — too short for streaming.\n bodyTimeout: 3_600_000,\n ...(conn.socketPath ? { socketPath: conn.socketPath } : {}),\n },\n });\n const connDesc = conn.socketPath ? `${conn.baseUrl} (unix:${conn.socketPath})` : conn.baseUrl;\n const wsDesc = upstream.websocket ? (wsOverSocket ? ', ws→unix' : ', ws') : '';\n gatewayLogger.info(`Upstream registered: ${name} → ${connDesc} (${upstream.prefix}${wsDesc})`);\n }\n\n // ── Gateway's own routes ────────────────────────────────────────────\n // Auth hooks now run globally (see above) and already cover these routes\n // via Fastify's hook inheritance (parent hooks apply to child-registered\n // routes), so they are not repeated here.\n await app.register(async function gatewayRoutes(scope) {\n // Per-tenant pressure (ADR-0056). Runs after auth so AuthContext is set.\n if (config.pressure?.perTenant?.enabled === true && platform.hasResourceBroker) {\n scope.addHook(\n 'preHandler',\n createPressurePreHandler({ broker: platform.resourceBroker, logger, config }),\n );\n }\n\n // Machine auth routes (/auth/register, /auth/token, /auth/refresh).\n // When userAuth is available, wire user cookie refresh into /auth/refresh.\n const authService = new AuthService(cache, jwtConfig);\n const userExt: MachineAuthRoutesUserExt | undefined = userAuth\n ? {\n userRefreshFn: createUserRefreshFn({\n userAuthService: userAuth.userAuthService,\n cookieOpts: { cookieSecure: userAuth.cookieSecure },\n }),\n pdp: userAuth.pdp,\n }\n : undefined;\n registerAuthRoutes(scope as unknown as Parameters<typeof registerAuthRoutes>[0], authService, userExt);\n\n // User-auth routes — all new endpoints + /auth/me.\n if (userAuth) {\n registerUserAuthRoutes(\n scope as unknown as Parameters<typeof registerUserAuthRoutes>[0],\n {\n userAuthService: userAuth.userAuthService,\n users: userAuth.users,\n sessions: userAuth.sessions,\n invites: userAuth.invites,\n providers: userAuth.providers,\n pdp: userAuth.pdp,\n tenantResolver: userAuth.tenantResolver,\n cookieOpts: { cookieSecure: userAuth.cookieSecure },\n accessTtlSec: userAuth.accessTtlSec,\n refreshTtlSec: userAuth.refreshTtlSec,\n inviteTtlMs: userAuth.inviteTtlMs,\n jwtConfig,\n rateLimiter: userAuth.rateLimiter,\n authRateLimit: userAuth.authRateLimit,\n oauthState: userAuth.oauthState,\n oauthCallbackPerIpPerMinute: userAuth.oauthCallbackPerIpPerMinute,\n },\n );\n }\n\n // Health (public) — comprehensive adapter + upstream health\n const HEALTH_CACHE_KEY = '__gateway_health';\n const HEALTH_CACHE_TTL = 15_000; // 15s cache to prevent health DDoS\n const startupTime = Date.now();\n\n const collectHealthSnapshot = async () => {\n const cached = await cache.get<Record<string, unknown>>(HEALTH_CACHE_KEY).catch(() => null);\n if (cached) {\n return cached;\n }\n\n const adapterNames = ['llm', 'cache', 'analytics', 'vectorStore', 'embeddings'] as const;\n const adapters: Record<string, { available: boolean; latencyMs?: number }> = {};\n\n for (const name of adapterNames) {\n await observability.observeOperation(`gateway.adapter.${name}`, async () => {\n const probeStart = Date.now();\n try {\n // Try direct property first (production runtime stores adapters as platform.llm etc.),\n // then fall back to getAdapter() for environments where only that API is available.\n type FlexPlatform = Record<string, unknown> & { getAdapter?: (n: string) => unknown };\n const pf = platform as unknown as FlexPlatform;\n const adapter = pf[name] ?? pf.getAdapter?.(name);\n adapters[name] = { available: !!adapter, latencyMs: Date.now() - probeStart };\n } catch {\n adapters[name] = { available: false, latencyMs: Date.now() - probeStart };\n }\n });\n }\n\n const upstreams: Record<string, { status: string; latencyMs?: number }> = {};\n for (const [name, upstream] of Object.entries(config.upstreams)) {\n await observability.observeOperation(`gateway.upstream.${name}.health`, async () => {\n const probeStart = Date.now();\n try {\n const res = await serviceTransport.call(upstream.serviceId, {\n path: '/health',\n signal: AbortSignal.timeout(2000),\n });\n const latencyMs = Date.now() - probeStart;\n upstreams[name] = { status: res.ok ? 'up' : 'down', latencyMs };\n if (!res.ok) {\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.upstream.health',\n level: 'warn',\n reasonCode: 'upstream_unavailable',\n message: 'Gateway upstream health probe failed',\n outcome: 'failed',\n serviceId: 'gateway',\n route: `${upstream.prefix}/health`,\n evidence: {\n upstreamId: name,\n serviceId: upstream.serviceId,\n statusCode: res.statusCode,\n latencyMs,\n },\n });\n }\n } catch (error) {\n const latencyMs = Date.now() - probeStart;\n upstreams[name] = { status: 'down', latencyMs };\n logDiagnosticEvent(logger, {\n domain: 'service',\n event: 'gateway.upstream.health',\n level: 'warn',\n reasonCode: 'upstream_unavailable',\n message: 'Gateway upstream health probe failed',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n route: `${upstream.prefix}/health`,\n evidence: {\n upstreamId: name,\n serviceId: upstream.serviceId,\n latencyMs,\n },\n });\n }\n });\n }\n\n const llmOk = adapters.llm?.available ?? false;\n const allOk = Object.values(adapters).every((a) => a.available);\n const snapshot = {\n status: llmOk ? (allOk ? 'healthy' : 'degraded') : 'unhealthy',\n version: '1.0',\n uptime: Math.floor((Date.now() - startupTime) / 1000),\n timestamp: new Date().toISOString(),\n adapters,\n upstreams,\n };\n\n await cache.set(HEALTH_CACHE_KEY, snapshot, HEALTH_CACHE_TTL).catch(() => {});\n return snapshot;\n };\n\n scope.get('/health', { schema: { tags: ['System'], summary: 'Gateway health check' } }, async () => {\n return collectHealthSnapshot();\n });\n\n scope.get('/health/adapters', {\n schema: {\n tags: ['System'],\n summary: 'Platform adapter status — mode (real | inmemory | noop) per slot',\n },\n }, async () => {\n return getAdapterStatus();\n });\n\n scope.get('/ready', { schema: { tags: ['System'], summary: 'Gateway readiness check' } }, async (_request, reply) => {\n const health = await collectHealthSnapshot();\n const upstreams = (health.upstreams as Record<string, { status?: string }> | undefined) ?? {};\n const missingRequiredUpstreams = ['rest']\n .filter((id) => (upstreams[id]?.status ?? 'down') !== 'up');\n const ready = missingRequiredUpstreams.length === 0;\n\n return reply.code(ready ? 200 : 503).send(createServiceReadyResponse({\n ready,\n status: ready ? 'ready' : 'degraded',\n reason: ready ? 'ready' : `upstream_unavailable:${missingRequiredUpstreams.join(',')}`,\n components: {\n gatewayAdapters: {\n ready: true,\n },\n restUpstream: {\n ready: (upstreams.rest?.status ?? 'down') === 'up',\n status: upstreams.rest?.status ?? 'down',\n },\n workflowUpstream: {\n ready: (upstreams.workflow?.status ?? 'down') === 'up',\n status: upstreams.workflow?.status ?? 'down',\n },\n marketplaceUpstream: {\n ready: (upstreams.marketplace?.status ?? 'down') === 'up',\n status: upstreams.marketplace?.status ?? 'down',\n },\n },\n }));\n });\n\n scope.get('/metrics', { schema: { tags: ['Observability'], summary: 'Gateway metrics in Prometheus format' } }, async (_request, reply) => {\n const health = await collectHealthSnapshot();\n const status = (health.status as 'healthy' | 'degraded' | 'unhealthy' | undefined) ?? 'healthy';\n reply.header('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');\n return observability.renderPrometheusMetrics(status);\n });\n\n scope.get('/observability/describe', {\n schema: { tags: ['Observability'], summary: 'Gateway observability contract descriptor' },\n }, async () => observability.buildDescribe());\n\n scope.get('/observability/health', {\n schema: { tags: ['Observability'], summary: 'Gateway observability health snapshot' },\n }, async () => {\n const health = await collectHealthSnapshot();\n const adapterChecks = Object.entries((health.adapters as Record<string, { available?: boolean; latencyMs?: number }> | undefined) ?? {})\n .map(([id, value]) => ({ id, available: !!value?.available, latencyMs: value?.latencyMs }));\n const upstreamChecks = Object.entries((health.upstreams as Record<string, { status?: string; latencyMs?: number }> | undefined) ?? {})\n .map(([id, value]) => ({ id, status: value?.status ?? 'unknown', latencyMs: value?.latencyMs }));\n const status = (health.status as 'healthy' | 'degraded' | 'unhealthy' | undefined) ?? 'healthy';\n return observability.buildHealth({ status, adapterChecks, upstreamChecks });\n });\n\n // Host registration (public)\n // Use injected registry (with persistence) or fallback to cache-only\n if (!registry) {\n gatewayLogger.warn('No persistent HostRegistry injected — hosts will be lost on restart');\n }\n const hostRegistry = registry ?? new HostRegistry(cache);\n scope.post('/hosts/register', { schema: { tags: ['Hosts'], summary: 'Register a host' } }, async (request, reply) => {\n const parsed = HostRegistrationSchema.safeParse(request.body);\n if (!parsed.success) {\n return reply.code(400).send({ error: 'Bad Request', issues: parsed.error.issues });\n }\n const result = await hostRegistry.register(parsed.data);\n return reply.code(201).send({\n hostId: result.descriptor.hostId,\n machineToken: result.machineToken,\n status: result.descriptor.status,\n });\n });\n\n // List hosts (auth required)\n scope.get('/hosts', { schema: { tags: ['Hosts'], summary: 'List registered hosts' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n const hosts = await hostRegistry.list(auth.namespaceId);\n return { hosts };\n });\n\n // Get host by ID (auth required)\n scope.get<{ Params: { hostId: string } }>('/hosts/:hostId', { schema: { tags: ['Hosts'], summary: 'Get host by ID' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n const { hostId } = request.params;\n const host = await hostRegistry.get(hostId, auth.namespaceId);\n if (!host) {\n return reply.code(404).send({ error: 'Host not found' });\n }\n return host;\n });\n\n // Deregister host (auth required)\n scope.delete<{ Params: { hostId: string } }>('/hosts/:hostId', { schema: { tags: ['Hosts'], summary: 'Deregister a host' } }, async (request, reply) => {\n const auth = request.authContext;\n if (!auth) {\n return reply.code(401).send({ error: 'Unauthorized' });\n }\n const { hostId } = request.params;\n const deleted = await hostRegistry.deregister(hostId, auth.namespaceId);\n if (!deleted) {\n return reply.code(404).send({ error: 'Host not found' });\n }\n return reply.code(204).send();\n });\n\n // Execute endpoint — public API for CLI/Studio clients (auth required)\n registerExecuteRoutes(scope as unknown as Parameters<typeof registerExecuteRoutes>[0], logger);\n\n // AI Gateway — OpenAI-compatible LLM endpoint (auth required)\n registerLLMGatewayRoutes(scope as unknown as Parameters<typeof registerLLMGatewayRoutes>[0], logger);\n\n // Telemetry ingestion — unified event collection (auth required)\n registerTelemetryRoutes(scope as unknown as Parameters<typeof registerTelemetryRoutes>[0], logger);\n\n // Unified Platform API — single dispatch for any adapter (auth required)\n registerPlatformRoutes(scope as unknown as Parameters<typeof registerPlatformRoutes>[0], logger);\n\n // Aggregated docs — /openapi-merged.json + /docs-all\n registerAggregatedDocsRoutes(scope as unknown as Parameters<typeof registerAggregatedDocsRoutes>[0], config, serviceTransport, cache);\n\n\n registerInternalRoutes(scope as unknown as Parameters<typeof registerInternalRoutes>[0], process.env.GATEWAY_INTERNAL_SECRET, hostRegistry, cache);\n\n // Webhook admin routes — provision / list / revoke (auth required, inside scope).\n // Registered unconditionally when the resource broker is available so that the\n // admin API (GET /api/v1/webhooks, POST /api/v1/webhooks/provision, DELETE) works\n // even in environments where no webhook-enabled plugins are currently installed.\n if (platform.hasResourceBroker) {\n const webhookBaseUrl = process.env.GATEWAY_PUBLIC_URL ?? `http://localhost:${config.port + (Number(process.env.KB_NET_OFFSET) || 0)}`;\n // Thin adapter: globalDispatcher.call() requires namespaceId — threaded via optional field\n const provisionBackend = {\n async execute({ handlerRef, pluginRoot, input, namespaceId }: {\n handlerRef: string; pluginRoot: string; input: unknown; namespaceId?: string;\n }): Promise<unknown> {\n if (!namespaceId) { return; }\n const hostId = globalDispatcher.firstHostWithCapability(namespaceId, 'execution');\n if (!hostId) { return; }\n return globalDispatcher.call(namespaceId, hostId, 'execution', 'execute', [\n { handlerRef, pluginRoot, input },\n ]);\n },\n };\n registerWebhookAdminRoutes(\n scope as unknown as Parameters<typeof registerWebhookAdminRoutes>[0],\n {\n cache,\n logger,\n backend: provisionBackend,\n manifests: webhookManifests ?? [],\n baseUrl: webhookBaseUrl,\n broker: platform.resourceBroker,\n },\n );\n }\n });\n\n // ── Webhook delivery routes (outside gatewayRoutes — no auth middleware) ──────\n // Registered in a separate Fastify scope so both user-auth and machine-token\n // middleware (which live only inside gatewayRoutes) are bypassed automatically.\n // Delivery auth is handled by the webhook router itself (secret / hmac / custom).\n if (webhookManifests?.length && platform.hasResourceBroker) {\n const webhookBaseUrl = process.env.GATEWAY_PUBLIC_URL ?? `http://localhost:${config.port + (Number(process.env.KB_NET_OFFSET) || 0)}`;\n await app.register(async (webhookScope) => {\n await registerWebhookRoutes(webhookScope, {\n cache,\n broker: platform.resourceBroker,\n logger,\n manifests: webhookManifests,\n baseUrl: webhookBaseUrl,\n });\n });\n }\n\n // ── Gateway WebSocket endpoints ────────────────────────────────────\n // Must be after ready() so http-proxy's upgrade listener is registered.\n // attachGatewayWs captures it, removes it, and installs a unified handler\n // that dispatches gateway WS paths to raw ws handlers and delegates\n // everything else (upstream WS proxy) to http-proxy.\n await app.ready();\n attachGatewayWs(app.server, cache, jwtConfig, logger, registry, socketWsUpstreams);\n\n return app;\n}\n","import { logDiagnosticEvent, type IServiceTransport } from '@kb-labs/core-platform';\nimport { createInMemoryDocumentDatabase, createInMemoryKVStore } from '@kb-labs/core-platform/inmemory';\nimport { platform, createServiceBootstrap, getPlatformRoot, getProjectRoot } from '@kb-labs/core-runtime';\nimport { makeAssemblyHook } from '@kb-labs/plugin-runtime';\nimport { createCorrelatedLogger } from '@kb-labs/shared-http';\nimport type { IHostStore, AuthConfig } from '@kb-labs/gateway-contracts';\nimport type { IDocumentDatabase } from '@kb-labs/core-platform/adapters';\nimport { HostStore } from '@kb-labs/gateway-core';\nimport {\n UsersStore,\n CredentialsStore,\n MembershipsStore,\n SessionsStore,\n InvitesStore,\n loadIdentityProviders,\n createPasswordPolicy,\n createUserAuthService,\n createStubPDP,\n createTenantResolver,\n createRateLimiter,\n ensureBootstrapAdmin,\n ensureBootstrapCliCredentials,\n AuthService,\n OAuthStateStore,\n} from '@kb-labs/gateway-auth';\nimport type { IKVStore } from '@kb-labs/core-platform/adapters';\nimport { createRegistry } from '@kb-labs/core-registry';\nimport { loadGatewayConfig } from './config.js';\nimport { createServer, type UserAuthServerDeps } from './server.js';\nimport { HostRegistry } from './hosts/registry.js';\nimport { registerPressureLimits } from './pressure/index.js';\nimport type { WebhookManifestEntry } from './webhook/router.js';\n\nexport async function bootstrap(repoRoot: string = process.cwd()): Promise<void> {\n // 1. Initialize platform (loads .env + adapters from kb.config.json)\n await createServiceBootstrap({ appId: 'gateway', repoRoot, assemblyHook: makeAssemblyHook() });\n\n const logger = createCorrelatedLogger(platform.logger, {\n serviceId: 'gateway',\n logsSource: 'gateway',\n layer: 'gateway',\n service: 'bootstrap',\n operation: 'gateway.bootstrap',\n });\n logger.info('Platform initialized', { repoRoot });\n\n // 2. Load gateway config — reads platform baseline + project layer +\n // `.kb/overlays/*.jsonc`. Use the resolved roots from core-runtime\n // (which honour KB_PROJECT_ROOT and the platform.dir override) rather\n // than process.cwd() — in installed mode the gateway process is\n // spawned with cwd at the platform root, and we MUST not conflate\n // that with the project root.\n const config = await loadGatewayConfig(getProjectRoot() ?? repoRoot, getPlatformRoot());\n logger.info('Gateway config loaded', {\n port: config.port,\n upstreams: Object.keys(config.upstreams),\n projectRoot: getProjectRoot() ?? repoRoot,\n platformRoot: getPlatformRoot(),\n configProviderIds: config.auth?.providers ? Object.keys(config.auth.providers) : [],\n });\n\n // 3. Create persistent host store backed by the platform document database.\n // Falls back to an in-memory implementation so user auth works without a\n // configured adapter (dev / CI environments with no external DB).\n // The same code runs on sqlite locally and on postgres/mongo in prod — the\n // gateway has no business knowing which driver is wired underneath.\n let hostStore: IHostStore | undefined;\n const configuredDocs = platform.getAdapter<IDocumentDatabase>('documentDatabase');\n const docs: IDocumentDatabase = configuredDocs ?? createInMemoryDocumentDatabase();\n if (configuredDocs) {\n hostStore = new HostStore(docs);\n logger.info('Host store: documentDatabase-backed (persistent)');\n } else {\n hostStore = new HostStore(docs);\n logger.warn('documentDatabase: in-memory fallback (data lost on restart)');\n logger.warn('Host store: in-memory (hosts will be lost on restart)');\n }\n\n // 3b. User auth infrastructure (ADR-0020). Always available — uses in-memory\n // documentDatabase when no persistent adapter is configured.\n let userAuth: UserAuthServerDeps | undefined;\n {\n const { accessTtlSec, refreshTtlSec, graceWindowMs, bcryptCost, cookieSecure } =\n resolveAuthRuntimeConfig(config.auth, process.env);\n const tenantPattern = config.tenants?.pattern ?? '{tenant}.kblabs.ru';\n const bootstrapTenantId =\n config.auth?.bootstrap?.tenantId ??\n process.env.GATEWAY_BOOTSTRAP_TENANT_ID ??\n 'kblabs-cloud';\n\n const users = new UsersStore(docs);\n const credentials = new CredentialsStore(docs);\n const memberships = new MembershipsStore(docs);\n const sessions = new SessionsStore(docs, {\n refreshTtlMs: refreshTtlSec * 1000,\n graceWindowMs,\n });\n const invites = new InvitesStore(docs);\n\n // Identity providers are loaded from config (ADR-0020, DD-3). An\n // empty/absent `auth.providers` registers the built-in email-password\n // door; configured providers (built-in `oidc` or third-party packages)\n // load through the same factory path. Fail-fast on any load error.\n const providers = await loadIdentityProviders(config.auth?.providers, {\n users,\n credentials,\n tenantId: bootstrapTenantId,\n bcryptCost,\n logger,\n });\n\n const passwordPolicy = createPasswordPolicy({\n minLength: config.auth?.passwordPolicy?.minLength ?? 8,\n maxLength: config.auth?.passwordPolicy?.maxLength ?? 256,\n hibpEnabled: config.auth?.passwordPolicy?.hibpEnabled ?? true,\n });\n\n const pdp = createStubPDP({ memberships });\n\n const tenantResolver = createTenantResolver({ pattern: tenantPattern });\n\n const userAuthService = createUserAuthService({\n users,\n credentials,\n memberships,\n sessions,\n invites,\n providers,\n passwordPolicy,\n jwtConfig: { secret: process.env.GATEWAY_JWT_SECRET ?? 'dev-insecure-secret-change-me' },\n accessTtlSec,\n refreshTtlSec,\n bcryptCost,\n });\n\n // Seed bootstrap admin account (step 1.14). Idempotent.\n const adminEmail =\n config.auth?.bootstrap?.adminEmail ?? process.env.GATEWAY_BOOTSTRAP_ADMIN_EMAIL;\n const adminPassword = process.env.GATEWAY_BOOTSTRAP_ADMIN_PASSWORD;\n await ensureBootstrapAdmin({\n bootstrap:\n adminEmail && adminPassword\n ? { adminEmail, adminPassword, tenantId: bootstrapTenantId }\n : undefined,\n users,\n credentials,\n memberships,\n bcryptCost,\n logger,\n }).catch((err) => {\n logger.warn('Bootstrap admin seed failed (non-fatal)', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n // AUTH_INVITE_TTL_MS env var overrides config (used in E2E to test short-lived invites).\n const inviteTtlMs = process.env.AUTH_INVITE_TTL_MS\n ? parseInt(process.env.AUTH_INVITE_TTL_MS, 10)\n : (config.auth?.inviteTtlMs ?? 7 * 24 * 60 * 60 * 1000);\n\n // Rate limiter — uses kvStore if available; falls back to in-memory.\n // In-memory is sufficient for single-process deployments (E2E, dev) and\n // ensures rate limiting is always active. Production deployments with a\n // persistent kvStore get cross-restart counters automatically.\n const kv = platform.getAdapter<IKVStore>('kvStore') ?? createInMemoryKVStore();\n const rateLimiter = createRateLimiter(kv);\n if (!platform.getAdapter<IKVStore>('kvStore')) {\n logger.warn('kvStore adapter not configured — auth rate limiting using in-memory KV (counters reset on restart)');\n }\n\n // AUTH_LOGIN_RATE_LIMIT_PER_IP / AUTH_LOGIN_RATE_LIMIT_PER_EMAIL env vars override\n // config (used in E2E where many specs call /auth/login from the same IP in rapid\n // succession — the production defaults of 10/m and 5/m would trigger false 429s).\n const loginPerIpPerMinute = process.env.AUTH_LOGIN_RATE_LIMIT_PER_IP\n ? parseInt(process.env.AUTH_LOGIN_RATE_LIMIT_PER_IP, 10)\n : (config.auth?.rateLimit?.loginPerIpPerMinute ?? 10);\n const loginPerEmailPerMinute = process.env.AUTH_LOGIN_RATE_LIMIT_PER_EMAIL\n ? parseInt(process.env.AUTH_LOGIN_RATE_LIMIT_PER_EMAIL, 10)\n : (config.auth?.rateLimit?.loginPerEmailPerMinute ?? 5);\n\n // OAuth state store (ADR-0020, DD-5). Shares the same KV as the rate\n // limiter via a namespaced key prefix. The redirect/OAuth routes register\n // only when this is present.\n const oauthState = new OAuthStateStore(kv);\n\n // Step 4b shared-KV requirement: in a multi-process / HA deployment the\n // callback may land on a different worker than the one that minted the\n // state, so an in-memory KV silently breaks OAuth. Warn when a redirect\n // provider is configured against a non-shared KV.\n const hasRedirectProvider = providers.list().some((p) => p.kind === 'redirect');\n if (hasRedirectProvider && !platform.getAdapter<IKVStore>('kvStore')) {\n logger.warn(\n 'OAuth requires a shared kvStore (Redis) in multi-process/HA; in-memory state is per-process and callbacks may land on a different worker',\n );\n }\n\n userAuth = {\n userAuthService,\n users,\n sessions,\n invites,\n providers,\n pdp,\n tenantResolver,\n cookieSecure,\n accessTtlSec,\n refreshTtlSec,\n inviteTtlMs,\n rateLimiter,\n authRateLimit: { loginPerIpPerMinute, loginPerEmailPerMinute },\n oauthState,\n };\n\n logger.info('User auth infrastructure initialised', {\n tenantPattern,\n bootstrapTenantId,\n cookieSecure,\n persistent: !!configuredDocs,\n });\n }\n\n // 4. Create host registry with cache + store\n // Capture once so registry and server share the exact same cache instance.\n const cache = platform.cache;\n const registry = new HostRegistry(cache, hostStore);\n\n // 5. Restore persisted hosts into cache (best-effort — cache may be unavailable on cold start)\n let restoredCount = 0;\n try {\n restoredCount = await registry.restore();\n } catch (error) {\n logDiagnosticEvent(platform.logger, {\n domain: 'registry',\n event: 'gateway.hosts.restore',\n level: 'error',\n reasonCode: 'registry_restore_failed',\n message: 'Failed to restore gateway host registry',\n outcome: 'failed',\n error: error instanceof Error ? error : new Error(String(error)),\n serviceId: 'gateway',\n evidence: {\n persistentStore: !!hostStore,\n },\n });\n // Non-fatal: gateway can start without restored state; hosts will re-register on reconnect\n }\n if (restoredCount > 0) {\n logger.info('Restored hosts from store', { count: restoredCount });\n }\n\n // 5b. Discover plugin manifests for webhook route registration.\n // Uses snapshot().manifests — PluginBrief from listPlugins() lacks manifest/pluginRoot.\n // Graceful: failure disables webhook routes but does not block gateway startup.\n let webhookManifests: WebhookManifestEntry[] = [];\n try {\n const projectRoot = getProjectRoot() ?? repoRoot;\n const platformRoot = getPlatformRoot();\n const pluginRegistry = await createRegistry({\n root: projectRoot,\n platformRoot: platformRoot !== projectRoot ? platformRoot : undefined,\n cache: { ttlMs: 600_000, adapter: cache },\n });\n const snapshot = pluginRegistry.snapshot();\n webhookManifests = snapshot.manifests\n .filter((entry) => (entry.manifest.webhooks?.handlers?.length ?? 0) > 0)\n .map((entry) => ({\n pluginId: entry.pluginId,\n manifest: entry.manifest,\n pluginRoot: entry.pluginRoot,\n }));\n if (webhookManifests.length > 0) {\n logger.info('Webhook manifests discovered', { count: webhookManifests.length });\n }\n } catch (err) {\n logger.warn('Webhook manifest discovery failed — webhook routes disabled', {\n error: err instanceof Error ? err.message : String(err),\n });\n webhookManifests = [];\n }\n\n // 6. Build JWT config — secret required; no fallback in production.\n const DEV_JWT_SECRET = 'dev-insecure-secret-change-me';\n const jwtSecret = process.env.GATEWAY_JWT_SECRET;\n const isProduction = process.env.NODE_ENV === 'production';\n if (!jwtSecret && isProduction) {\n throw new Error(\n 'GATEWAY_JWT_SECRET must be set in production. ' +\n 'Generate one with: node -e \"console.log(require(\\'crypto\\').randomBytes(64).toString(\\'hex\\'))\"',\n );\n }\n if (!jwtSecret) {\n logger.warn('GATEWAY_JWT_SECRET not set — using insecure default (dev only, never use in production!)');\n }\n const jwtConfig = { secret: jwtSecret ?? DEV_JWT_SECRET };\n\n // 7. Auto-provision the CLI's first credential for non-local installs (#271).\n // Opt-in via config.auth.bootstrap.provisionCliCredentials (set by kb-create\n // for --yes/server-mode installs). Mints a fixed-handle machine service\n // account in-process (no HTTP round-trip, so MACHINE_REGISTER never applies)\n // and writes ~/.kb/credentials.json so `kb` commands work with zero manual\n // `kb auth login`. Idempotent — see ensureBootstrapCliCredentials.\n if (config.auth?.bootstrap?.provisionCliCredentials === true) {\n const bootstrapAuthService = new AuthService(cache, jwtConfig);\n await ensureBootstrapCliCredentials({\n enabled: true,\n authService: bootstrapAuthService,\n gatewayUrl: `http://127.0.0.1:${config.port}`,\n logger,\n }).catch((err: unknown) => {\n logger.warn('Bootstrap CLI credentials provisioning failed (non-fatal)', {\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }\n\n // 8. Register HTTP pressure-control limits (ADR-0056). No-op when\n // `gateway.pressure` is absent or disabled in config.\n if (platform.hasResourceBroker) {\n registerPressureLimits(platform.resourceBroker, config.pressure, platform.logger);\n } else {\n logger.warn('Resource broker unavailable — pressure control disabled');\n }\n\n // 9. Get service transport from platform adapter.\n // Configured via platform.adapters.serviceTransport in kb.config.json.\n // kb-create installs @kb-labs/adapters-service-transport-http by default\n // and writes adapterOptions.serviceTransport.services with TCP URLs.\n const serviceTransport = platform.getAdapter<IServiceTransport>('serviceTransport');\n if (!serviceTransport) {\n throw new Error(\n 'Gateway requires the serviceTransport adapter. ' +\n 'Configure it in kb.config.json:\\n' +\n ' \"adapters\": { \"serviceTransport\": \"@kb-labs/adapters-service-transport-http\" },\\n' +\n ' \"adapterOptions\": { \"serviceTransport\": { \"services\": { \"rest\": { \"url\": \"http://127.0.0.1:5050\" }, ... } } }',\n );\n }\n\n // 10. Create server with injected registry, transport and optional user auth deps\n const server = await createServer(config, cache, platform.logger, jwtConfig, registry, serviceTransport, userAuth, webhookManifests);\n\n // 11. Listen\n const bindHost = config.host ?? '0.0.0.0';\n\n // Safety guardrail (B-023): a platform with auth disabled must never be\n // reachable off the local machine. If auth is off, the bind host MUST be a\n // loopback address — otherwise refuse to start with a clear, actionable error.\n if (config.auth?.enabled === false && !isLoopbackHost(bindHost)) {\n throw new Error(\n `Refusing to start: auth is disabled but the gateway binds to \"${bindHost}\" ` +\n `(not loopback). A no-auth platform reachable on the network grants full ` +\n `access to anyone. Either set gateway.auth.enabled = true, or bind to ` +\n `127.0.0.1 (gateway.host) for solo/local use.`,\n );\n }\n\n // The gateway is the network's entry point — not a target in the transport\n // map — so it reads the offset directly (edge service). Internal routing to\n // upstreams already shifts via the transport. KB_NET_OFFSET is a LOCAL\n // mechanism (parallel environments on one host); 0 in cloud/k8s.\n const netOffset = Number(process.env.KB_NET_OFFSET) || 0;\n const listenPort = config.port + netOffset;\n const address = await server.listen({ port: listenPort, host: bindHost });\n logger.info('Gateway listening', { address, authEnabled: config.auth?.enabled !== false });\n\n // 10. Graceful shutdown\n const shutdown = async (signal: string) => {\n logger.warn('Received shutdown signal', { signal });\n await platform.shutdown();\n await server.close();\n logger.info('Gateway shutdown complete');\n process.exit(0);\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n}\n\n/**\n * Resolves the user-auth runtime knobs (TTLs, cookie security, bcrypt cost,\n * refresh grace window) from config + environment.\n *\n * `config.auth` is optional in the raw JSON, but once the `auth` object is\n * present at all — which it now always is, since kb-create writes\n * gateway.auth.bootstrap on every non-local install — zod applies its own\n * schema defaults (sessionAccessTtlSec: 900, cookieSecure: true, etc.) to\n * every field, not just the ones actually set in the raw config. That means\n * `config.auth?.X ?? envFallback` NEVER reaches the env fallback once `auth`\n * exists at all, even for fields the user never explicitly configured.\n *\n * AUTH_ACCESS_TTL_SEC / AUTH_REFRESH_TTL_SEC / AUTH_COOKIE_SECURE are meant\n * to be a CI-only override \"without touching the config file\" (e.g.\n * AUTH_ACCESS_TTL_SEC=5 for session-lifecycle E2E tests, AUTH_COOKIE_SECURE=\n * false for HTTP-only CI environments) — so they must be checked BEFORE the\n * (possibly zod-defaulted) config value, not after.\n */\nexport function resolveAuthRuntimeConfig(\n authConfig: AuthConfig | undefined,\n env: NodeJS.ProcessEnv,\n): {\n accessTtlSec: number;\n refreshTtlSec: number;\n graceWindowMs: number;\n bcryptCost: number;\n cookieSecure: boolean;\n} {\n const accessTtlSec = env.AUTH_ACCESS_TTL_SEC\n ? parseInt(env.AUTH_ACCESS_TTL_SEC, 10)\n : (authConfig?.sessionAccessTtlSec ?? 900);\n const refreshTtlSec = env.AUTH_REFRESH_TTL_SEC\n ? parseInt(env.AUTH_REFRESH_TTL_SEC, 10)\n : (authConfig?.sessionRefreshTtlSec ?? 30 * 24 * 3600);\n const graceWindowMs = (authConfig?.refreshGraceWindowSec ?? 5) * 1000;\n const bcryptCost = authConfig?.bcryptCost ?? 12;\n // AUTH_COOKIE_SECURE=false disables Secure flag for HTTP-only CI environments.\n // In production (HTTPS) leave unset or set to true.\n const cookieSecure = env.AUTH_COOKIE_SECURE === 'false'\n ? false\n : (authConfig?.cookieSecure ?? true);\n\n return { accessTtlSec, refreshTtlSec, graceWindowMs, bcryptCost, cookieSecure };\n}\n\n/**\n * True when the bind host is a loopback address (only reachable from the local\n * machine). Used by the auth-disabled startup guardrail (B-023).\n */\nexport function isLoopbackHost(host: string): boolean {\n const h = host.trim().toLowerCase();\n return (\n h === '127.0.0.1' ||\n h === 'localhost' ||\n h === '::1' ||\n h === '[::1]' ||\n h.startsWith('127.')\n );\n}\n","import { bootstrap } from './bootstrap.js';\n\n// process.cwd() = workspace root when launched via `node ./infra/kb-labs-gateway/.../dist/index.js`\nbootstrap(process.cwd()).catch((error) => {\n console.error('Failed to start gateway:', error);\n process.exit(1);\n});\n"]}