feat(api): answer GET /api/health without a key (#10771)

Merged via merge-train (release/v3.8.50, batch1 2026-08-20) — static gates (typecheck/file-size/complexity/cognitive/changelog) green on the combined tree; test:unit reds observed in the boarded run were verified pre-existing on the pure release tip (unrelated flake), not caused by this PR. Thanks for the contribution!
This commit is contained in:
Dizzle
2026-08-20 11:29:45 +02:00
committed by GitHub
parent ee230fa93a
commit 49a47cbe6f
4 changed files with 94 additions and 1 deletions

View File

@@ -44,6 +44,14 @@ const PUBLIC_READONLY_API_ROUTE_PREFIXES = [
"/api/settings/require-login",
];
// Read-only routes public by EXACT path, never by prefix.
//
// `/api/health` has to be reachable without a key — a probe has none, and a 401 there is
// indistinguishable from a wrong key or a missing route. It cannot go in the prefix list
// above: `startsWith("/api/health")` would also expose `/api/health/degradation`, which is
// authenticated today.
const PUBLIC_READONLY_API_ROUTES_EXACT = new Set(["/api/health"]);
const PUBLIC_READONLY_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
const PUBLIC_CLOUD_API_ROUTES = [
@@ -76,7 +84,18 @@ export function isPublicApiRoute(pathname: string, method = "GET"): boolean {
return false;
}
for (const route of PUBLIC_READONLY_API_ROUTES_EXACT) {
if (pathMatchesExactRoute(pathname, route)) {
return true;
}
}
return PUBLIC_READONLY_API_ROUTE_PREFIXES.some((route) => pathname.startsWith(route));
}
export { PUBLIC_API_ROUTE_PREFIXES, PUBLIC_READONLY_API_ROUTE_PREFIXES, PUBLIC_READONLY_METHODS };
export {
PUBLIC_API_ROUTE_PREFIXES,
PUBLIC_READONLY_API_ROUTE_PREFIXES,
PUBLIC_READONLY_API_ROUTES_EXACT,
PUBLIC_READONLY_METHODS,
};