Skip to main content

Passwordless authentication for Flask using magic links (and future passkeys).

Project description

Flask-Pass0

Alpha passwordless auth module implementing magic links to start with scaffolding for future passkey implementation. Not ready for production. Magic links are not intended for high security use cases.

What It Does

Handles magic link authentication flow to start with built-in security

  • Token hashing (HMAC-SHA256)
  • Single-use enforcement
  • Secure generation (256-bit entropy)
  • 10-minute expiry

What You Add

  • HTTPS (required)
  • Email sending
  • Rate limiting
  • CSRF protection
  • Any other security

Install

pip install flask-pass0

Quick Start

from flask import Flask
from flask_pass0 import Pass0
from flask_pass0.utils import login_required

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['PASS0_DEV_MODE'] = True  # Shows links in console and not by email

pass0 = Pass0(app)

@app.route('/')
@login_required
def index():
    return "Protected page"

Configuration

Option Default Description
SECRET_KEY required For token hashing
PASS0_DEV_MODE False Show links in console vs by email
PASS0_TOKEN_EXPIRY 10 Token expiry (minutes)
PASS0_TOKEN_LENGTH 32 Token bytes (32 = 256 bits)

Storage

SQLAlchemy

from flask_sqlalchemy import SQLAlchemy
from flask_pass0.storage import SQLAlchemyStorageAdapter

db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    
    def to_dict(self):
        return {"id": self.id, "email": self.email}

storage = SQLAlchemyStorageAdapter(
    user_model=User,
    session=db.session,
    secret_key=app.config['SECRET_KEY']
)
pass0 = Pass0(app, storage_adapter=storage)

Custom

Implement StorageAdapter interface for Redis, MongoDB, etc. See flask_pass0/storage.py.

Email Setup

app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'user@gmail.com'
app.config['MAIL_PASSWORD'] = 'app-password'
app.config['MAIL_DEFAULT_SENDER'] = 'noreply@example.com'
app.config['PASS0_DEV_MODE'] = False  # Send real emails

Security

Built-in:

  • Tokens hashed with HMAC-SHA256
  • Single-use enforcement
  • 10-minute expiry
  • 256-bit entropy

Your responsibility:

  • HTTPS (tokens in URLs)
  • Email security
  • Rate limiting (use Flask-Limiter)
  • CSRF protection (use Flask-WTF)
  • Strong SECRET_KEY
  • All other security

Attack scenarios:

Database compromised: Tokens are hashed, can't be reversed without SECRET_KEY.

Token intercepted: Can be used once within 10 minutes. HTTPS required. For high security applications, add 2FA separately.

Brute force: 2^256 space makes guessing impossible.

Routes

  • GET /auth/login - Login page
  • POST /auth/request-magic-link - Request link (JSON: {"email": "user@example.com"})
  • GET /auth/verify/<token> - Verify token
  • GET /auth/logout - Logout

Notes

Magic links are bearer tokens. Device/email compromise allows token interception. For sensitive apps, implement 2FA after login.

Power users with password managers may prefer passwords. Consider offering both.

Examples

See examples/ directory.

License

MIT

Issues

Found a bug? Open an issue on GitHub. Security issue? Contact maintainer directly.

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

flask_pass0-0.1.1.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

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

flask_pass0-0.1.1-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file flask_pass0-0.1.1.tar.gz.

File metadata

  • Download URL: flask_pass0-0.1.1.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for flask_pass0-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8e84fda96ffc9abadc6be09b133eac68eb935b5a3bbccb93300e81a50b2eb10d
MD5 2ca26c9b15f0f9c9fab675e7b7324e0c
BLAKE2b-256 c102b057a8082b89fad3ac831cf4f1d8091bd90339222d3c36d6c832f55aac51

See more details on using hashes here.

File details

Details for the file flask_pass0-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: flask_pass0-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for flask_pass0-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 324b8693b03965574e5336a300bf4aef470efcff9a9a1012ee169ac3c560bea2
MD5 71fc34e21c0e1114ca21e2a3647cf350
BLAKE2b-256 1ddbbf4a4d8b816169f585669243affd0ca17f9cae6099522112f04d76e2f735

See more details on using hashes here.

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