fix(security): require auth for detailed health metadata#4715
Merged
Conversation
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
koala73
force-pushed
the
codex/health-details-require-api-key
branch
from
July 4, 2026 05:50
26e3c82 to
c3031fc
Compare
This was referenced Jul 5, 2026
koala73
added a commit
that referenced
this pull request
Jul 5, 2026
…support discovery + status advertisement fixes (#4867) Five external agent-journey runs (signup, pricing, developer-auth, support, integration intents) showed a clean split: intents answerable via the Link-header → .well-known → auth.md chain scored 90-100%, while pricing, signup, and support — discoverable only via llms.txt or nowhere — forced agents into slug-guessing, UA 403s, and misleading-200 SPA shells. Closes #4850 (signup journey): - llms.txt/llms-full.txt + auth.md: document the descriptive User-Agent policy (edge WAF challenges curl/*, python-requests/*, short UAs — and masks 404s as 403s for those UAs) - docs/accounts.mdx (+ nav): agent-facing account-creation guide — free tier needs no account; Clerk modal flow; MCP OAuth path for agents - vercel.json: 301 /blog/posts → /blog (posts live at /blog/posts/<slug>/, the parent had no index) Closes #4854 (pricing journey): - .well-known/api-catalog: RFC 9727 service-meta advertising pricing.md, the live product-catalog JSON, and support.md on the api context object - middleware.ts: /api/product-catalog joins PUBLIC_API_PATHS — the keyless read-only pricing catalog was UA-403'd for the exact agents it serves; robots.txt gets the matching Allow carve-out (llms.txt precedent) - docs/pricing.mdx (+ nav) with a drift guard test extracting prices from convex/config/productCatalog.ts source text (no generator import) - docs/openapi/CommerceService.openapi.yaml wired into the api-reference nav — placed OUTSIDE docs/api/ (that directory is generated: proto-check regen diff + injector scripts would clobber a hand-authored spec); kept out of the root openapi.json to respect the #4853 ~1MB size budget - docs.json redirects for the guessed slugs: plans/tiers → pricing, rate-limit(s) → usage-rate-limits, mcp-api-key → usage-auth - pricing.md: Limits & Overage section (hard 429 + Retry-After, no silent overage billing) + live JSON catalog pointer + UA note Closes #4856 (status advertisement, stale since #4715): - api-catalog status href + 3x vercel.json Link rel="status" now point at the keyless /api/health?compact=1 form - /api/health 401 carries WWW-Authenticate with RFC 9728 resource_metadata (RFC 7235 §3.1 made it mandatory; it was absent) and a body hint naming the public compact form - deploy-config guards: every advertised status URL must be the keyless compact form; service-meta entries pinned Closes #4857 (support journey): - public/support.md (root, sitemap-listed) + docs/support.mdx (+ nav): consolidated channels (support@/enterprise@, GitHub issues, Discord, status page, Turnstile form marked human-only) + explicit no-SLA statement per tier - vercel.json: /contact, /support, /help 301 → /docs/support (they served the misleading-200 dashboard SPA shell via the catch-all rewrite) - server-card.json documentation block: support repointed to /docs/support (was getting-started), pricing + productCatalog entries added Out of scope, noted: the Cloudflare-side WAF UA rule (dashboard config, not repo) and the root openapi info.description (generated + size-budgeted). Claude-Session: https://claude.ai/code/session_01N3xTXNUrCiy1xqy3VbkMRx
This was referenced Jul 5, 2026
koala73
added a commit
that referenced
this pull request
Jul 5, 2026
…p the anon 401-per-minute flood (#4902) (#4905) #4715 key-gated detailed /api/health (operator/enterprise only) but the dashboard client kept fetching it bare: every anonymous tab 401'd once a minute and the seed-health → data-freshness pipeline went silently dead. - Default the client to /api/health?compact=1 (public). `problems` carries the same per-check shape; mapped checks absent from it were evaluated server-side and found within budget, so synthesize OK-as-of-checkedAt (seedAgeMin 0 — an age-less update would leave lastUpdate null and calculateStatus reports no_data). - 401/403 → 15-min suppression window: one visible error per window per tab instead of one per tick if the endpoint ever gets re-gated (same caller-sweep flood class as #4865). - REDIS_DOWN 503 body-first handling unchanged (short-circuits before the compact branch server-side). Verified against live prod: 24 mapped sources hydrate, stale gdeltIntel maps very_stale, absent checks read fresh. Fixes #4902 Claude-Session: https://claude.ai/code/session_01YKrVoDp8TfEKLYXo83kPFV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Unauthenticated health probes can still check compact status, but they can no longer retrieve the full operational inventory of cache keys, record counts, and freshness thresholds. Detailed
/api/healthresponses and?history=1now require an operator/enterprise API key, while?compact=1remains public for UptimeRobot and keyword monitors.The endpoint also normalizes user-key gateway fallback failures to
Invalid API key, so standalone detailed-health auth does not expose internal validation plumbing. The docs now point public monitors at the compact URL and describe the keyed operator view explicitly.Validation
node --test tests/health-redis-down-status.test.mjs api/health-cors.test.mjsnpm run typecheck:apinpm run lint:mintlify-slugsnpm run lint:unicode:stagedgit push --force-with-leasepre-push guardrails passed, including full typecheck, API typecheck, Convex/CJS/unicode/boundary checks, safe HTML, rate-limit policy, premium-fetch parity, edge function bundle/tests, markdown lint, MDX lint, and version sync