Skip to main content

API Key Authentication for Litestar applications

Project description

litestar-api-auth

Pluggable API key authentication for Litestar applications

PyPI version Python versions License Documentation

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


Download files

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

Source Distribution

litestar_api_auth-0.1.0.tar.gz (26.3 kB view details)

Uploaded Source

Built Distribution

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

litestar_api_auth-0.1.0-py3-none-any.whl (33.4 kB view details)

Uploaded Python 3

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

Hashes for litestar_api_auth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3610536510265d9a598393f8d788823103f9bfbfffff4aae5fa926768c6ca6ea
MD5 99f19439833339d391ba0e1da1817df5
BLAKE2b-256 cf9176876b2c39bafc20a16f5b5ba59d949e8b195623b430dca65f3771c3457b

See more details on using hashes here.

Provenance

The following attestation bundles were made for litestar_api_auth-0.1.0.tar.gz:

Publisher: publish.yml on JacobCoffee/litestar-api-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file litestar_api_auth-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for litestar_api_auth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 979c5d2608afe39922968a880187cfdffd10bb5d9d66ee66c70a2815a1794927
MD5 00ad26f65a3afef174b70573b26daa82
BLAKE2b-256 b7e3781e56a05b27ef21ec3951450bec3f4446bdeb251aa07f189d6f3caf0bfd

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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