Production-grade, multi-tenant authentication and authorization for Python.
Every B2B Python project needs auth. Building it from scratch is:
- Time consuming (weeks of work)
- Easy to get wrong (security mistakes are costly)
- Repetitive (everyone solves the same problems)
PyAuth gives you enterprise-grade auth in minutes, not weeks.
pip install pyauthfrom pyauth import Auth
auth = Auth(
db_url="postgresql+asyncpg://...",
jwt_secret="your-secret",
multi_tenant=True,
)
app.include_router(auth.get_router(), prefix="/auth")
@app.get("/leads")
async def get_leads(user=auth.protect("leads:read")):
return {"tenant": user.tenant_id}That's it. Full auth system running.
- Multi-tenancy first — tenant isolation enforced at library level
- JWT auth — access + refresh tokens with automatic rotation
- RBAC — 6 built-in roles with granular permissions
- MFA — TOTP-based (Google Authenticator / Authy)
- Email Verification — compulsory verification flow for new users
- Device Fingerprinting — identify and manage trusted devices
- Anomaly Detection — impossible travel, new device alerts, unusual hour detection
- Step-Up Auth — contextual multi-factor re-verification for sensitive actions
- Invite system — employees are invited, not self-registered
- Breach detection — HaveIBeenPwned check on every password
- Audit logs — every action logged automatically with anomaly flags
- Flexible config — code, YAML, or environment variables
- Custom email — plug in SendGrid, SES, or any provider
- Hardened Defaults — CSP/HSTS headers, rate limiting, and encryption-at-rest
PyAuth is built with a security-first philosophy. When you use auth.register_security_middleware(app), the following protections are automatically enabled:
- Encryption-at-Rest: Sensitive database fields (MFA secrets, user payloads) are encrypted using AES-256 (Fernet).
- Security Headers: Automatic injection of
Content-Security-Policy,Strict-Transport-Security,X-Frame-Options, andX-Content-Type-Options. - Rate Limiting: Built-in sliding window protection (100 req/min) for all authentication endpoints.
- Timing Attack Protection: Constant-time string comparisons for all secrets and tokens.
You can verify these features on your local machine by running:
python examples/verify_security.pypip install pyauthfrom fastapi import FastAPI
from pyauth import Auth
app = FastAPI()
auth = Auth(db_url="...", jwt_secret="...")
@app.on_event("startup")
async def startup():
await auth.init_db()
app.include_router(auth.get_router(), prefix="/auth")PyAuth supports three config styles. ENV variables take highest priority.
Code:
auth = Auth(db_url="...", jwt_secret="...")YAML (pyauth.yaml):
jwt:
secret: "your-secret"
database:
url: "postgresql+asyncpg://..."Environment variables:
PYAUTH_JWT_SECRET=your-secret
PYAUTH_DB_URL=postgresql+asyncpg://...Full docs at authentication-system.readthedocs.io
PyAuth provides built-in management endpoints for tenant and user administration (enforced via RBAC):
GET /auth/admin/users— List all users in the current tenant.PATCH /auth/admin/users/{id}/role— Promote/demote users (respects hierarchy).PATCH /auth/admin/tenants/{id}/status— Superadmin control for suspending/activating tenants.
PyAuth provides several production-grade security layers. Here is a quick breakdown of What they are, Why they are used, and if they can be Customized:
- What: Monitors login behavior (IP, Country, Time) and assigns a 0-100 risk score.
- Why: Stops attackers from using stolen credentials if their behavior looks "weird."
- Customization: Enable/Disable via
security.anomaly_detection_enabled. Custom rules can be injected via theAuthconstructor.
- What: Forces re-authentication before sensitive actions (e.g., deleting data).
- Why: Prevents "Unlocked Laptop" attacks where an active session is left unattended.
- Customization: Use the
@auth.step_up_required(valid_window_minutes=15)decorator to set your own security windows.
- What: Automatically locks accounts or destroys tokens after multiple failed attempts.
- Why: Stops automated bots from guessing your users' passwords or recovery links.
- Customization: Change limits via
security.max_login_attempts(Default: 5).
- What: Identifies a browser and hardware configuration beyond just cookies.
- Why: Backbone of identity trust; allows users to "Trust" their primary devices.
- Customization: Complete audit logs available in
device_fingerprintsdatabase table.
MIT © Your Name