Oxaigen Auth SDK
Project description
Oxaigen Auth SDK Guide
This project is a minimal FastAPI backend that demonstrates how to protect endpoints with the oxaigen-auth SDK.
Use this document as a shareable integration guide for teams that want to add Oxaigen authentication to their own backend app.
What this SDK gives you
- Request middleware that enriches each request with auth context.
- A
get_current_userdependency for authenticated routes. - A
get_current_user_optionaldependency for mixed public/private routes. - A
require_permission("<permission>")dependency for role/permission checks. - A typed
Usermodel injected into your endpoint handlers.
Requirements
- Python
3.11+ - FastAPI app
- An Oxaigen environment/proxy available for token verification
Install
With Poetry:
poetry add oxaigen-auth
With pip:
pip install oxaigen-auth
Import paths (recommended)
from oxaigen import (
User,
get_current_user,
get_current_user_optional,
require_permission,
OxaigenAuthMiddleware,
)
Available root exports include:
- Main API:
User,get_current_user,get_current_user_optional,require_permission,OxaigenAuthMiddleware - Settings and exceptions:
OxaigenAuthSettings,OxaigenAuthUnauthenticatedError,OxaigenAuthPermissionDeniedError,OxaigenAuthUpstreamError - Advanced utilities:
ProxyAuthClient,aclose_client,extract_bearer_token,derive_proxy_base_url
Minimal FastAPI integration
from typing import Optional
from fastapi import FastAPI, Depends
from oxaigen_auth import OxaigenAuthMiddleware
from oxaigen_auth import (
User,
get_current_user,
get_current_user_optional,
require_permission,
)
app = FastAPI()
app.add_middleware(OxaigenAuthMiddleware)
@app.get("/v1/me")
async def me(user: User = Depends(get_current_user)):
return user
@app.get("/v1/maybe-public")
async def maybe_public(user: Optional[User] = Depends(get_current_user_optional)):
if user:
return {"signed_in": True, "email": user.email}
return {"signed_in": False}
@app.get("/v1/audit")
async def audit(user: User = Depends(require_permission("audit"))):
return {"audit_log": [{"hello": "world"}]}
Behavior model
Important: middleware and dependencies have different responsibilities.
-
OxaigenAuthMiddleware:- Parses incoming auth context.
- Enriches request state with user/auth metadata when present.
- Does not block unauthenticated requests on its own.
-
get_current_user:- Enforces authentication.
- Returns the authenticated
User. - Fails the request when token/user validation fails.
-
get_current_user_optional:- Returns
Userwhen token is valid. - Returns
Nonewhen token is missing/invalid. - Still fails with
502when auth upstream is unavailable.
- Returns
-
require_permission("..."):- Enforces both authentication and permission presence.
- Use for routes that require explicit capabilities (for example
audit). - Validates permission name format:
[A-Za-z0-9_-]+.
Authenticated request flow
- Client sends request with auth cookie/token.
- Middleware runs and prepares auth request context.
- Endpoint dependency (
get_current_userorrequire_permission) validates against Oxaigen auth backend. - Endpoint executes with resolved
User.
Token extraction order:
Authorization: Bearer <token>header- Auth cookie (configured name)
Caching behavior
The SDK caches per process to reduce upstream traffic:
- User cache: token hash ->
User(CACHE_TTL_SECONDS, default30s) - Permission cache: token hash + permission -> bool (
CACHE_TTL_SECONDS, default30s) - Negative cache for invalid tokens: token hash sentinel (
NEGATIVE_CACHE_TTL_SECONDS, default5s)
Notes:
- Cache keys use a hash of the token (not the raw token).
- Invalid token bursts are throttled by the negative cache.
- Middleware and dependencies share the same validation/cache pipeline.
SDK configuration (optional)
All env vars are optional with safe defaults:
| Var | Default | Purpose |
|---|---|---|
OXAIGEN_AUTH_PROXY_URL_OVERRIDE |
unset | Force a specific proxy URL. Default: derived from Host header. |
OXAIGEN_AUTH_PROXY_SCHEME |
https |
Scheme when deriving proxy URL. Set http for dev. |
OXAIGEN_AUTH_ACCESS_TOKEN_COOKIE_NAME |
OxaigenPlatformAuthAccessToken |
Match if the proxy uses a custom cookie name. |
OXAIGEN_AUTH_CACHE_TTL_SECONDS |
30 |
Validation cache TTL. |
OXAIGEN_AUTH_NEGATIVE_CACHE_TTL_SECONDS |
5 |
TTL for failed-validation entries. |
OXAIGEN_AUTH_CACHE_MAX_ENTRIES |
1024 |
LRU cap. |
OXAIGEN_AUTH_PROXY_TIMEOUT_SECONDS |
5.0 |
Server-to-server HTTP timeout. |
Tip: for local/dev environments behind non-standard host routing, OXAIGEN_AUTH_PROXY_URL_OVERRIDE is commonly the most
useful setting.
Local auth mock server
The package ships a development mock at oxaigen_auth/dev/mock_server.py that emulates the proxy's /_oxa_auth/*
surface (login, callback, token exchange, get-me, permission checks) so you can run your backend end-to-end without a
real proxy or Keycloak. Start it with uv run oxaigen-auth-mock (or poetry run oxaigen-auth-mock).
See docs/DEVELOPMENT.md for the full setup: built-in personas, env vars, frontend dev-server
proxy config, and troubleshooting.
Advanced usage
Most apps only need dependencies + middleware. Advanced consumers can use:
ProxyAuthClientfor direct low-level proxy callsextract_bearer_tokenandderive_proxy_base_urlfor custom flowsaclose_clientto close SDK HTTP resources during app shutdown
Production recommendations
- Keep
/healthpublic; protect business endpoints with dependencies. - Use short timeout/cache defaults unless you have measured reasons to change.
- Add integration tests for:
- unauthenticated access (expect failure),
- authenticated access (expect success),
- missing permission (expect failure),
- required permission present (expect success).
Deployment expectations
Your app must be served behind the Oxaigen proxy so /_oxa_auth/* endpoints are available on the same host as the
frontend.
If those endpoints are unavailable, SDK auth checks cannot succeed.
Local development setup (two-terminal flow)
When developing a backend app that uses the Oxaigen Auth SDK, you typically run two processes side by side:
- The auth mock server — emulates the proxy's
/_oxa_auth/*endpoints that the SDK calls to validate tokens. - Your backend application — the FastAPI app that imports the SDK.
This is necessary because in production, your app sits behind the Oxaigen proxy and the SDK resolves /_oxa_auth/* on
the request's own Host. Locally there is no proxy in front, so the SDK needs to be told to call the mock instead.
That's what OXAIGEN_AUTH_DEV_MODE is for.
Terminal 1 — start the mock server
poetry run oxaigen-auth-mock
This boots the mock on http://127.0.0.1:8765 and serves the full /_oxa_auth/* surface (login, callback,
token-exchange, get-me, test-app-permission, etc.). Leave this running.
Terminal 2 — run your backend with the SDK in dev mode
Set OXAIGEN_AUTH_DEV_MODE=1 so the SDK routes validation calls to the mock instead of deriving the URL from the
incoming request's Host:
export OXAIGEN_AUTH_DEV_MODE=1
# Optional — only set if your mock isn't on the default 127.0.0.1:8765
# export OXAIGEN_AUTH_DEV_PROXY_URL=http://127.0.0.1:8765
poetry run uvicorn my_app.main:app --reload --port 8000
Your backend now runs on http://127.0.0.1:8000 and every SDK validation call (/_oxa_auth/get-me,
/_oxa_auth/test-app-permission/...) goes to the mock on 127.0.0.1:8765.
How the SDK picks the auth URL
The SDK's derive_proxy_base_url resolves in this order:
OXAIGEN_AUTH_PROXY_URL_OVERRIDE— if set, used verbatim. Wins over everything, including dev mode. Useful for pointing at a fixed staging proxy.OXAIGEN_AUTH_DEV_MODE=1— usesOXAIGEN_AUTH_DEV_PROXY_URL(defaulthttp://127.0.0.1:8765). This is the normal local-dev path.- Default (production) — builds
{scheme}://{host}from the incoming request'sX-Forwarded-HostorHostheader, assuming the app is behind the Oxaigen proxy.
So in dev you generally only need OXAIGEN_AUTH_DEV_MODE=1; the default OXAIGEN_AUTH_DEV_PROXY_URL already matches
the mock's default bind address.
Sending requests against your dev backend
With the mock running, the default token mock-dev-token is valid. You can hit your backend directly:
curl -H "Authorization: Bearer mock-dev-token" http://127.0.0.1:8000/v1/me
The SDK will pull the bearer token off the header, call the mock at http://127.0.0.1:8765/_oxa_auth/get-me, and
resolve a User. If you're driving a frontend against the mock, the access cookie set by the mock's callback flow will
also be accepted by the SDK on same-origin requests.
Tips
- If you change mock env vars (e.g.
OXAIGEN_AUTH_MOCK_PERMISSIONS), restart Terminal 1 — the mock reads env at startup. - Token validation results are cached for 30s by default. If you flip a token between valid and invalid while testing, either wait out the TTL or restart your backend.
- Running the mock on a non-default host/port? Set
OXAIGEN_AUTH_DEV_PROXY_URLin Terminal 2 to match (e.g.http://127.0.0.1:9000), and also setOXAIGEN_AUTH_MOCK_HOST/OXAIGEN_AUTH_MOCK_PORTin Terminal 1. - To temporarily point dev traffic at a remote staging proxy instead of the local mock, unset
OXAIGEN_AUTH_DEV_MODEand setOXAIGEN_AUTH_PROXY_URL_OVERRIDE=https://your-staging-host— no other changes needed.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oxaigen_auth-0.0.6.tar.gz.
File metadata
- Download URL: oxaigen_auth-0.0.6.tar.gz
- Upload date:
- Size: 32.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.10.12 Darwin/24.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd4fd24ec41e48fd4bc64452c61f4ce1304bf6743a0a4366385bf909752e30a2
|
|
| MD5 |
169544da919638091c21cd4f0658ac7f
|
|
| BLAKE2b-256 |
48228975d557166a97f01d73e02982256d7574520249f4be10174c09d949d3e5
|
File details
Details for the file oxaigen_auth-0.0.6-py3-none-any.whl.
File metadata
- Download URL: oxaigen_auth-0.0.6-py3-none-any.whl
- Upload date:
- Size: 38.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.10.12 Darwin/24.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
946d3cbf30018b68d9cb67c5a0c849d63981d835d933d78b98eba1523633e79f
|
|
| MD5 |
1dc35298a0fc2b6ec76cb2273bab7c05
|
|
| BLAKE2b-256 |
47ab819d6f382e7896bf1198c862d3686ea4f8d872d8e82b0a0823ae84dba795
|