evework / agent /lib /api-key-auth.ts
hunian
refactor: streamline Dockerfile and improve environment variable handling
5f68d99
Raw
History Blame Contribute Delete
1.67 kB
/** /eve 与 /agentfs 共用:Bearer AGENT_API_KEY + localDev。 */
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);
}
/** 生产未配 key 直接报错;错/无 token 返回 null 交给 localDev。 */
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()];
}