
Security News
OWASP 2025 Top 10 Adds Software Supply Chain Failures, Ranked Top Community Concern
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.
auth0-api-python
Advanced tools
The auth0-api-python library allows you to secure APIs running on Python, particularly for verifying Auth0-issued access tokens.
It’s intended as a foundation for building more framework-specific integrations (e.g., with FastAPI, Django, etc.), but you can also use it directly in any Python server-side environment.
📚 Documentation - 🚀 Getting Started - 💬 Feedback
This SDK provides comprehensive support for securing APIs with Auth0-issued access tokens:
verify_request() - automatically detects and validates Bearer or DPoP schemesThis library is part of Auth0's Python ecosystem for server-side authentication and API security. Related SDKs:
@auth0/auth0-auth-js - Core authentication client (low-level primitives)@auth0/auth0-api-js - Server-side API security (Node.js equivalent of this library)@auth0/auth0-server-js - Server-side web app authentication (session management)This library requires Python 3.9+.
pip install auth0-api-python
If you’re using Poetry:
poetry install auth0-api-python
Create an instance of the ApiClient. This instance will be imported and used anywhere we need access to the methods.
from auth0_api_python import ApiClient, ApiClientOptions
api_client = ApiClient(ApiClientOptions(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>"
))
AUTH0_DOMAIN can be obtained from the Auth0 Dashboard once you've created an application.AUTH0_AUDIENCE is the identifier of the API. You can find this in the APIs section of the Auth0 Dashboard.Use the verify_access_token method to validate access tokens. The method automatically checks critical claims like iss, aud, exp, nbf.
import asyncio
from auth0_api_python import ApiClient, ApiClientOptions
async def main():
api_client = ApiClient(ApiClientOptions(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>"
))
access_token = "..."
decoded_and_verified_token = await api_client.verify_access_token(access_token=access_token)
print(decoded_and_verified_token)
asyncio.run(main())
In this example, the returned dictionary contains the decoded claims (like sub, scope, etc.) from the verified token.
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:
import asyncio
from auth0_api_python import ApiClient, ApiClientOptions
async def main():
api_client = ApiClient(ApiClientOptions(
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 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
[!NOTE] This feature is currently available in Early Access for Enterprise customers. Please reach out to Auth0 support to get it enabled for your tenant.
This feature requires a confidential client (both client_id and client_secret must be configured).
Custom Token Exchange allows you to exchange a subject token for Auth0 tokens using RFC 8693. This is useful for:
import asyncio
from auth0_api_python import ApiClient, ApiClientOptions
async def main():
api_client = ApiClient(ApiClientOptions(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
client_id="<AUTH0_CLIENT_ID>",
client_secret="<AUTH0_CLIENT_SECRET>",
timeout=10.0 # Optional: HTTP timeout in seconds (default: 10.0)
))
subject_token = "..." # Token from your legacy system or external source
result = await api_client.get_token_by_exchange_profile(
subject_token=subject_token,
subject_token_type="urn:example:subject-token",
audience="https://api.example.com", # Optional - omit if your Action or tenant configuration sets the audience
scope="openid profile email", # Optional
requested_token_type="urn:ietf:params:oauth:token-type:access_token" # Optional
)
# Result contains access_token, expires_in, expires_at
# id_token, refresh_token, and scope are profile/Action dependent (not guaranteed; scope may be empty)
asyncio.run(main())
Important:
client_id/client_secret), not in the form body.subject_token with "Bearer " - send the raw token value only (checked case-insensitively).subject_token_type must match a Token Exchange Profile configured in Auth0. This URI identifies which profile will process the exchange and must not use reserved OAuth namespaces (IETF or vendor-controlled). Use your own collision-resistant namespace. See the Custom Token Exchange documentation for naming guidance.audience nor tenant/Action logic sets it, you may receive a token not targeted at your API.You can pass additional parameters for your Token Exchange Profile or Actions via the extra parameter. These are sent as form fields to Auth0 and may be inspected by Actions:
result = await api_client.get_token_by_exchange_profile(
subject_token=subject_token,
subject_token_type="urn:example:subject-token",
audience="https://api.example.com",
extra={
"device_id": "device-12345",
"session_id": "sess-abc"
}
)
[!WARNING] Extra parameters are sent as form fields and may appear in logs. Do not include secrets or sensitive data. Reserved OAuth parameter names (like
grant_type,client_id,scope) cannot be used and will raise an error. Arrays are supported but limited to 20 values per key to prevent abuse.
from auth0_api_python import GetTokenByExchangeProfileError, ApiError
try:
result = await api_client.get_token_by_exchange_profile(
subject_token=subject_token,
subject_token_type="urn:example:subject-token"
)
except GetTokenByExchangeProfileError as e:
# Validation errors (invalid token format, missing credentials, reserved params, etc.)
print(f"Validation error: {e}")
except ApiError as e:
# Token endpoint errors (invalid_grant, network issues, malformed responses, etc.)
print(f"API error: {e.code} - {e.message} (status: {e.status_code})")
Related SDKs: auth0-auth-js (see @auth0/auth0-api-js package for Node.js equivalent)
More info: https://auth0.com/docs/authenticate/custom-token-exchange
If your application demands extra claims, specify them with required_claims:
decoded_and_verified_token = await api_client.verify_access_token(
access_token=access_token,
required_claims=["my_custom_claim"]
)
If the token lacks my_custom_claim or fails any standard check (issuer mismatch, expired token, invalid signature), the method raises a VerifyAccessTokenError.
[!NOTE]
This feature is currently available in Early Access. Please reach out to Auth0 support to get it enabled for your tenant.
This library supports DPoP (Demonstrating Proof-of-Possession) for enhanced security, allowing clients to prove possession of private keys bound to access tokens.
Accepts both Bearer and DPoP tokens - ideal for gradual migration:
api_client = ApiClient(ApiClientOptions(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True, # Default - enables DPoP support
dpop_required=False # Default - allows both Bearer and DPoP
))
# Use verify_request() for automatic scheme detection
result = await api_client.verify_request(
headers={
"authorization": "DPoP eyJ0eXAiOiJKV1Q...", # DPoP scheme
"dpop": "eyJ0eXAiOiJkcG9wK2p3dC...", # DPoP proof
},
http_method="GET",
http_url="https://api.example.com/resource"
)
Enforces DPoP-only authentication, rejecting Bearer tokens:
api_client = ApiClient(ApiClientOptions(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_required=True # Rejects Bearer tokens
))
api_client = ApiClient(ApiClientOptions(
domain="<AUTH0_DOMAIN>",
audience="<AUTH0_AUDIENCE>",
dpop_enabled=True, # Enable/disable DPoP support
dpop_required=False, # Require DPoP (reject Bearer)
dpop_iat_leeway=30, # Clock skew tolerance (seconds)
dpop_iat_offset=300, # Maximum proof age (seconds)
))
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-api-python 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
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.