Authdog

Python

Last updated Jul 19, 2026CI passing
View as Markdown

Authdog's Python source provides session integrations for FastAPI, Django, Flask, Starlette, and aiohttp. All use the same cookie/bearer-token and OIDC userinfo flow.

Availability and install

Unreleased: authdog-fastapi is not available on PyPI. Do not use pip install authdog-fastapi in production setup instructions.

Current code is source-only in `packages/python`. It requires Python 3.10+ and is versioned 0.1.0. Clone or pin a commit of the public repository, then install that directory with the appropriate extra:

python -m pip install "./packages/python[fastapi]"

Extras and minimum framework versions: fastapi 0.110, django 4.2, flask 3.0, starlette 0.37, and aiohttp 3.9. httpx 0.27+ is the base runtime dependency. Published compatibility is not yet guaranteed.

Configure and protect

Each module exports its own Authdog binding. Construct it once with your environment's public key (pk_...):

import os
from authdog.fastapi import Authdog

authdog = Authdog(public_key=os.environ["PK_AUTHDOG"])

The key is safe to expose. Construction rejects malformed keys and identity hosts outside the trusted HTTPS allowlist.

FastAPI

Use session for optional context and require_auth as the 401 dependency:

from fastapi import Depends, FastAPI, Request

app = FastAPI()

@app.get("/me")
async def me(user=Depends(authdog.require_auth)):
    return user

@app.get("/logout")
async def logout(request: Request):
    return authdog.logout(request)

Framework APIs

Framework Optional session Authentication gate Registration and logout
FastAPI Depends(authdog.session) Depends(authdog.require_auth) authdog.logout(request)
Django authdog.session(request) @authdog.require_auth Optional authdog.middleware; authdog.logout(request)
Flask authdog.session() @authdog.require_auth Context cached on flask.g; authdog.logout()
Starlette await authdog.session(request) await authdog.require_auth(request) Add authdog.middleware; authdog.logout(request)
aiohttp await authdog.session(request) @authdog.require_auth Add authdog.middleware; route authdog.logout

Django and Flask drive the async userinfo resolver with asyncio.run; use their documented synchronous view paths. Starlette and aiohttp bindings are async. aiohttp's logout raises its HTTPFound response, as expected by aiohttp.

Every binding resolves AuthdogContext:

@dataclass
class AuthdogContext:
    token: str | None = None
    user: Any | None = None
    is_authenticated: bool = False
    user_info: dict | None = None

The resolver prefers authdog-session, then Authorization: Bearer <token>. Missing, invalid, or failed userinfo requests return anonymous context rather than raising. Only meta.code == 200 with a user sets is_authenticated.

fetch_user=False only exposes an unverified token. user remains None and is_authenticated remains false, so every built-in gate rejects it. Use this option only when separate server-side validation and enforcement replace Authdog's gate.

Security boundaries

  • session and middleware are informational; require_auth is the authentication boundary.
  • Authentication does not grant application permissions. Apply authorization separately.
  • Bearer tokens are sent only to a trusted HTTPS identity host. Self-hosted hosts require explicit AUTHDOG_ALLOWED_IDENTITY_HOSTS entries.
  • Logout clears the local cookie and sanitizes redirect_uri; it does not revoke bearer tokens or end an upstream provider session.

Next steps

Learn more