feat: protect /docs and /redoc with API key

Adds middleware requiring X-Api-Key header or ?api_key= query param
to access Swagger UI and ReDoc. OpenAPI schema remains public.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-05-25 20:45:21 +00:00
parent 5d78d865a4
commit 98ad65d248
+17
View File
@@ -4,10 +4,14 @@ from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from src.backend.api.dependencies import limiter
from src.backend.config import settings
from src.backend.api.routes.health import router as health_router
from src.backend.api.routes.requests import router as requests_router
from src.backend.api.routes.sessions import router as sessions_router
@@ -41,6 +45,19 @@ app = FastAPI(
lifespan=lifespan,
)
PROTECTED_DOCS_PATHS = {"/docs", "/redoc"}
class DocsAuthMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
if request.url.path in PROTECTED_DOCS_PATHS:
key = request.headers.get("X-Api-Key") or request.query_params.get("api_key")
if key != settings.api_key:
return JSONResponse(status_code=403, content={"detail": "API key required"})
return await call_next(request)
app.add_middleware(DocsAuthMiddleware)
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)