Problem
@fastify/swagger-ui is registered at /swagger with no authentication hook. In production, the full API schema — all endpoint paths, request/response shapes, and internal data model — is publicly visible to anyone without a login.
src/server/index.ts:
await fastify.register(fastifySwaggerUi, {
routePrefix: RoutePrefix.SWAGGER, // "/swagger"
uiConfig: { docExpansion: "full", deepLinking: false },
});
Options
Option A (recommended): Disable Swagger UI entirely in production — it's only useful for development:
if (!isProd) {
await fastify.register(fastifySwaggerUi, { routePrefix: RoutePrefix.SWAGGER, ... });
}
Option B: Gate Swagger UI behind COORDINATOR/ADMIN auth (more complex with @fastify/swagger-ui).
The @fastify/swagger spec itself (used for SDK contract at /swagger/json) can remain but should also be gated or removed in production since it exposes all route structures.
Context
Part of pre-NGO-onboarding security audit.
Problem
@fastify/swagger-uiis registered at/swaggerwith no authentication hook. In production, the full API schema — all endpoint paths, request/response shapes, and internal data model — is publicly visible to anyone without a login.src/server/index.ts:Options
Option A (recommended): Disable Swagger UI entirely in production — it's only useful for development:
Option B: Gate Swagger UI behind COORDINATOR/ADMIN auth (more complex with
@fastify/swagger-ui).The
@fastify/swaggerspec itself (used for SDK contract at/swagger/json) can remain but should also be gated or removed in production since it exposes all route structures.Context
Part of pre-NGO-onboarding security audit.