# 05 — API SURFACE + AUTH MATRIX Generated 2026-07-21 · prod arm64-a8595e555c2d · regenerated from live code > snapshot 2026-07-21 · regenerated live. Scope: every `src/app/api/**/route.ts` (**427 routes**). Next.js App Router, **no global `middleware.ts`** — every route self-guards. Classes below are grep-derived from the route source; the **exhaustive machine-readable route→methods→authClass list is in `passport.json`** (baseline for route-diffs via `refresh.sh`). > ⚠ **SOURCE ↔ PROD DRIFT.** This is derived from the M1 SOURCE tree (behind live). A route flagged public/unauthed here may already be hardened on prod — cross-check the SEC-* status in 06 and curl live per 09 before trusting it. ## Detected auth-class distribution (live, 427 routes) | authClass (detector) | Count | Maps to legend | |---|---|---| | `session` | 300 | AUTHN / AUTHZ (`auth()`/`getServerSession`/`session.user`) | | `public/unauthed` | 71 | PUBLIC (by-design) **or** REVIEW (sensitive) — split below | | `admin` | 30 | ADMIN (`requireAdmin`/`isAdmin`/`ADMIN_EMAILS`) | | `webhook-sig` | 9 | WEBHOOK (sig/secret verify) | | `cron-secret` | 9 | CRON (`CRON_SECRET`) | | `key` | 5 | KEY (accessCode/apiKey/bearer) | | `token` | 3 | TOKEN (path/magic token) | Detection is grep-based: `session` covers both AUTHN and ownership-scoped AUTHZ (ownership is enforced inline via `where:{ id, userId }`, not a shared helper). Webhook/token counts under-report — some webhook routes (e.g. `telegram/webhook`) verify a secret in `lib` and fall to `public/unauthed` here; verify in code. --- ## ⚠ REVIEW — public/unauthed on a sensitive/mutating surface (audit first) Grep found no session/admin/sig/cron/token guard in the **route file**. Many have a SEC ticket already Deployed/Accepted on prod (source drift) — cross-check status. | Route | Methods | SEC ref / note | |---|---|---| | `video/pipeline/run/[runId]` | GET,POST | SEC-0241/0242 IDOR+cred-abuse (Owner Accepted — fixed live) | | `video/pipeline/run/[runId]/cancel` | POST | SEC-0248 (Rejected by Lead) | | `video/pipeline/run/[runId]/export` | GET | SEC-0243 IDOR exfil (Owner Accepted) | | `video/pipeline/run/[runId]/retry` | (POST re-export) | SEC-0242 | | `video/pipeline/run/[runId]/stream` | GET | SEC-0263 SSE IDOR (Rejected by Lead) | | `video/pipeline/download/[runId]` | (GET re-export) | SEC-0243 | | `media/tiktok/{resolve,author/collect,helper/find,helper/ping}` | GET,POST | SEC-0292 SSRF-resolve / SEC-0302 media-import unauth RAG-write | | `media/youtube/check` | POST | SEC-0302 | | `tasks/extract` | GET,POST | SEC-DEF-UNGATED-COMPUTE (Deployed live) | | `gardener/{cleanup,conflicts,health,stacks,stats}` | GET,POST | SEC-DEF-UNGATED-COMPUTE (Deployed live) | | `writing-actions` | GET | ungated (cf. `admin/writing-actions` = ADMIN) | | `challenges/{start,submit,evaluate}` | POST | game, no auth | ## PUBLIC by design (expected open) - **Auth/onboarding:** `auth/[...nextauth]`, `auth/register`, `auth/login-rate-limit`, `auth/magic-login` (TOKEN), `auth/verify-email` (TOKEN), `eu-waitlist`, `profile/agent-email/confirm` (TOKEN). - **Health/infra:** `health`, `db/health`, `ops/live-sha`, `metrics/system`. - **Catalogs/i18n:** `i18n/{full,scoped,keys}`, `image-models/openrouter`, `models/*`. - **Embed widget** (embed-guard token + OPTIONS/CORS): `embed/{bootstrap,assets/[name],widget,realtime,session,chat,voice-turn,simplify,transcribe,share/[id]/bootstrap}`. - **Public media/links:** `media/[filename]` (path-traversal fixed SEC-0249), `s/[token]` (shortlink, boundary SEC-0285). - **OAuth connector start/callback:** `integrations/{dropbox,google,notion,onedrive}/auth`, `integrations/google/status`. - **Connect/guest:** `connect/[slug]`, `connect/[slug]/activate`. - **Meeting-room info:** `meeting-rooms/v1/{browser-media-readiness,runtime-boundary}`; `video/pipeline/capabilities`. ## WEBHOOK / CRON / TOKEN / KEY / INTERNAL - **WEBHOOK (sig/secret):** `billing/webhook` (Stripe `constructEvent`), `video/pipeline/ingest/webhook` (`verifyCloudWebhookSignature`), `slack/command` (sig, fail-closed SEC-0300), `telegram/webhook` + `messenger/v1/telegram/webhook` (secret + `verifyTelegramScopedAccessCode`), `whatsapp/webhook`, `webhooks/telnyx/{voice,messaging}`, `pstn/v1/telnyx-outbound-events`, `email/webhook`. - **CRON (`CRON_SECRET`, `?secret=` compat):** `cron/{process-tasks,topic-stats,watchdog,process-scheduled-posts,update-engagement,process-messages,entity-resolution}`. - **KEY / TOKEN:** `clipper`, `transcribe`, `scan/*`, `vision`, `completion` (KEY, cost-gated per SEC-026x); `telephony/v1/provision/[token]`, `s/[token]`, `connect/[slug]`. - **INTERNAL (guard in `lib/telephony/runtime` — verify there, Codex zone):** `telephony/v1/sessions/{start,[...path],verify-pin,owner-callback/telegram}`, `telephony/v1/pstn/route/[e164]` (IP-allowlist by design), `signal-call/v1/*`, `telegram-call/v1/*`, `whatsapp-call/v1/*`. ## ADMIN (30 routes) `admin/{config,settings,runtime-target,embed-public-host,messaging/*,messenger/events,reports/*,takedown,telephony/*,users/[id]/suspend,writing-actions,agents,playwright,lighthouse*,social/credentials,set-tier,…}`. Note SEC-0295/0296/0297 (agents/playwright/lighthouse auth-bypass) and SEC-0260 (set-tier priv-esc) — all Deployed/Accepted on prod; SEC-0308 adds an `/api/admin/**` middleware + ESLint `requireAdmin` guard. --- ### Counts (live) 427 routes · session 300 · public/unauthed 71 (≈12 REVIEW-sensitive + ≈59 by-design) · admin 30 · webhook-sig 9 · cron-secret 9 · key 5 · token 3. Re-verify any REVIEW row live (09) and any INTERNAL row (guard lives in `lib`) before relying on it.