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.
How it works
- SDK reads
Authorization: Bearer <token>from the request, or falls back to theOxaigenPlatformAuthAccessTokencookie. - SDK calls
/_oxa_auth/get-meon the proxy (viahttps://{request_host}) with the token forwarded asAuthorization: Bearer. - Proxy validates the token against Keycloak, looks up the user in the
platform DB, returns a
MeResponse. - SDK parses into a
User, caches for 30s keyed onsha256(token). - For
require_permission(name), SDK additionally calls/_oxa_auth/test-app-permission/{name}, also cached for 30s.
Where the bearer token comes from
- Same-origin frontend → backend — the access cookie auto-attaches. The SDK reads it from the cookie.
- Cross-origin frontend → backend — frontend uses
useAccessToken()from@oxaigen/reactto read the JS-readable access cookie and forward it asAuthorization: Bearer. The SDK reads the header.
HTTP error mapping
Dependencies convert auth failures to FastAPI HTTPException responses:
- Missing/invalid token ->
401 Unauthorized - Missing permission ->
403 Forbidden - Auth proxy unavailable / upstream failure ->
502 Bad Gateway
Common pitfalls
- Adding middleware without using dependencies on routes: endpoints stay publicly accessible.
- Forgetting permission checks on privileged routes: use
require_permission(...). - Host/proxy mismatch in local setups: configure
OXAIGEN_AUTH_PROXY_URL_OVERRIDE. - Using invalid permission names: only
[A-Za-z0-9_-]+is accepted.
User model deep dive
User is the SDK's typed representation of the auth proxy response (/_oxa_auth/get-me), scoped to one workspace and app context.
The model is designed for forward compatibility. If the proxy adds new fields, older SDK clients should keep working without an immediate SDK release.
Why this model is permissive
The auth models intentionally use:
- Optional fields for most identity/profile values
extra = "allow"on auth models
This gives app developers:
- Typed, stable access for known fields
- Non-breaking behavior when upstream adds fields
- Access to newly added proxy fields via
user.extra
Structure and semantics
Workspace-scoped models
UserWorkspace: workspace identity in scope (id,name)WorkspaceRole: role assignment in the scoped workspaceWorkspacePermission: permission assignment in the scoped workspace
All three allow unknown fields, so upstream schema expansion remains non-breaking.
Core identity fields
Common profile fields are optional because availability can vary by identity provider and rollout stage:
id,user_name,emailaccount_type(commonly"internal"or"external")enabled,first_name,last_name
Treat these as "present when provided by upstream", not guaranteed invariants.
Authentication state
is_authenticateddefaults toTruefor resolved usersis_anonymousis a convenience property (not is_authenticated)
In standard dependency-based usage, get_current_user returns authenticated users. Anonymous behavior is mainly relevant in optional/mixed-auth flows and tests.
Authorization data
workspace_rolesdefaults to an empty listworkspace_permissionsdefaults to an empty list
Using default_factory=list avoids mutable-default pitfalls and allows safe iteration even when upstream omits these fields.
Middleware state contract
When OxaigenAuthMiddleware is installed, each request has:
request.state.user(UserorNone)request.state.auth_error(strorNone)
The middleware never blocks the request by itself. If upstream auth is down, it sets auth_error and continues; route dependencies decide enforcement.
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.
Project details
Release history Release notifications | RSS feed
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.3.tar.gz.
File metadata
- Download URL: oxaigen_auth-0.0.3.tar.gz
- Upload date:
- Size: 19.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.5.1 CPython/3.10.12 Darwin/24.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ceb5a9d45134aeffbe9038fff14a40ae6ab0331270e52de2bac7fb23e4c6b38a
|
|
| MD5 |
2944059f15f378e08e50a22b907b0a50
|
|
| BLAKE2b-256 |
f4490f6e0fc3630157778a6b995f90c87374f63aa4b6df8134afee28a0158a40
|
File details
Details for the file oxaigen_auth-0.0.3-py3-none-any.whl.
File metadata
- Download URL: oxaigen_auth-0.0.3-py3-none-any.whl
- Upload date:
- Size: 21.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.5.1 CPython/3.10.12 Darwin/24.3.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b9f8211b91379647076300fa614c244de989b03d97497cfef777fbe322d67ad
|
|
| MD5 |
4b13db77a90fc26baf06d07f0f4ee90d
|
|
| BLAKE2b-256 |
f6227a6f32627028b1c7821ba6ae30a79b992adfc7a7a1d0ac532eba7d991937
|