From 13446a217023e2fc3b13c21f206f75c71baae14c Mon Sep 17 00:00:00 2001 From: Elie Habib Date: Wed, 15 Apr 2026 15:34:38 +0400 Subject: [PATCH] fix(seed-contract-probe): send Origin header so /api/bootstrap boundary check doesn't 401 (#3100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(seed-contract-probe): send Origin header so /api/bootstrap boundary check doesn't 401 Production probe returned {boundary: [{endpoint: '/api/bootstrap', pass: false, status: 401, reason: 'status:401'}]}. Root cause: checkPublicBoundary's self-fetch had no Origin header, so /api/bootstrap's validateApiKey() treated it as a non-browser caller and required an API key. Fix: set Origin: https://worldmonitor.app on the boundary self-fetch. This takes the trusted-browser path without needing to embed an API key in the probe. The probe runs edge-side with x-probe-secret internal auth; emulating a trusted browser is only for boundary response-shape verification. Tests still 17/17. * fix(seed-contract-probe): explicit User-Agent on boundary self-fetch Per AGENTS.md, server-side fetches must include a UA. middleware.ts:138 returns 403 for !ua || ua.length < 10 on non-public paths, and /api/bootstrap is not in PUBLIC_API_PATHS — the probe works today only because Vercel Edge implicitly adds a UA. Making it explicit. Addresses greptile P2 on PR #3100. --- api/seed-contract-probe.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/api/seed-contract-probe.ts b/api/seed-contract-probe.ts index 71c51b32f..8ee24faf4 100644 --- a/api/seed-contract-probe.ts +++ b/api/seed-contract-probe.ts @@ -163,7 +163,18 @@ const BOUNDARY_CHECKS: BoundaryCheck[] = [ export async function checkPublicBoundary(origin: string): Promise { return Promise.all(BOUNDARY_CHECKS.map(async ({ endpoint, requireSourceHeader }): Promise => { try { - const r = await fetch(`${origin}${endpoint}`, { signal: AbortSignal.timeout(5_000) }); + // Send Origin of the canonical public host so endpoints that gate + // behind validateApiKey() (e.g. /api/bootstrap) take the trusted-browser + // branch instead of demanding an API key. The probe runs edge-side with + // internal auth; we intentionally emulate a trusted browser for boundary + // verification only. + const r = await fetch(`${origin}${endpoint}`, { + signal: AbortSignal.timeout(5_000), + headers: { + Origin: 'https://worldmonitor.app', + 'User-Agent': 'WorldMonitor-SeedContractProbe/1.0', + }, + }); const text = await r.text(); // Detect any envelope leak in the response body. A substring match on // the literal `"_seed":` is sufficient because `_seed` only appears on