Skip to main content

Pluggable authentication framework for FastAPI.

Project description

Aura Auth

Batteries-included authentication for FastAPI — install, wire three lines, ship.

Python 3.11+ FastAPI License

Early beta — APIs, module layout, and defaults may change without a major-version bump while we learn from real apps. Pin versions in production and read the release notes when upgrading.


Why this exists

If you have built auth in Python, you have probably felt the same friction:

  • “Batteries included” rarely means “works on Monday.” You still glue together hashing, sessions or JWTs, a user model, migrations, login routes, dependency injection, and error shapes — often from blog posts that disagree with each other.
  • Frameworks tend to stop at the tutorial. The happy path is documented; edge cases, transport choices (cookie vs bearer), and clean extension points are left as an exercise.
  • Teams get discouraged and either ship something fragile, over-buy a SaaS, or copy-paste security-sensitive code they do not fully own.

Aura Auth is an attempt to fix that for the FastAPI + async SQLAlchemy lane: a small, explicit library where the default install gives you email/password auth that actually runs — identity and credential accounts, server-side sessions, models you can extend, and a ready-made router — while optional extras stay pluggable (OAuth, magic links, OTP, 2FA, passkeys, etc.) as the project grows.

We are not trying to be every auth product at once on day one. We are trying to be the library you reach for when you want clarity, defaults that work, and a path to more without rewriting your app.


What you get today (default install)

Capability Notes
Account-based data model User (identity) + Account (how you sign in, e.g. provider_id="credential" with bcrypt hash) + Session + Verification
Mixins + defaults UserMixin, AccountMixin, SessionMixin, VerificationMixin; DefaultUser / DefaultAccount / DefaultSession / DefaultVerification for zero-config
Async SQLAlchemy backend CRUD for all four entities with sensible errors (e.g. duplicate email)
Password strategy Register creates user + credential account; login verifies password on that account
Opaque session tokens Stored in sessions (revocable, listable); transported via Bearer or cookie — not a stateless login JWT
Security helpers PasswordHelper, TokenHelper (JWT for future or custom flows), generate_random_token / generate_session_token
UserManager Register, login, session resolution, logout, list/revoke sessions, email verification rows
FastAPI integration AuraAuth, init_app, configurable route_prefix, raw_router, dependencies

Optional installs (see pyproject.toml[project.optional-dependencies]) add OAuth (google, github, facebook, oauth), magic-link, 2fa, passkey, sqlmodel, admin, postgres, mysql, and an all extra.


Installation

Requires Python 3.11+. email-validator is included so Pydantic EmailStr works out of the box.

From PyPI (once the package is published):

uv add aura-auth
# or
pip install aura-auth

From GitHub (typical during early beta):

uv add "aura-auth @ git+https://github.com/YOUR_ORG/aura-auth.git"
# or
pip install "git+https://github.com/YOUR_ORG/aura-auth.git"

Replace YOUR_ORG/aura-auth with your real repository path. For local development, use uv pip install -e . from a clone of this repo.


Quickstart (copy-paste)

Minimal FastAPI app: create tables on startup, mount auth, protect a route.

from fastapi import Depends, FastAPI

from aura_auth import AuraAuth

app = FastAPI()

# `secret` is required on the config surface today (signing / future JWT flows).
auth = AuraAuth(
    database_url="sqlite+aiosqlite:///./app.db",
    secret="change-me-to-a-long-random-secret-at-least-32-chars",
)


@app.on_event("startup")
async def startup() -> None:
    await auth.create_tables()


auth.init_app(app)  # registers /auth routes + exception handlers


@app.get("/protected")
async def protected(user=Depends(auth.current_user())):
    return {"message": f"Hello, {user.name}"}

Default response shape for register and login (AuthResponse): JSON includes user (profile) and session (id, token, expires_at). Send Authorization: Bearer <session.token> (or rely on the cookie when cookie_transport=True).

Endpoints under route_prefix (default /auth):

Method Path Purpose
POST /auth/register Body: name, email, password201 + AuthResponse; sets session cookie if configured
POST /auth/login Body: email, passwordAuthResponse; sets session cookie if configured
POST /auth/logout Revokes the current session; clears cookie when using cookie transport
GET /auth/me Current user (UserRead); requires session token
GET /auth/sessions Lists your non-expired sessions
DELETE /auth/sessions/{session_id} Revokes one of your sessions (204 on success)

Custom URL prefix (for example /api/v1/auth):

auth = AuraAuth(
    database_url="sqlite+aiosqlite:///./app.db",
    secret="...",
    route_prefix="/api/v1/auth",
)

Mount routes yourself (full control over path):

app.include_router(auth.raw_router, prefix="/identity")

Dependencies you can attach to routes:

  • Depends(auth.current_user()) — must be authenticated (401 otherwise)
  • Depends(auth.current_verified_user()) — must have email_verified (403 otherwise)

Mental model (for humans and AI coding agents)

Think in four layers plus four tables. Everything else hangs off these names in the repo.

flowchart LR
  subgraph transport [Transport]
    T[Bearer / Cookie]
  end
  subgraph strategy [Strategy]
    S[Password — more later]
  end
  subgraph backend [Backend]
    B[SQLAlchemy async CRUD]
  end
  subgraph data [Data]
    U[User]
    A[Account]
    SE[Session]
    V[Verification]
  end
  T <--> SE
  S <--> A
  B <--> U
  B <--> A
  B <--> SE
  B <--> V
Layer Role Main entry points in code
Transport How the session token is read/written on HTTP aura_auth.transport.*
Strategy How credentials map to a user + hooks aura_auth.strategies.password
Backend Persistence implementing BackendProtocol aura_auth.backend.sqlalchemy
Orchestration Wires pieces together for apps aura_auth.app.AuraAuth, aura_auth.manager.UserManager

Contracts (types, protocols, schemas, exceptions, security helpers) live under aura_auth._core. Routers and FastAPI dependencies live under aura_auth.router and aura_auth.dependencies.

If you are an AI agent implementing or extending this library:

  1. Read AGENTS.md in this repo — phased plan, folder target, and conventions (imports, docstrings, testing layout). Some phase text may predate the account/session architecture; trust the source tree and this README for the current shape.
  2. Prefer protocols in _core over importing concrete backends from “higher” layers — keeps cycles and coupling down.
  3. Run make check (or uv run ruff check ., uv run ty check, uv run pytest) before proposing a PR-style change.

Configuration highlights

AuraAuth(database_url=..., secret=..., **kwargs) forwards supported keys to AuraAuthConfig (aura_auth._core.config), including:

  • route_prefix — URL prefix for the bundled router (default "/auth")
  • session_lifetime_seconds — session row lifetime and cookie max-age when using cookies (default one week)
  • verify_token_lifetime_seconds — lifetime for verification rows (email verify, etc.)
  • cookie_transport — register/login set Set-Cookie; current_user reads the session from the cookie (no Authorization header needed)
  • cookie_name, cookie_secure, cookie_httponly, cookie_samesite — tune the session cookie (cookie_secure=False for plain HTTP local dev)
  • password_min_length — minimum password length (default 8)
  • user_model, account_model, session_model, verification_model — optional custom SQLAlchemy models (defaults match the mixins)
  • engineadvanced / testing: inject a pre-built async engine (see tests)

Extending models

Subclass the mixins from aura_auth.models.base (or start from DefaultUser in aura_auth.models.sqlalchemy) and pass your types into AuraAuth(..., user_model=MyUser, ...). Fields beyond UserProtocol are yours; the auth core only relies on the protocol surface.


Development

Clone the repo, then:

make sync    # install with dev dependencies (uv)
make check   # lint + format check + types + tests

Individual targets: make lint, make format, make type, make test, make test-cov.

Documentation site (Fumadocs, Next.js) lives in docs/. From that directory: pnpm install, pnpm dev, and optional pnpm build. Endpoints /llms.txt and /llms-full.txt are generated for LLM-friendly exports.


Project layout (source of truth)

src/aura_auth/
├── _core/           # types, protocols, schemas, exceptions, config, security
├── app.py           # AuraAuth + FastAPI wiring
├── manager.py       # UserManager (orchestration)
├── models/          # SQLAlchemy mixins + default models (user, account, session, verification)
├── backend/         # BaseBackend + SQLAlchemy implementation
├── strategies/      # Password (extensible)
├── transport/       # Bearer + cookie
├── router/          # FastAPI auth routes
├── dependencies.py  # current_user, verified
└── __init__.py      # lazy export of AuraAuth (avoids heavy imports on submodule import)

Tests mirror this under tests/ (see AGENTS.md for the full testing map).


Roadmap & stability

  • Now: Email/password, server-side sessions, four-table SQLAlchemy backend, FastAPI router and dependencies, bearer/cookie transports, configurable route prefix.
  • Next: Optional extras (OAuth, magic links, OTP, 2FA, passkeys) as documented in AGENTS.md and pyproject.toml extras.
  • Stability: Until 1.0, treat semver as best effort; breaking changes may land in 0.x while the public surface stabilizes. Issues and design feedback are welcome.

License

License TBD — add a LICENSE file when you publish to GitHub.


Built so you spend less time wiring auth and more time shipping your product.

If Aura Auth saves you a day, a star on GitHub helps others find it.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aura_auth-0.1.1.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aura_auth-0.1.1-py3-none-any.whl (26.4 kB view details)

Uploaded Python 3

File details

Details for the file aura_auth-0.1.1.tar.gz.

File metadata

  • Download URL: aura_auth-0.1.1.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.20

File hashes

Hashes for aura_auth-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c6937bc15afa2971923e703c78a0c80fd8012ea04aa993bc6463e3731ba9a1f9
MD5 a6aa98a84b1c89584957580330da9d00
BLAKE2b-256 64a7b3df50bded378cbe7aa33a0b18946a55c26a1afd3186418e46c499356390

See more details on using hashes here.

File details

Details for the file aura_auth-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: aura_auth-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 26.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.20

File hashes

Hashes for aura_auth-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 83d3d93fff3fc50f25f44f547c7bae88e253827bd64907d04a04200f609fd761
MD5 5ccdfa7784bb441d3169f966f511a97e
BLAKE2b-256 5894345193f5432fddd23c3d785335eb3f41dff9302f1b041a8aed8ab2947d83

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page