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 (+ allow_unverified_dev), 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 by default.

Environment Secret present allow_unverified_dev Behaviour
PRODUCTION / STAGING yes any Verified-only. Boot succeeds.
PRODUCTION / STAGING no any Raises ConfigurationError at boot. Flag ignored.
DEVELOPMENT yes any Verified-only. Boot succeeds.
DEVELOPMENT no False (default) Raises ConfigurationError at boot.
DEVELOPMENT no True Boots. Single warning logged. Tokens decoded without signature verification.

Enable the dev opt-in

Via environment variable:

export LEX_AUTH__TOKEN__ALLOW_UNVERIFIED_DEV=true

Via Python config:

from lexigram.auth.config import AuthConfig, JWTConfig

config = AuthConfig(
    secret_key="any-placeholder",
    token=JWTConfig(
        secret_key="any-placeholder",
        allow_unverified_dev=True,
    ),
)

The allow_unverified_dev flag is silently ignored in PRODUCTION and STAGING; the service always rejects the flag in those environments and raises if no real secret is configured. 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

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

lexigram_auth-0.1.3007-py3-none-any.whl (216.9 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for lexigram_auth-0.1.3007-py3-none-any.whl
Algorithm Hash digest
SHA256 6cbea51e809e9bd87cd509c3a570705a5bf5d80d4de552d49b9e680e4afebc73
MD5 6b64aa4dec4975067424d36dc502a844
BLAKE2b-256 ee01c75e2b75a93bc1b01078d89c2bffb6a676957ec0bfbdbf3b475047858df0

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5010

1 file

0.1.5007

2 files

0.1.5001

2 files

This release

0.1.3007 This release

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