Skip to main content

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: AuthConfig requires both secret_key and token.secret_key — pass an explicit config via AuthModule.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 Distribution

lexigram_auth-0.1.5001.tar.gz (234.1 kB view details)

Uploaded Source

Built Distribution

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

lexigram_auth-0.1.5001-py3-none-any.whl (217.9 kB view details)

Uploaded Python 3

File details

Details for the file lexigram_auth-0.1.5001.tar.gz.

File metadata

  • Download URL: lexigram_auth-0.1.5001.tar.gz
  • Upload date:
  • Size: 234.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for lexigram_auth-0.1.5001.tar.gz
Algorithm Hash digest
SHA256 707664641dc89d8f6ea88e092c95f4083737f5c10fe367b0800ec103ca5f97fb
MD5 b05a242ececac769876320324adbadd0
BLAKE2b-256 9f45c0570dd698452907f56a23a344b40a7856bd2f3758ce65d443c62e9b0ec4

See more details on using hashes here.

File details

Details for the file lexigram_auth-0.1.5001-py3-none-any.whl.

File metadata

File hashes

Hashes for lexigram_auth-0.1.5001-py3-none-any.whl
Algorithm Hash digest
SHA256 2d98397580086ecb45e7eb5bd46bf5919b4462a03ae6bc539c55df76257e6d17
MD5 258016d298ec7c9b5af703aa09b81aaa
BLAKE2b-256 36a3887a4b731d887ab48b59f83c494ad26d60a27a6cb33bdb5dca48dc0d3047

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5010

1 file

0.1.5007

2 files

This release

0.1.5001 This release

2 files

0.1.3007

1 file

0.1.3006

1 file

0.1.3005

1 file

0.1.4

2 files

0.1.2

1 file

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page