-
Notifications
You must be signed in to change notification settings - Fork 346
Open
Description
Context
When deploying FastAPI behind a reverse proxy (e.g., NGINX, Traefik, Caddy), several issues commonly arise:
- Incorrect scheme detection (
httpinstead ofhttps) - Redirect loops (especially trailing slash redirects)
- Broken OpenAPI docs URLs
- Misinterpreted client IP addresses
- Security header inconsistencies
- Inconsistent behavior between local and production environments
Reference: Official docs "Behind a Proxy - FastAPI"
Proposals
Disable Automatic Redirect Slashes
Proposal
app = FastAPI(redirect_slashes=False)
Why
FastAPI (via Starlette) automatically redirects:
/endpoint→/endpoint/- or
/endpoint/→/endpoint
Behind a proxy, this can cause:
- Scheme downgrades (HTTPS → HTTP)
- Infinite redirect loops
- Incorrect Location headers
Benefits
- Avoids proxy-related redirect issues
- Makes routes explicit and predictable
- Reduces 307/308 unnecessary redirects
- Cleaner behavior in containerized/proxy environments
Best Practice
Be explicit in route definitions:
@app.get("/users")
and ensure frontend uses exact paths on the clients SDK.
Proper Proxy Header Handling (CRITICAL)
Disabling redirect slashes alone is not enough.
Ensure proxy headers are trusted:
Run with:
fastapi run app.main:app --proxy-headers
or (if using uvicorn directly):
uvicorn app.main:app --proxy-headers --forwarded-allow-ips="*"
Why
Without this:
request.url.schememay be wrong- Generated OpenAPI docs may use
http - Redirects may downgrade HTTPS
This is mandatory behind TLS termination.
Adopt fastapi run Over uvicorn
Proposal
Standardize on:
fastapi run app.main:app
over:
uvicorn app.main:app
Why
fastapi run:
- Is the officially recommended entrypoint
- Provides better defaults
- Handles reload and production flags more clearly
- Reduces config drift between environments
Recommendation
- Use
fastapi devfor development - Use
fastapi runfor production - Avoid mixing CLI strategies across environments
Set Proper Referrer Policy
Proposal
Add response header:
Referrer-Policy: strict-origin-when-cross-origin
(or if you truly need same-origin only)
Referrer-Policy: same-origin
Recommended Value
strict-origin-when-cross-origin
Why
It:
- Sends full referrer for same-origin
- Sends only origin for HTTPS cross-origin
- Sends nothing for HTTP downgrade
- Is modern browser default
- Protects sensitive paths
Reverse Proxy Configuration
NGINX Example
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
Without these:
- HTTPS detection fails
- Client IP is lost
- URL generation breaks
Set root_path If Behind Subpath
If your app is served at: https://example.com/api
Use:
API_ROOT_PATH = os.environ.get("LLM_PROVIDER", "/api")
app = FastAPI(root_path=API_ROOT_PATH)
Or configure via proxy properly.
Otherwise:
- OpenAPI docs break
- Swagger UI fails
- Static URLs mismatch
Recommended Deployment Baseline
FastAPI App
app = FastAPI(
redirect_slashes=False,
)
Run Command
fastapi run app.main:app --proxy-headers
Proxy Must Set
X-Forwarded-ProtoX-Forwarded-ForHost
Security Headers
- Referrer-Policy
- X-Content-Type-Options
- X-Frame-Options
- Strict-Transport-Security (if HTTPS)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels