Discovered during review of #2083.
Files:
packages/api/src/index.ts:27 (mount point)
packages/api/src/utils/openapi.ts (packratOpenApi setup)
@elysiajs/openapi is mounted before any auth plugins apply and has no exclude list. Every route in the app graph — including /api/admin/* and API-key-gated cron routes — is emitted to the public /openapi.json (and the Scalar UI). Unauthenticated enumeration exposes the admin surface and ETL/queue paths.
Fix options:
- Pass
exclude: [/^\/api\/admin/] to @elysiajs/openapi (plus any API-key-only patterns)
- Add
detail: { hide: true } on individual admin / API-key routes
- Gate
/openapi.json and /scalar behind the admin basic-auth guard, or an env flag (OPENAPI_PUBLIC=false in prod)
Option 1 is the cleanest; option 3 is defense-in-depth.
Also verify: no API-key or secret value is baked into route description / summary strings (spot-check the schema after fixing).
Related: #2083 (new OpenAPI surface introduced with the Elysia migration)
Discovered during review of #2083.
Files:
packages/api/src/index.ts:27(mount point)packages/api/src/utils/openapi.ts(packratOpenApisetup)@elysiajs/openapiis mounted before any auth plugins apply and has noexcludelist. Every route in the app graph — including/api/admin/*and API-key-gated cron routes — is emitted to the public/openapi.json(and the Scalar UI). Unauthenticated enumeration exposes the admin surface and ETL/queue paths.Fix options:
exclude: [/^\/api\/admin/]to@elysiajs/openapi(plus any API-key-only patterns)detail: { hide: true }on individual admin / API-key routes/openapi.jsonand/scalarbehind the admin basic-auth guard, or an env flag (OPENAPI_PUBLIC=falsein prod)Option 1 is the cleanest; option 3 is defense-in-depth.
Also verify: no API-key or secret value is baked into route
description/summarystrings (spot-check the schema after fixing).Related: #2083 (new OpenAPI surface introduced with the Elysia migration)