
Security News
Software Engineering Daily Podcast: Feross on AI, Open Source, and Supply Chain Risk
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.
auth0-fastapi-api
Advanced tools

📚 Documentation - 🚀 Getting Started - 💬 Feedback
This library requires Python 3.9+.
pip install auth0-fastapi-api
If you’re using Poetry:
poetry install auth0-fastapi-api
In your FastAPI application, create an instance of the Auth0FastAPI class. Supply the domain and audience from Auth0:
AUTH0_DOMAIN can be obtained from the Auth0 Dashboard once you've created an API.AUTH0_AUDIENCE is the identifier of the API that is being called. You can find this in the API section of the Auth0 dashboard.from fastapi_plugin.fast_api_client import Auth0FastAPI
# Create the Auth0 integration
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
)
The SDK supports DPoP (Demonstrating Proof-of-Possession) for enhanced security:
# Mixed mode - accepts both Bearer and DPoP (recommended for migration)
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True, # Enable DPoP support
dpop_required=False # Allow Bearer tokens too (mixed mode)
)
# DPoP-only mode - rejects Bearer tokens
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True,
dpop_required=True # Only accept DPoP tokens
)
# Custom DPoP timing configuration
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True,
dpop_iat_leeway=30, # Clock skew tolerance (seconds)
dpop_iat_offset=300 # Maximum DPoP proof age (seconds)
)
When deploying behind a reverse proxy (nginx, AWS ALB, etc.), you must enable proxy trust for DPoP validation to work correctly:
from fastapi import FastAPI
from fastapi_plugin.fast_api_client import Auth0FastAPI
app = FastAPI()
# CRITICAL: Enable proxy trust when behind a reverse proxy
app.state.trust_proxy = True
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True
)
Why this matters:
http://localhost:8000/api)https://api.example.com/api)trust_proxy=True, validation will failNote: Only enable trust_proxy=True when your app is actually behind a trusted reverse proxy. Never enable this for direct internet-facing deployments, as it would allow header injection attacks.
Nginx Configuration Example:
location /api {
proxy_pass http://backend:8000;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /api;
}
To protect a FastAPI route, use the require_auth(...) dependency. The SDK automatically detects and validates both Bearer and DPoP authentication schemes. Any incoming requests must include a valid token in the Authorization header, or they will receive an error response (e.g., 401 Unauthorized).
@app.get("/protected-api")
async def protected(
# The route depends on require_auth returning the decoded token claims
claims: dict = Depends(auth0.require_auth())
):
# `claims` is the verified JWT payload (dict) extracted by the SDK
return {"message": f"Hello, {claims['sub']}"}
Bearer Authentication:
Authorization: Bearer <JWT>.iss, aud, exp, etc.DPoP Authentication:
Authorization: DPoP <JWT> and DPoP: <proof-jwt> headers.The SDK automatically detects which authentication scheme is being used and validates accordingly.
[!IMPORTANT]
This method protects API endpoints using bearer tokens. It does not create or manage user sessions in server-side rendering scenarios. For session-based usage, consider a separate library or approach.
If your tokens have additional custom claims, you’ll see them in the claims dictionary. For example:
@app.get("/custom")
async def custom_claims_route(claims: dict = Depends(auth0.require_auth())):
# Suppose your JWT includes { "permissions": ["read:data"] }
permissions = claims.get("permissions", [])
return {"permissions": permissions}
You can parse or validate these claims however you like in your application code.
In case you don't need to use the claims dictionary in your endpoint you can also use the dependency as part of the path decorator. For example:
@app.get("/protected", dependencies=[Depends(auth0.require_auth())])
async def protected():
# Protected endpoint
return {"msg": "You need to have an access token to see this endpoint."}
This way you can protected your endpoint and not have an unused variable.
read:data), call require_auth(scopes="read:data") or pass a list of scopes. The SDK will return a 403 if the token lacks those scopes in its scope claim.@app.get("/read-data")
async def read_data_route(
claims=Depends(auth0.require_auth(scopes="read:data"))
):
return {"data": "secret info"}
pytest-httpx or patch the verification method to avoid real cryptographic checks.from fastapi import FastAPI, Depends
from auth0_fastapi_api import Auth0FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
auth0 = Auth0FastAPI(domain="my-tenant.us.auth0.com", audience="my-api")
@app.get("/public")
async def public():
return {"message": "No token required here"}
@app.get("/secure")
async def secure_route(
claims: dict = Depends(auth0.require_auth(scopes="read:secure"))
):
# claims might contain {"sub":"user123","scope":"read:secure"}
return {"message": f"Hello {claims['sub']}, you have read:secure scope!"}
# Example test
def test_public_route():
client = TestClient(app)
response = client.get("/public")
assert response.status_code == 200
assert response.json() == {"message": "No token required here"}
Note: DPoP is currently in Early Access. Contact Auth0 support to enable it for your tenant.
DPoP (Demonstrating Proof-of-Possession) provides enhanced security by binding access tokens to cryptographic proof of possession.
To use DPoP authentication, clients must:
Authorization: DPoP <access-token> - The DPoP-bound access tokenDPoP: <proof-jwt> - The DPoP proof JWTGET /protected-api HTTP/1.1
Host: api.example.com
Authorization: DPoP eyJ0eXAiOiJKV1Q...
DPoP: eyJ0eXAiOiJkcG9wK2p3dC...
Use mixed mode for gradual migration:
# Start with mixed mode to support both Bearer and DPoP
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True,
dpop_required=False # Allows both Bearer and DPoP
)
# Later, enforce DPoP-only
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_required=True # Rejects Bearer tokens
)
If you need to get an access token for an upstream idp via a connection, you can use the get_access_token_for_connection method on the underlying api_client:
import asyncio
from fastapi_plugin.fast_api_client import Auth0FastAPI
async def main():
auth0 = Auth0FastAPI(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
client_id="<AUTH0_CLIENT_ID>",
client_secret="<AUTH0_CLIENT_SECRET>",
)
connection = "my-connection" # The Auth0 connection to the upstream idp
access_token = "..." # The Auth0 access token to exchange
connection_access_token = await auth0.api_client.get_access_token_for_connection({"connection": connection, "access_token": access_token})
# The returned token is the access token for the upstream idp
print(connection_access_token)
asyncio.run(main())
More info https://auth0.com/docs/secure/tokens/token-vault
We appreciate feedback and contribution to this repo! Before you get started, please read the following:
To provide feedback or report a bug, please raise an issue on our issue tracker.
Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.
Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?
This project is licensed under the MIT license. See the LICENSE file for more info.
FAQs
SDK for verifying access tokens and securing APIs with Auth0, using Authlib.
We found that auth0-fastapi-api demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.

Security News
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.