lexigram-auth
Authentication and authorization for the Lexigram Framework — JWT, OAuth2, SAML, RBAC, and multi-tenancy.
Overview
Complete authentication and authorization stack for Lexigram — JWT, OAuth2, RBAC,
SAML, passkeys, and MFA. Provides a production-ready auth layer with multiple
authentication strategies, policy-based access control, session management, and
seamless integration with lexigram-web middleware.
Use AuthModule.configure() to register the auth bundle and protect routes with
@require_auth, @require_roles, and @require_permissions decorators.
Full documentation: docs.lexigram.dev
Install
uv add lexigram-auth
# Optional extras
uv add "lexigram-auth[oauth2,saml]"
Quick Start
from lexigram import Application
from lexigram.di.module import Module, module
from lexigram.auth import AuthModule, AuthConfig, JWTConfig
@module(
imports=[
AuthModule.configure(
config=AuthConfig(
secret_key="your-secret-key",
token=JWTConfig(secret_key="your-jwt-secret"),
)
)
]
)
class AppModule(Module):
pass
async def main() -> None:
async with Application.boot(modules=[AppModule]) as app:
# app is running — resolve services from app.container
...
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Configuration
Note:
AuthConfigrequires bothsecret_keyandtoken.secret_key— pass an explicit config viaAuthModule.configure().
Option 1 — YAML file
# application.yaml
auth:
secret_key: "your-secret-key"
token:
secret_key: "your-jwt-secret"
algorithm: "HS256"
access_token_expire: "30m"
rbac:
enabled: true
default_role: "viewer"
Option 2 — Profiles + Environment Variables (recommended)
export LEX_AUTH__SECRET_KEY=your-secret-key
export LEX_AUTH__TOKEN__SECRET_KEY=your-jwt-secret
export LEX_AUTH__TOKEN__ALGORITHM=HS256
export LEX_AUTH__RBAC__DEFAULT_ROLE=viewer
Option 3 — Python
from lexigram.auth import AuthModule, AuthConfig, JWTConfig
from lexigram.contracts.core import Duration
config = AuthConfig(
secret_key="your-secret-key",
token=JWTConfig(
secret_key="your-jwt-secret",
algorithm="HS256",
access_token_expire=Duration.minutes(30),
),
)
AuthModule.configure(config)
Config reference
| Field | Default | Env var | Description |
|---|---|---|---|
secret_key |
— | LEX_AUTH__SECRET_KEY |
Top-level signing secret (required) |
token.secret_key |
— | LEX_AUTH__TOKEN__SECRET_KEY |
JWT signing secret (required) |
token.algorithm |
HS256 |
LEX_AUTH__TOKEN__ALGORITHM |
JWT algorithm: HS256, RS256, ES256 |
token.access_token_expire |
30m |
LEX_AUTH__TOKEN__ACCESS_TOKEN_EXPIRE |
Access token lifetime (duration string, e.g. 30m, 1h30m) |
rbac.enabled |
True |
LEX_AUTH__RBAC__ENABLED |
Enable RBAC |
rbac.default_role |
viewer |
LEX_AUTH__RBAC__DEFAULT_ROLE |
Default role for new users |
Module Factory Methods
| Method | Description |
|---|---|
AuthModule.configure(...) |
Configure with explicit AuthConfig |
AuthModule.stub() |
Minimal config for testing |
Key Features
- JWT authentication — HS256/RS256, key rotation, token blacklisting
- OAuth2 / OIDC — authlib-backed: Google, GitHub, custom providers
- SAML 2.0 — Enterprise SSO via pysaml2
- Passkeys (WebAuthn) — FIDO2 device-based authentication
- MFA (TOTP) — Time-based one-time passwords
- RBAC — Role/permission inheritance with policy expressions
- Session management — Device-aware sessions with concurrency limits
- Token binding — IP address binding to prevent token theft
Testing
async with Application.boot(modules=[AuthModule.stub()]) as app:
# your test code
...
Key Source Files
| File | What it contains |
|---|---|
src/lexigram/auth/module.py |
AuthModule definition |
src/lexigram/auth/config.py |
AuthConfig, JWTConfig, RBACConfig |
src/lexigram/auth/di/bundle_provider.py |
AuthBundleProvider wiring |
src/lexigram/auth/di/sub_providers/token_provider.py |
TokenProvider (boots policy) |
src/lexigram/auth/authn/jwt.py |
JWTTokenManager implementation |
src/lexigram/auth/authn/_jwt_lifecycle.py |
verify_token (enforces policy) |
src/lexigram/auth/authz/service.py |
AuthorizationService |
JWT verification policy
lexigram-auth enforces verified-only JWT decoding — signature verification
cannot be disabled.
| Environment | Secret present | Behaviour |
|---|---|---|
PRODUCTION / STAGING |
yes | Verified-only. Boot succeeds. |
PRODUCTION / STAGING |
no | Raises ConfigurationError at boot. |
DEVELOPMENT |
yes | Verified-only. Boot succeeds. |
DEVELOPMENT |
no | Verified-only. Boots with a generated ephemeral secret (tokens invalidated on restart). |
Stable development secret
For multi-service development, set a stable secret via environment variable:
export LEX_AUTH__TOKEN__SECRET_KEY="a-stable-dev-secret-at-least-32-chars"
Via Python config:
from lexigram.auth.config import AuthConfig, JWTConfig
config = AuthConfig(
secret_key="a-stable-dev-secret-at-least-32-chars",
token=JWTConfig(
secret_key="a-stable-dev-secret-at-least-32-chars",
),
)
This prevents the Piccolina-style mistake of silently trusting unverified tokens in production when a secret env-var is missing.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
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 lexigram_auth-0.1.5010-py3-none-any.whl.
File metadata
- Download URL: lexigram_auth-0.1.5010-py3-none-any.whl
- Upload date:
- Size: 230.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a07414a409ab0c2be4c086cb4779cd3933664f1955b06bf007c2e1d9147041d
|
|
| MD5 |
c5a209a97e9f3decea90b658f3f0f986
|
|
| BLAKE2b-256 |
6fb809c0f1382a9e5574f945d26a94b74081896c16148c9c276e2957389671dd
|