From b5c81f732c95fbbfc9dcbff03a166e63ec357720 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 04:39:59 +0000 Subject: [PATCH] refactor(gateway): share bearer auth helper --- src/gateway/http-auth-helpers.ts | 27 +++++++++++++++++++++++++++ src/gateway/openai-http.ts | 16 +++++++--------- src/gateway/openresponses-http.ts | 16 +++++++--------- 3 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 src/gateway/http-auth-helpers.ts diff --git a/src/gateway/http-auth-helpers.ts b/src/gateway/http-auth-helpers.ts new file mode 100644 index 000000000..449e9369c --- /dev/null +++ b/src/gateway/http-auth-helpers.ts @@ -0,0 +1,27 @@ +import type { IncomingMessage, ServerResponse } from "node:http"; +import type { AuthRateLimiter } from "./auth-rate-limit.js"; +import { authorizeGatewayConnect, type ResolvedGatewayAuth } from "./auth.js"; +import { sendGatewayAuthFailure } from "./http-common.js"; +import { getBearerToken } from "./http-utils.js"; + +export async function authorizeGatewayBearerRequestOrReply(params: { + req: IncomingMessage; + res: ServerResponse; + auth: ResolvedGatewayAuth; + trustedProxies?: string[]; + rateLimiter?: AuthRateLimiter; +}): Promise { + const token = getBearerToken(params.req); + const authResult = await authorizeGatewayConnect({ + auth: params.auth, + connectAuth: token ? { token, password: token } : null, + req: params.req, + trustedProxies: params.trustedProxies, + rateLimiter: params.rateLimiter, + }); + if (!authResult.ok) { + sendGatewayAuthFailure(params.res, authResult); + return false; + } + return true; +} diff --git a/src/gateway/openai-http.ts b/src/gateway/openai-http.ts index 57eec192b..86b0e2d7d 100644 --- a/src/gateway/openai-http.ts +++ b/src/gateway/openai-http.ts @@ -1,6 +1,7 @@ import type { IncomingMessage, ServerResponse } from "node:http"; import { randomUUID } from "node:crypto"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; +import type { ResolvedGatewayAuth } from "./auth.js"; import { createDefaultDeps } from "../cli/deps.js"; import { agentCommand } from "../commands/agent.js"; import { emitAgentEvent, onAgentEvent } from "../infra/agent-events.js"; @@ -10,16 +11,15 @@ import { buildAgentMessageFromConversationEntries, type ConversationEntry, } from "./agent-prompt.js"; -import { authorizeGatewayConnect, type ResolvedGatewayAuth } from "./auth.js"; +import { authorizeGatewayBearerRequestOrReply } from "./http-auth-helpers.js"; import { readJsonBodyOrError, - sendGatewayAuthFailure, sendJson, sendMethodNotAllowed, setSseHeaders, writeDone, } from "./http-common.js"; -import { getBearerToken, resolveAgentIdForRequest, resolveSessionKey } from "./http-utils.js"; +import { resolveAgentIdForRequest, resolveSessionKey } from "./http-utils.js"; type OpenAiHttpOptions = { auth: ResolvedGatewayAuth; @@ -161,16 +161,14 @@ export async function handleOpenAiHttpRequest( return true; } - const token = getBearerToken(req); - const authResult = await authorizeGatewayConnect({ - auth: opts.auth, - connectAuth: { token, password: token }, + const authorized = await authorizeGatewayBearerRequestOrReply({ req, + res, + auth: opts.auth, trustedProxies: opts.trustedProxies, rateLimiter: opts.rateLimiter, }); - if (!authResult.ok) { - sendGatewayAuthFailure(res, authResult); + if (!authorized) { return true; } diff --git a/src/gateway/openresponses-http.ts b/src/gateway/openresponses-http.ts index bb8cbf7e6..df32f643c 100644 --- a/src/gateway/openresponses-http.ts +++ b/src/gateway/openresponses-http.ts @@ -12,6 +12,7 @@ import type { ClientToolDefinition } from "../agents/pi-embedded-runner/run/para import type { ImageContent } from "../commands/agent/types.js"; import type { GatewayHttpResponsesConfig } from "../config/types.gateway.js"; import type { AuthRateLimiter } from "./auth-rate-limit.js"; +import type { ResolvedGatewayAuth } from "./auth.js"; import { createDefaultDeps } from "../cli/deps.js"; import { agentCommand } from "../commands/agent.js"; import { emitAgentEvent, onAgentEvent } from "../infra/agent-events.js"; @@ -39,16 +40,15 @@ import { buildAgentMessageFromConversationEntries, type ConversationEntry, } from "./agent-prompt.js"; -import { authorizeGatewayConnect, type ResolvedGatewayAuth } from "./auth.js"; +import { authorizeGatewayBearerRequestOrReply } from "./http-auth-helpers.js"; import { readJsonBodyOrError, - sendGatewayAuthFailure, sendJson, sendMethodNotAllowed, setSseHeaders, writeDone, } from "./http-common.js"; -import { getBearerToken, resolveAgentIdForRequest, resolveSessionKey } from "./http-utils.js"; +import { resolveAgentIdForRequest, resolveSessionKey } from "./http-utils.js"; import { CreateResponseBodySchema, type ContentPart, @@ -334,16 +334,14 @@ export async function handleOpenResponsesHttpRequest( return true; } - const token = getBearerToken(req); - const authResult = await authorizeGatewayConnect({ - auth: opts.auth, - connectAuth: { token, password: token }, + const authorized = await authorizeGatewayBearerRequestOrReply({ req, + res, + auth: opts.auth, trustedProxies: opts.trustedProxies, rateLimiter: opts.rateLimiter, }); - if (!authResult.ok) { - sendGatewayAuthFailure(res, authResult); + if (!authorized) { return true; }