AuthX turns FastAPI's JWT layer into a configurable authentication module
Ready-to-use and customizable Authentications and Oauth2 management for FastAPI ✨
At a glance
- What is it?
- A small MIT licensed library that adds token issuing, four token locations, refresh and freshness, a blocklist, an AuthManager for multi login types and a pluggable policy engine to a FastAPI application, with a companion package for Redis, caching and metrics.
- Who is it for?
- Adopt AuthX if you are building a FastAPI service that needs more than a bearer token check, for example refresh flows, revocation, several login types or scope policies, and you want that behaviour in one dependency rather than in your own middleware. Do not adopt it if a single bearer token dependency is all you need, since the basics are a few dozen lines of PyJWT, and do not treat its Beta status as incidental.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the library is for, and where it sits in a FastAPI app
AuthX is a Python package for FastAPI that adds authentication and authorization without asking you to write the middleware. The project describes itself as ready to use and customizable authentications and OAuth2 management for FastAPI, and the documentation site is at authx.yezz.me. The package metadata calls the licence MIT, requires Python 3.9 or newer, and marks the project as Development Status 4, Beta.
What you get is a configured object that owns the token lifecycle. You construct an AuthXConfig, hand it to an AuthX instance, register the instance's error handling on the app, and then ask for a dependency when you want a route protected. The token creation and the token verification are both methods on that object, so the signing key, the token locations and the policy settings live in one place rather than being spread across routers.
The dependency set explains where the work happens: FastAPI itself, PyJWT with the crypto extra for signing, Pydantic 2 and pydantic-settings for the configuration model, itsdangerous for signed values, python-dateutil and pytz for the time handling that token claims need, and uvicorn. That last one is unusual in a library, since a server is normally the application's own dependency, and it is worth noticing if you are packaging AuthX inside a service that pins its own ASGI server.
The declared FastAPI floor is 0.111.0, and the classifiers list Python 3.9 through 3.14, so the package is meant to work across a wide range of current FastAPI applications.
Installing it and wiring the first protected route
Installation is one pip command:
pip install authxThe quick start shows the whole shape of the integration, and it is short enough to read as a checklist. A config object carries the secret and the token locations, an AuthX instance is built from that config, the instance handles errors on the app, and routes use a dependency:
from fastapi import FastAPI, Depends, HTTPException
from authx import AuthX, AuthXConfig
app = FastAPI()
config = AuthXConfig(
JWT_SECRET_KEY="your-secret-key", # Change this!
JWT_TOKEN_LOCATION=["headers"],
)
auth = AuthX(config=config)
auth.handle_errors(app)
@app.post("/login")
def login(username: str, password: str):
if username == "test" and password == "test":
token = auth.create_access_token(uid=username)
return {"access_token": token}
raise HTTPException(401, detail="Invalid credentials")
@app.get("/protected", dependencies=[Depends(auth.access_token_required)])
def protected():
return {"message": "Hello World"}Two things stand out. The secret key is passed as a plain string, and the README's own comment says to change it, so the configuration surface exists but the example does not read it from the environment, even though pydantic-settings is a dependency and would allow that. The other is that the login route in the example does the credential check itself, with a hardcoded test password, so AuthX is not an identity store, it is the token machinery around whatever credential logic you already have.
The README then shows how to exercise it:
# Get a token
curl -X POST "http://localhost:8000/login?username=test&password=test"
# Access protected route
curl -H "Authorization: Bearer <your-token>" http://localhost:8000/protectedFour token locations, and why cookies need more care
The feature list is where the library earns its keep, and the first item is the set of places a token may be read from. AuthX supports headers, cookies, query parameters and the JSON body. The header case is the conventional bearer token, and the query parameter case is the pattern used by links that need a token attached without a JavaScript client.
Cookies are the interesting one, because the README marks them explicitly as coming with CSRF protection. That matters more than it first appears. A token in a header does not travel automatically with a browser request, so it is not attached to a cross-site request by default. A token in a cookie is attached automatically, which is convenient for a browser application and dangerous for exactly that reason unless the token is bound to something the attacker cannot supply, such as a double submit token or a same site policy. A library that puts cookies on the list without mentioning CSRF would be handing you a trap, and this one mentions it in the same sentence as the feature.
The set of locations is also a policy question rather than a technical one. Accepting a token from four places widens the surface an attacker can probe, and the more sources you accept, the more careful your logging and your refresh logic have to be. The configuration puts the list in one place, JWT_TOKEN_LOCATION, so tightening it later is a configuration change, and that is the right place for it to be.
Refresh, freshness and revocation: the parts a demo usually leaves out
Three features in the list are about token lifetime rather than token format, and they are the ones that decide whether an authentication system is usable in production.
Access and refresh token support means the library can issue a short lived access token and a longer lived one, and the client can trade the second for the first. Token freshness for sensitive operations is the idea that a token can be required to have been issued recently, so that changing a password or revoking a session takes effect for sensitive actions immediately rather than whenever the access token happens to expire. That is a small configuration flag with a large effect on how quickly a credential compromise can be contained.
The token blocklist, also described as revocation, is the third. It is the piece that a pure JWT design usually lacks, because a signed token is valid until it expires and there is no way to withdraw it early. A blocklist solves that by keeping revoked identifiers in a store and checking them on each verification, at the cost of that store becoming part of the request path and needing the same availability as your API. A Redis session store and cache are listed under the extra package rather than in the core, so read that package's documentation if you need shared state for revocation.
The AuthManager is described as built in for isolated multi-login-type applications, which reads as a way to keep several login mechanisms, for example a local password login and an external provider, from sharing a namespace of identifiers and state.
The policy engine and the extra package
The feature list describes a pluggable policy engine for scopes, attributes, environment checks and custom evaluators. That is the authorization half of the library, separated from the token half. Scopes are the familiar case, a permission string carried in the token. Attributes are a more expressive form, conditions on properties of the request or the subject. Environment checks mean the same rule can be allowed in one deployment and denied in another, which is how a policy can differ between development and production without a code change. Custom evaluators are the extension point for anything the built-in kinds do not cover.
The design point is that a policy engine is a separate concept from a decorator on a route. A dependency that only checks a token answers the question may this caller see this resource. A policy engine answers the question under what conditions may this caller do this thing, and lets you answer it once, in one place, with rules that can be tested without spinning up an HTTP request.
The extra features live in a separate distribution, authx-extra, installed with:
pip install authx-extraIt adds a Redis session store and cache, HTTP caching, performance profiling with pyinstrument, and Prometheus metrics. The split is sensible: the core stays small, and the operational pieces arrive only if you want them. It also means the blocklist and session state have a home when you need multi-process or multi-machine deployments, and that home is a separate dependency you have to choose to install.
Maintenance, licensing and where AuthX is the wrong choice
The project is active. The last push was on 2026-10-12, and the release line reached 1.7.1 on 2026-06-27 after 1.7.0 in June and 1.6.0 in April 2026. The documentation is built with mkdocs from the docs directory, the examples live in a separate package with their own pyproject.toml and lock file, and the root carries a uv.lock, so the project works with uv as well as pip. The CI setup in the badges is a full one, with a GitHub Actions workflow, pre-commit, Codecov, Ruff and a SonarCloud quality gate, and the contributor list is maintained with the all-contributors tool, with eighteen contributors named.
The licence is MIT, which is permissive and covers both use in closed source products and modification without any obligation to contribute back.
The wrong choice for many projects is the simplest case. If your service needs one bearer token on a handful of routes, the whole feature set is a few dozen lines of PyJWT plus a dependency, and a library that owns your secret key, your token locations and your policy configuration is more surface than you need. The cost of a configuration object is that it becomes the place where the security decisions live, and the cost of a policy engine is that you have to learn it before you can change a rule.
Two honest caveats remain. The package is marked Beta, and the README points to release notes for the changes, so the API is still moving. And the OAuth2 claim deserves reading carefully: the package description advertises OAuth2 management, while the documented features and the quick start are built on JWT access and refresh tokens with a configurable location. The OAuth2 flow itself is not shown in the README, which points to the documentation site, so if OAuth2 is the reason you are considering this library, read that documentation before you commit to it.
Editorial conclusion
Adopt AuthX if you are building a FastAPI service that needs more than a bearer token check, for example refresh flows, revocation, several login types or scope policies, and you want that behaviour in one dependency rather than in your own middleware. Do not adopt it if a single bearer token dependency is all you need, since the basics are a few dozen lines of PyJWT, and do not treat its Beta status as incidental. Verify first by reading how AuthXConfig is populated in your environment, since the quick start puts the JWT secret key in code, then by running the two curl commands from the README against your own instance before you rely on the refresh or blocklist paths.
Frequently asked questions
How do I install AuthX and protect a FastAPI route?
Install it with pip install authx, build an AuthXConfig with your secret and token locations, create the AuthX instance and call auth.handle_errors(app). Then add the dependency to the route, for example dependencies=[Depends(auth.access_token_required)], and issue tokens with auth.create_access_token.
Where can AuthX read the access token from?
Four locations are supported: headers as a bearer token, cookies, query parameters and the JSON body. Cookies come with CSRF protection, and the list of locations is set in the configuration through JWT_TOKEN_LOCATION, so it can be narrowed to headers only.
Does AuthX support refresh tokens and revoking a token before it expires?
Yes. The feature list includes access and refresh token support, token freshness for sensitive operations, and a token blocklist for revocation. The separate authx-extra package adds a Redis session store and cache.
What does the AuthX policy engine cover?
It is described as pluggable and handles scopes, attributes, environment checks and custom evaluators. That is the authorization side, separate from the token issuing and verification side, and it lets you write the same rule once rather than in every route decorator.
Is AuthX an OAuth2 server, and what is its development status?
The package description advertises ready to use authentications and OAuth2 management for FastAPI, while the README documents the JWT layer: access and refresh tokens, four token locations, freshness, blocklist, AuthManager and a policy engine. The OAuth2 flow is not shown in the README, which points to the documentation site. The project is classified as Development Status 4, Beta.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yezz123-authx)Was this useful?