| |
| import { createHash, timingSafeEqual } from "node:crypto"; |
|
|
| import { |
| extractBearerToken, |
| localDev, |
| UnauthenticatedError, |
| type AuthFn, |
| } from "eve/channels/auth"; |
| import type { SessionAuthContext } from "eve/context"; |
|
|
| export const AGENT_API_KEY = process.env.AGENT_API_KEY?.trim() ?? ""; |
|
|
| function isPublicDeployment(): boolean { |
| if (process.env.VERCEL) { |
| return process.env.VERCEL_ENV !== "development"; |
| } |
| return process.env.NODE_ENV === "production"; |
| } |
|
|
| function safeEqual(a: string, b: string): boolean { |
| const aHash = createHash("sha256").update(a).digest(); |
| const bHash = createHash("sha256").update(b).digest(); |
| return timingSafeEqual(aHash, bHash); |
| } |
|
|
| |
| export function apiKeyAuth(): AuthFn<Request> { |
| return (request) => { |
| if (AGENT_API_KEY.length === 0) { |
| if (isPublicDeployment()) { |
| throw new UnauthenticatedError({ |
| code: "eve_api_key_not_configured", |
| message: |
| "AGENT_API_KEY is not configured. Set it in deployment secrets (HF Space / .env).", |
| }); |
| } |
| return null; |
| } |
| const token = extractBearerToken(request.headers.get("authorization")); |
| if (token === null) return null; |
| if (!safeEqual(token, AGENT_API_KEY)) return null; |
| return { |
| attributes: {}, |
| authenticator: "api-key", |
| principalId: "api-key", |
| principalType: "service", |
| } satisfies SessionAuthContext; |
| }; |
| } |
|
|
| export function serviceAuthChain(): readonly AuthFn<Request>[] { |
| return [apiKeyAuth(), localDev()]; |
| } |
|
|