Security
Configure authentication and security schemes for your OpenAPI spec.
Security schemes in the spec
Pass securitySchemes to the generator to declare authentication methods:
const doc = generateOpenApiDocument(appRouter, {
// ...
securitySchemes: {
api_key: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'UUID',
description: 'API key authentication',
},
},
});This adds the scheme to components.securitySchemes and applies it to every operation.
Public endpoints
Use protect: false to exclude specific endpoints from security requirements:
t.procedure.meta({
openapi: {
method: 'GET',
path: '/health',
protect: false,
},
});Authentication in the handler
The handler itself doesn't enforce authentication — that's your middleware's job. The handler calls createContext with the request, and your tRPC middleware chain handles auth:
// Context factory — extract credentials
createOpenApiFetchHandler({
// ...
createContext: async ({ req }) => {
const token = req.headers.get('authorization')?.split(' ')[1];
const user = token ? await verifyToken(token) : null;
return { user };
},
});
// tRPC middleware — enforce auth
const authMiddleware = t.middleware(({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next({ ctx });
});This separation means the same auth logic works for both tRPC and REST calls.