Skip to main content

A high-performance, framework-agnostic authorization and session management library for Python

Project description

PyPI version Python Versions License CI codecov Downloads

AuthTuna 🐟

A modern async security framework for Python (FastAPI-first, framework-agnostic core).
Battle-tested, batteries-included authentication, session management, RBAC, SSO, MFA, and much more.


Table of Contents

  1. Getting Started (Basic Auth & Login)
  2. Configuring AuthTuna (Environment, Secrets Manager, etc.)
  3. SSO (Social Login)
  4. MFA (Multi-Factor Authentication)
  5. Permission Checker
  6. Role Checker
  7. Sample Backend Code
  8. Advanced Guide & Patterns
  9. Proof of Endless Possibility

Getting Started (Basic Auth & Login)

1. Install dependencies:

pip install authtuna fastapi uvicorn[standard] asyncpg aiosqlite python-dotenv

2. Create a .env file with minimum configs:

API_BASE_URL=http://localhost:8000
FERNET_KEYS=["YOUR_GENERATED_FERNET_KEY","OPTIONAL_OLDER_KEYS_FOR_COMPATIBILITY_DURING_ROTATION"]
DEFAULT_DATABASE_URI=sqlite+aiosqlite:///./authtuna.db
SECRET_KEY=your-very-secret-key

(See below for how to generate FERNET_KEYS)

3. Minimal FastAPI app:

from fastapi import FastAPI, Depends
from authtuna.middlewares.session import DatabaseSessionMiddleware
from authtuna.integrations.fastapi_integration import get_current_user

app = FastAPI()
app.add_middleware(DatabaseSessionMiddleware)

@app.get("/me")
async def me(user=Depends(get_current_user)):
    return {"id": user.id, "username": user.username, "email": user.email}

4. Run it:

uvicorn main:app --reload

Configuring AuthTuna (Environment, Secrets Manager, etc.)

Required Config Keys (FERNET_KEYS, API_BASE_URL)

  • FERNET_KEYS: Comma-separated base64-encoded keys for encrypting sensitive data (sessions, cookies, etc).

    • To generate:
      from cryptography.fernet import Fernet
      print(Fernet.generate_key().decode())
      
    • Or you can also
      python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
      
      (Repeat to rotate keys, separate by commas. Oldest last in list.)
  • API_BASE_URL: The base URL of your API. Used for generating links in emails and security validation.

All Config Options

Variable Description Required Example
API_BASE_URL Your app's public base URL Yes http://localhost:8000
FERNET_KEYS Comma-separated list of Fernet keys (base64) Yes key1,key2,...
DEFAULT_DATABASE_URI SQLAlchemy DB URI (async supported) Yes sqlite+aiosqlite:///./authtuna.db
SECRET_KEY Secret for signing tokens Yes your-super-secret-key
JWT_SECRET_KEY JWT encryption secret (defaults, override for prod)
ENCRYPTION_PRIMARY_KEY Encryption key for sensitive fields (defaults, override for prod)
ENCRYPTION_SECONDARY_KEYS For key rotation
APP_NAME Application name No AuthTuna
DATABASE_USE_ASYNC_ENGINE Use async SQLAlchemy drivers No True
SESSION_LIFETIME_SECONDS Session duration (seconds) No 604800
SESSION_TOKEN_NAME Cookie name for session No session_token
EMAIL_ENABLED Enable/disable email features No False
SMTP_HOST, SMTP_PORT, ... SMTP config for sending emails If email smtp.example.com, 587, ...
EMAIL_DOMAINS Allowed email domains (list) No gmail.com,example.com
... See source for full list and default values

See core/config.py for ALL options.

Using .env or Environment Variables

  • Place your config in a .env file (see above).
  • Or export them in your shell:
    export API_BASE_URL="https://api.mysite.com", etc.
  • If you want to use a custom file:
    ENV_FILE_NAME=".myenv"

Using a Secrets Manager or Custom init_settings

  • For ultimate flexibility (Docker, cloud, Vault, AWS, etc), call init_settings() at app startup:
from authtuna.core.config import init_settings

def fetch_secrets():
    # Example: fetch from AWS, Vault, or any source
    import os
    return {
        "API_BASE_URL": os.environ.get("API_BASE_URL"),
        "FERNET_KEYS": os.environ.get("FERNET_KEYS"),
        # ...add your secrets here...
    }

init_settings(**fetch_secrets())
  • If you set AUTHTUNA_NO_ENV=true, AuthTuna will not auto-load from env and will require explicit init_settings().

SSO (Social Login)

  • Enable and configure Google, GitHub, or other OAuth providers in your config:
    GOOGLE_CLIENT_ID=...
    GOOGLE_CLIENT_SECRET=...
    GITHUB_CLIENT_ID=...
    GITHUB_CLIENT_SECRET=...
    
  • Mount the built-in routers:
    from authtuna.routers import social as social_router
    app.include_router(social_router.router, prefix="/social", tags=["Social Login"])
    

MFA (Multi-Factor Authentication)

  • AuthTuna supports TOTP, email MFA, and backup codes.
  • Enable MFA in your app settings and use the built-in flows:
    # Flows available in templates/pages and routers
    

Permission Checker

  • Protect any route with fine-grained, context-aware permissions:
    from authtuna.integrations.fastapi_integration import PermissionChecker
    
    @app.get("/resource/{resource_id}")
    async def get_resource(
        resource_id: str,
        user = Depends(PermissionChecker("resource:read", scope_from_path="resource_id"))
    ):
        ...
    

Role Checker

  • Require a role for access (supports multiple roles, hierarchical RBAC):
    from authtuna.integrations.fastapi_integration import RoleChecker
    
    @app.get("/admin")
    async def admin_panel(user=Depends(RoleChecker("admin", "superuser"))):
        ...
    

Sample Backend Code

from fastapi import FastAPI, Depends, HTTPException
from authtuna.middlewares.session import DatabaseSessionMiddleware
from authtuna.integrations.fastapi_integration import (
    get_current_user, PermissionChecker, RoleChecker
)
from authtuna.core.database import User

app = FastAPI()
app.add_middleware(DatabaseSessionMiddleware)

@app.get("/me")
async def me(user: User = Depends(get_current_user)):
    return {"id": user.id, "username": user.username}

@app.get("/project/{project_id}/edit")
async def edit_project(
    project_id: str,
    user: User = Depends(PermissionChecker("project:edit", scope_from_path="project_id"))
):
    # Only users with 'edit' permission in this project
    return {"msg": "Project edit granted"}

@app.get("/superadmin")
async def superadmin(user: User = Depends(RoleChecker("superadmin"))):
    return {"msg": f"Welcome, {user.username}!"}

Advanced Guide & Patterns

  • Multi-Tenancy: Use scoped permissions to isolate orgs/customers.
  • Device/IP/Region Security: Use session hooks to enforce device or location controls.
  • Key Rotation: Rotate FERNET_KEYS, ENCRYPTION_PRIMARY_KEY as needed. Old keys are accepted for decryption.
  • Event Hooks: Run logic on login, registration, session validation, etc.
  • Custom User Models: Extend or swap out models as needed.
  • Pluggable Routers: Use only pieces you want, or replace with your own.

Proof of Endless Possibility

  • SaaS Platforms: Isolated orgs, user impersonation, custom admin flows.
  • FinTech: Device fingerprinting, session hijack protection, audit logging.
  • Education/Community: Nested hierarchy permissions, moderation, bulk actions.
  • Enterprise: SSO, approval workflows, compliance and auditing.

If you can describe the business logic, you can implement it in AuthTuna.

Community & Support


No hype, no snake oil—just a modern, async security framework that works. PRs, questions, and feedback always welcome!

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

authtuna-0.1.7.tar.gz (89.5 kB view details)

Uploaded Source

Built Distribution

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

authtuna-0.1.7-py3-none-any.whl (109.2 kB view details)

Uploaded Python 3

File details

Details for the file authtuna-0.1.7.tar.gz.

File metadata

  • Download URL: authtuna-0.1.7.tar.gz
  • Upload date:
  • Size: 89.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for authtuna-0.1.7.tar.gz
Algorithm Hash digest
SHA256 29675d9b1198033bd224008a63afecf8229b7576a75607c086656c357a8da385
MD5 1d99c54c197e10c69667121f4ea28bf4
BLAKE2b-256 c6f57aa666282ce9a57094c4bf6f4ec928f3632f36a3646d87a13d2c0a1dce74

See more details on using hashes here.

Provenance

The following attestation bundles were made for authtuna-0.1.7.tar.gz:

Publisher: publish-on-push.yml on shashstormer/AuthTuna

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

File details

Details for the file authtuna-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: authtuna-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 109.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for authtuna-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 d1e194086e4b02be26964d7035571e255f4ec4363304eace33644f59b5512275
MD5 7e7e39775b957b39117a1e3b15dfd047
BLAKE2b-256 46b1bd6559bf2493327867c88c761fc0d9c0aa07528b3650002e93899c0c82f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for authtuna-0.1.7-py3-none-any.whl:

Publisher: publish-on-push.yml on shashstormer/AuthTuna

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