JWT tokens, user management, refresh token rotation, and CSRF protection. One function call from zero to a fully authenticated FastAPI application.
Install
$ uv add bluefox-auth
Wire it up
from bluefox_core import BluefoxSettings, create_bluefox_app from bluefox_auth import BluefoxAuth settings = BluefoxSettings() app = create_bluefox_app(settings) BluefoxAuth(app, settings)
Protect a route
from fastapi import Depends from bluefox_auth import current_active_user, BluefoxUser @app.get("/dashboard") async def dashboard(user: BluefoxUser = Depends(current_active_user)): return {"message": f"Hello, {user.email}"}
Both Bearer header and HttpOnly cookies work out of the box. The right transport is auto-detected per request.
# Login and get tokens $ curl -X POST /auth/login \ -d '{"email": "user@example.com", "password": "..."}' # Use the access token $ curl /auth/me -H "Authorization: Bearer eyJhbG..."
// Login — cookies are set automatically await fetch("/auth/login", { method: "POST", credentials: "include", body: JSON.stringify({ email, password }), }); // Subsequent requests just work await fetch("/auth/me", { credentials: "include" });
Access and refresh tokens with jti, iat, and audience claims. Configurable expiry and algorithm.
Each refresh creates a new token in the same family. Replay a revoked token and the entire family is invalidated.
Plain double-submit cookie pattern for cookie transport. Bearer requests skip CSRF automatically.
bcrypt hashing with timing-safe verification. 72-byte limit enforced at the schema level. Dummy hash prevents enumeration.
Stateless one-time-use tokens via async email hook. Silent on unknown emails to prevent enumeration.
Stateless one-time-use tokens via async email hook. Short-circuits when already verified.
Provide async callback hooks and the endpoints light up. No hooks, no 500s — just a clean 501 until you're ready.
async def send_reset(email: str, token: str) -> None: url = f"https://app.example.com/reset?token={token}" await mailer.send(to=email, subject="Reset your password", body=url) async def send_verify(email: str, token: str) -> None: url = f"https://app.example.com/verify?token={token}" await mailer.send(to=email, subject="Verify your email", body=url) BluefoxAuth( app, settings, password_reset_send_fn=send_reset, email_verify_send_fn=send_verify, )