type JsonObject = Record; const FINE_GRAINED_ROLE = "fineGrained"; const INFERENCE_PROVIDERS_PERMISSION = "inference.serverless.write"; const INFERENCE_ENDPOINTS_PERMISSION = "inference.endpoints.infer.write"; const ALLOWED_INFERENCE_PERMISSIONS = new Set([ INFERENCE_PROVIDERS_PERMISSION, INFERENCE_ENDPOINTS_PERMISSION, ]); export type InferenceCredentialReadiness = | { credential: "ok" } | { credential: "not_required" } | { credential: "missing"; error: string } | { credential: "invalid"; error: string } | { credential: "unknown"; error: string }; export async function checkInferenceCredential(params: { enabled: boolean; token: string | undefined; fetchFn?: typeof fetch; }): Promise { if (!params.enabled) return { credential: "not_required" }; if (params.token === undefined) { return { credential: "missing", error: "INFERENCE_TOKEN is required when enrichment is enabled.", }; } try { const response = await (params.fetchFn ?? fetch)("https://huggingface.co/api/whoami-v2", { headers: { authorization: `Bearer ${params.token}` }, }); if (!response.ok) { return tokenStatusError(response.status); } const errors = inferenceTokenErrors(await response.json()); return errors.length === 0 ? { credential: "ok" } : { credential: "invalid", error: errors.join(" ") }; } catch (error) { return { credential: "unknown", error: errorMessage(error) }; } } export function inferenceCredentialOk(status: InferenceCredentialReadiness): boolean { return status.credential === "ok" || status.credential === "not_required"; } function inferenceTokenErrors(payload: unknown): string[] { const root = asRecord(payload); const accessToken = asRecord(asRecord(root["auth"])["accessToken"]); const fineGrained = asRecord(accessToken["fineGrained"]); const role = text(accessToken["role"]); const errors = role === FINE_GRAINED_ROLE ? [] : [`INFERENCE_TOKEN role is '${role || "unknown"}', expected fine-grained.`]; const globalHasInference = evaluateGlobalInferencePermissions(fineGrained, errors); const scoped = evaluateScopedInferencePermissions(fineGrained, errors); if (!globalHasInference && !scoped.hasInference) { errors.push(`INFERENCE_TOKEN must include ${INFERENCE_PROVIDERS_PERMISSION}.`); } return errors; } function evaluateGlobalInferencePermissions(fineGrained: JsonObject, errors: string[]): boolean { let hasInference = false; for (const permission of strings(fineGrained["global"])) { if (ALLOWED_INFERENCE_PERMISSIONS.has(permission)) { if (permission === INFERENCE_PROVIDERS_PERMISSION) hasInference = true; } else { errors.push(`Unexpected global permission on INFERENCE_TOKEN: ${permission}.`); } } return hasInference; } function evaluateScopedInferencePermissions( fineGrained: JsonObject, errors: string[], ): { hasInference: boolean } { let hasInference = false; for (const scope of array(fineGrained["scoped"])) { const scoped = asRecord(scope); const permissions = strings(scoped["permissions"]); if ( isUserScope(asRecord(scoped["entity"])) && permissions.length > 0 && permissions.every((permission) => ALLOWED_INFERENCE_PERMISSIONS.has(permission)) ) { if (permissions.includes(INFERENCE_PROVIDERS_PERMISSION)) hasInference = true; } else { errors.push(`Unexpected scoped permission on INFERENCE_TOKEN: ${scopeLabel(scoped)}.`); } } return { hasInference }; } function isUserScope(entity: JsonObject): boolean { const type = text(entity["type"]); return type === "user" || type === "users"; } function scopeLabel(scope: JsonObject): string { const entity = asRecord(scope["entity"]); const kind = text(entity["type"]) || "unknown"; const name = text(entity["name"]) || text(entity["id"]) || "unknown"; const permissions = strings(scope["permissions"]); return `${permissions.join(", ") || "unknown"} on ${kind}:${name}`; } function tokenStatusError(status: number): InferenceCredentialReadiness { const error = `Hugging Face rejected INFERENCE_TOKEN (${String(status)}).`; if (status === 401 || status === 403) return { credential: "invalid", error }; return { credential: "unknown", error }; } function asRecord(value: unknown): JsonObject { return typeof value === "object" && value !== null && !Array.isArray(value) ? (value as JsonObject) : {}; } function array(value: unknown): readonly unknown[] { return Array.isArray(value) ? value : []; } function strings(value: unknown): readonly string[] { return array(value).filter((item): item is string => typeof item === "string"); } function text(value: unknown): string { return typeof value === "string" ? value : ""; } function errorMessage(error: unknown): string { return error instanceof Error ? error.message : "unknown error"; }