Files
OpenSquawk/server/utils/serviceAuth.ts
leubeem 1d09a9fc2f feat(pm): LLM routing endpoint, usage capture, and admin review view
Backend counterpart to the Python engine's semantic router.

- POST /api/decision/route: service-secret-guarded endpoint the Python
  backend calls on regex-miss. Calls gpt-5-mini (ROUTER_LLM_MODEL),
  validates the chosen id against the candidate set, and writes both a
  UsageEvent (central cost ledger) and a routing-review record — including
  timeouts, with timeoutMs + actual latencyMs — so the budget can be tuned
- LlmRoutingDecision model + GET /api/admin/llm-routing (paginated,
  status-filtered, per-status counts)
- admin "LLM Routing" tab: transcript vs expected phrase, candidate chips
  with the chosen one highlighted, latency/budget chip, model reason
- serviceAuth util (mirrors CRON_SECRET pattern)
- .env.example: ROUTER_LLM_MODEL, SERVICE_SECRET

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 10:27:57 +02:00

33 lines
1.1 KiB
TypeScript

import type { H3Event } from 'h3'
import { createError, getHeader } from 'h3'
let warnedMissingSecret = false
/**
* Guards internal server-to-server endpoints (e.g. the Python decision backend
* calling back into Nuxt). The secret is read from SERVICE_SECRET and must be
* supplied via the `x-service-secret` header.
*
* Fail closed: if no secret is configured the endpoint refuses to run (503)
* rather than being publicly callable.
*/
export function requireServiceSecret(event: H3Event) {
const secret = (process.env.SERVICE_SECRET || '').trim()
if (!secret) {
if (!warnedMissingSecret) {
console.error(
'[service] SERVICE_SECRET is not set — internal endpoints are disabled (503). ' +
'Set SERVICE_SECRET and pass it via the x-service-secret header.',
)
warnedMissingSecret = true
}
throw createError({ statusCode: 503, statusMessage: 'Service endpoint is not configured.' })
}
const provided = (getHeader(event, 'x-service-secret') || '').trim()
if (provided !== secret) {
throw createError({ statusCode: 401, statusMessage: 'Invalid service secret.' })
}
}