Today PROJECT_API_KEY_PERMISSION_CATALOG (apps/apollo/src/lib/apiKeys/project_api_key_permissions/catalog.ts) is a standalone route list that must be kept in sync with the real route registrations by hand. PLEN-2623 showed the failure mode: the whole MCP surface, files routes, and realtime routes shipped without catalog entries, so scoped keys failed closed on them for months (21.7k denials / 110+ orgs in 14d before the fix).
Proposal to investigate: declare the required permission preset where the route is registered — e.g. a scopedKeyPermission: { preset: "sessions", access: "write" } option on createAuthRoute / the Hono router builders (and an equivalent for App Router routes like the MCP transport). The catalog then gets derived from route registrations instead of maintained separately, so a new developer-facing route physically cannot ship uncataloged — the author has to either declare a preset or explicitly mark it scoped-key-inaccessible.
Things to figure out:
- App Router routes (MCP transport, tool-router MCP) do not go through createAuthRoute — they pass literal route templates to auth middleware; need a story for those
- Lint rule vs runtime derivation: a custom oxlint rule requiring the option on every PROJECT_API_KEY route may be the cheap 80% version
- Keep the dashboard catalog-items endpoint working (labels/descriptions/accessLevels currently live on the catalog entries)
- Migration: existing catalog stays the source of truth until parity is proven (compare derived vs static in a unit test)