API Key Authentication for Litestar applications
Project description
litestar-api-auth
Pluggable API key authentication for Litestar applications
Features
- Secure Key Generation: API key generation with SHA-256 hashing
- Configurable Prefixes: Customizable key prefixes (e.g.,
pyorg_,myapp_) - Key Lifecycle Management: Expiration and revocation support
- Usage Tracking: Last-used timestamp tracking for keys
- Pluggable Backends: SQLAlchemy, Redis, and in-memory storage backends
- Route Protection: Pre-built guards for securing endpoints
- Auto-Registration: Automatic management route registration
- Scopes & Permissions: Fine-grained key scopes and permissions system
- OpenAPI Integration: Automatic OpenAPI schema generation
Installation
# Using uv (recommended)
uv add litestar-api-auth
# Using pip
pip install litestar-api-auth
With Optional Dependencies
# With SQLAlchemy support
uv add litestar-api-auth[sqlalchemy]
# With Redis support
uv add litestar-api-auth[redis]
# All optional dependencies
uv add litestar-api-auth[all]
Quick Start
Basic Configuration
from litestar import Litestar
from litestar_api_auth import APIAuthPlugin, APIAuthConfig
from litestar_api_auth.backends.memory import MemoryBackend
app = Litestar(
plugins=[
APIAuthPlugin(
config=APIAuthConfig(
backend=MemoryBackend(), # Use SQLAlchemyBackend for production
key_prefix="myapp_",
header_name="X-API-Key",
auto_routes=True,
route_prefix="/api/v1/api-keys",
)
)
]
)
Protecting Routes with Guards
from litestar import get
from litestar_api_auth import require_api_key, require_scope
@get("/protected", guards=[require_api_key])
async def protected_route() -> dict:
"""Requires any valid API key."""
return {"status": "authenticated"}
@get("/admin", guards=[require_scope("admin:write")])
async def admin_route() -> dict:
"""Requires an API key with the 'admin:write' scope."""
return {"status": "admin access"}
Working with API Keys
from datetime import datetime, timedelta, timezone
from litestar_api_auth.types import APIKeyInfo
# API key information is available after authentication
key_info = APIKeyInfo(
key_id="abc123",
prefix="myapp_",
name="Production API Key",
scopes=["read:users", "write:posts"],
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc) + timedelta(days=365),
last_used_at=None,
is_active=True,
metadata={"owner": "admin@example.com"},
)
# Check key validity
if key_info.is_valid:
print("Key is active and not expired")
# Check for specific scopes
if key_info.has_scope("read:users"):
print("Key has read:users scope")
# Check for multiple scopes
if key_info.has_scopes(["read:users", "write:users"], requirement="all"):
print("Key has all required scopes")
Key States
API keys can be in one of three states:
| State | Description |
|---|---|
ACTIVE |
Key is active and can be used for authentication |
EXPIRED |
Key has passed its expiration date |
REVOKED |
Key has been manually revoked |
Storage Backends
SQLAlchemy Backend
from sqlalchemy.ext.asyncio import create_async_engine
from litestar_api_auth.backends.sqlalchemy import SQLAlchemyBackend
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
backend = SQLAlchemyBackend(engine)
Redis Backend
from litestar_api_auth.backends.redis import RedisBackend
backend = RedisBackend(url="redis://localhost:6379/0")
In-Memory Backend (Testing)
from litestar_api_auth.backends.memory import MemoryBackend
backend = MemoryBackend()
Error Handling
The library provides a comprehensive exception hierarchy:
from litestar_api_auth.exceptions import (
APIAuthError, # Base exception for all auth errors
APIKeyNotFoundError, # Key does not exist
APIKeyExpiredError, # Key has expired
APIKeyRevokedError, # Key has been revoked
InsufficientScopesError, # Key lacks required scopes
InvalidAPIKeyError, # Key format is invalid
ConfigurationError, # Plugin misconfiguration
)
Example Error Handling
from litestar import get
from litestar.exceptions import HTTPException
from litestar_api_auth.exceptions import (
APIKeyExpiredError,
InsufficientScopesError,
)
@get("/resource")
async def get_resource() -> dict:
try:
# ... authentication logic
pass
except APIKeyExpiredError as e:
raise HTTPException(status_code=401, detail="API key has expired")
except InsufficientScopesError as e:
raise HTTPException(
status_code=403,
detail=f"Missing required scopes: {e.required_scopes}"
)
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
backend |
APIKeyBackend |
Required | Storage backend instance |
key_prefix |
str |
"pyorg_" |
Prefix for generated keys |
header_name |
str |
"X-API-Key" |
HTTP header name for API key |
auto_routes |
bool |
True |
Auto-register management routes |
route_prefix |
str |
"/api-keys" |
Prefix for management routes |
enable_openapi |
bool |
True |
Include auth in OpenAPI schema |
track_usage |
bool |
True |
Update last_used_at on requests |
Documentation
Full documentation is available at https://jacobcoffee.github.io/litestar-api-auth
Contributing
Contributions are welcome! Please see our Contributing Guide for details.
License
MIT License - see LICENSE for details.
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 litestar_api_auth-0.1.0.tar.gz.
File metadata
- Download URL: litestar_api_auth-0.1.0.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3610536510265d9a598393f8d788823103f9bfbfffff4aae5fa926768c6ca6ea
|
|
| MD5 |
99f19439833339d391ba0e1da1817df5
|
|
| BLAKE2b-256 |
cf9176876b2c39bafc20a16f5b5ba59d949e8b195623b430dca65f3771c3457b
|
Provenance
The following attestation bundles were made for litestar_api_auth-0.1.0.tar.gz:
Publisher:
publish.yml on JacobCoffee/litestar-api-auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
litestar_api_auth-0.1.0.tar.gz -
Subject digest:
3610536510265d9a598393f8d788823103f9bfbfffff4aae5fa926768c6ca6ea - Sigstore transparency entry: 763769399
- Sigstore integration time:
-
Permalink:
JacobCoffee/litestar-api-auth@a70f72153e49d085bbef5f9a044c82d1930bc69b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JacobCoffee
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a70f72153e49d085bbef5f9a044c82d1930bc69b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file litestar_api_auth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: litestar_api_auth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 33.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
979c5d2608afe39922968a880187cfdffd10bb5d9d66ee66c70a2815a1794927
|
|
| MD5 |
00ad26f65a3afef174b70573b26daa82
|
|
| BLAKE2b-256 |
b7e3781e56a05b27ef21ec3951450bec3f4446bdeb251aa07f189d6f3caf0bfd
|
Provenance
The following attestation bundles were made for litestar_api_auth-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on JacobCoffee/litestar-api-auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
litestar_api_auth-0.1.0-py3-none-any.whl -
Subject digest:
979c5d2608afe39922968a880187cfdffd10bb5d9d66ee66c70a2815a1794927 - Sigstore transparency entry: 763769400
- Sigstore integration time:
-
Permalink:
JacobCoffee/litestar-api-auth@a70f72153e49d085bbef5f9a044c82d1930bc69b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JacobCoffee
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a70f72153e49d085bbef5f9a044c82d1930bc69b -
Trigger Event:
workflow_dispatch
-
Statement type: