FastAPI Authentication & Authorization
FastAPI doesn't impose an authentication system. It provides security utilities that integrate with its dependency injection and OpenAPI docs. You declare a security scheme (OAuth2 bearer tokens, API keys, HTTP Basic), write a dependency that validates credentials and returns the current user, and then require that dependency on routes. The interactive docs gain an "Authorize" button automatically.
Most production APIs either validate tokens issued by an identity provider (Auth0, Keycloak, Entra ID, Cognito, Clerk, Supabase) or issue their own tokens for first-party clients. Either way, the durable principles are the same: validate tokens fully, authorize every request, including object-level ownership checks, and never roll your own crypto.
TL;DR
- Security schemes (
OAuth2PasswordBearer,HTTPBearer,APIKeyHeader) extract credentials and document them in OpenAPI. - A
get_current_userdependency validates the credential and returns a user, or raises 401. - For JWTs, verify signature, issuer, audience, and expiry, using the IdP's JWKS keys rather than a shared secret where possible.
- Enforce scopes and roles with dependencies (
Security(..., scopes=[...])) or checks that raise 403. - Object-level authorization (does this user own this order?) must happen in handlers or services, for every resource.
- Configure CORS narrowly, and hash passwords with Argon2 or bcrypt if you manage credentials yourself.
Quick Example
Validating access tokens from an OIDC identity provider, with scope checks:
Core Concepts
Security Schemes
FastAPI's fastapi.security module provides classes that both extract credentials and declare them in OpenAPI:
They return raw credentials; your dependency validates them.
Validating JWTs
A JWT access token is only trustworthy after verification:
- Signature: using the issuer's public keys (JWKS for RS256/ES256) or a shared secret (HS256, only for tokens you issue yourself).
- Algorithm allowlist: pass explicit
algorithms=[...], and never acceptnoneor algorithm switching. - Issuer (
iss) and audience (aud): tokens for other APIs must be rejected. - Expiry (
exp) and not-before (nbf), with a small leeway. - Then map claims (
sub,scope, roles, tenant) to your user model.
Cache JWKS keys, and refresh them on unknown key IDs to handle rotation. See JWT.
Issuing Your Own Tokens
For first-party apps without an external IdP, FastAPI's docs show the OAuth2 password flow: a /token endpoint verifies username and password and returns a signed JWT. Keep access tokens short-lived (5–15 minutes), use refresh tokens with rotation, and store passwords with Argon2 (via pwdlib or argon2-cffi) or bcrypt. For browser-based first-party apps, HttpOnly session cookies with CSRF protection are often simpler and safer than tokens in JavaScript. See authentication and password security.
Scopes, Roles, and Permissions
Security(dep, scopes=[...])declares required OAuth2 scopes. FastAPI aggregates scopes across the dependency tree intoSecurityScopesand documents them.- Role checks as reusable dependencies:
RequireRole("admin")raising 403. - Apply to whole routers (
APIRouter(dependencies=[Depends(require_admin)])) for admin areas.
Object-Level Authorization
Authentication tells you who; authorization must also answer may they access this specific resource? Filter queries by owner or tenant (WHERE customer_id = :user_id), or check ownership after loading. Return 404 for resources the user can't see, to avoid revealing their existence. This is the top API vulnerability, broken object-level authorization. See broken access control.
CORS
Browser frontends on other origins need CORS configured via CORSMiddleware: list explicit origins, allow credentials only when using cookies, and restrict methods and headers. allow_origins=["*"] with credentials is both invalid and dangerous.
Best Practices
Delegate Identity to a Provider
Let an IdP handle login, MFA, password resets, social login, and SSO. Your API validates tokens. That removes the most sensitive code from your application.
Make Authentication the Default
Apply the auth dependency at the router or app level and explicitly mark public endpoints, so new routes aren't accidentally left open.
Return Consistent 401 vs 403
401 means "not authenticated or invalid credentials" (include WWW-Authenticate); 403 means "authenticated but not allowed". Use 404 to hide resources the user may not know exist.
Test Authorization Paths
Write tests for missing tokens, expired or invalid tokens, insufficient scopes, and access to other users' resources, using dependency overrides for fast cases and real token validation for integration tests. See FastAPI testing.
Common Mistakes
Decoding JWTs Without Verifying
Always verify the signature and validate iss, aud, and exp with an explicit algorithm list.
Checking Authentication but Not Ownership
Scope the query by the user or tenant.
Long-Lived Tokens Without Revocation
Week-long access tokens can't be revoked quickly when a device is lost or an account compromised. Use short-lived access tokens with refresh tokens, or server-side sessions.
FAQ
How do I add authentication to FastAPI?
Create a dependency that extracts credentials with a security scheme (for example HTTPBearer), validates them (verifying a JWT or looking up a session or API key), and returns the user or raises 401. Then add it to endpoints or routers via Depends, or Security with scopes.
Should I build login myself or use an identity provider?
Use an identity provider for most applications. Login, MFA, account recovery, and SSO are security-critical and costly to build correctly. Build your own only for simple internal cases, using well-reviewed libraries for hashing and token handling.
Where should tokens be stored in the browser?
For first-party web apps, prefer HttpOnly, Secure, SameSite cookies (possibly via a backend-for-frontend), which JavaScript can't read. Tokens in localStorage are exposed to any XSS. Bearer tokens in memory suit SPAs with short-lived tokens and silent refresh.
How do I protect the interactive docs?
In production, disable them (docs_url=None, redoc_url=None, openapi_url=None), or serve them behind authentication or on an internal network, especially for private APIs.
Related Topics
- FastAPI — The framework overview
- FastAPI Dependencies — Auth as dependencies
- JWT — Token structure and validation
- OAuth — Flows and scopes
- Broken Access Control — Object-level authorization failures
- API Security — Broader API security practices