Authentication
User authentication and security in ReadyKit.
Overview
ReadyKit uses Flask-Security-Too for authentication, with OAuth integration via Flask-Dance. Every new user automatically gets a workspace created for them.
Authentication Methods
Email/Password
Standard registration and login with secure password hashing:
- Argon2 password hashing (configured in settings)
- Email-only login (no usernames)
- Password recovery via email
- Configurable password policies
OAuth (Social Login)
Supported providers:
- Google (profile and email scopes)
- GitHub (user:email scope)
OAuth users automatically get a workspace created on first login.
OAuth Setup
Google OAuth
- Go to Google Cloud Console
- Create credentials → OAuth client ID
- Add authorized redirect URI:
https://yourdomain.com/login/google/authorized
# .env
GOOGLE_AUTH_ENABLED=true
GOOGLE_OAUTH_CLIENT_ID=your_client_id
GOOGLE_OAUTH_CLIENT_SECRET=your_secretGitHub OAuth
- Go to GitHub Developer Settings
- New OAuth App
- Set callback URL:
https://yourdomain.com/login/github/authorized
# .env
GITHUB_AUTH_ENABLED=true
GITHUB_OAUTH_CLIENT_ID=your_client_id
GITHUB_OAUTH_CLIENT_SECRET=your_secretTwo-Factor Authentication
ReadyKit supports multiple 2FA methods:
TOTP (Authenticator Apps)
Users can enable TOTP via their security settings. Works with any authenticator app (Google Authenticator, Authy, 1Password, etc.).
WebAuthn (Passkeys/Security Keys)
Hardware security keys and passkeys are supported via WebAuthn. Users can register multiple devices.
Recovery Codes
When 2FA is enabled, users receive 3 recovery codes. These can be regenerated if lost.
Session Management
Sessions are stored in Redis for security and scalability:
# .env
REDIS_SESSION=redis://localhost:6379/1Session security features:
- Strong protection: IP + user agent validation
- Secure cookies: HttpOnly, Secure, SameSite
- Session clearing: On login/logout to prevent workspace data leakage
Platform Roles vs Workspace Roles
ReadyKit has two role systems:
Platform Roles
Applied to the user account itself:
| Role | Access |
|---|---|
| superadmin | Full platform access, admin panel |
| admin | Legacy role (use workspace roles instead) |
Create a superadmin:
uv run flask install --super-admin
# or
uv run flask create -e admin@example.com -p password --super-adminWorkspace Roles
Applied to membership within a workspace (see Teams):
| Role | Access |
|---|---|
| admin | Billing, members, settings, all data |
| member | Standard workspace access |
Route Protection
Require Login
from flask_security import auth_required
@app.route("/account/")
@auth_required()
def account():
return render_template("account.html")Require Platform Role
from flask_security import roles_required
@app.route("/admin/")
@roles_required("superadmin")
def admin_panel():
return render_template("admin/index.html")Require Workspace Access
from enferno.services.workspace import require_workspace_access
@app.route("/workspace/<int:workspace_id>/data/")
@require_workspace_access("member") # or "admin"
def workspace_data(workspace_id):
return render_template("data.html")Security Configuration
Key settings in .env:
# Auto-generated by setup.sh
SECRET_KEY=your_secure_key
SECURITY_PASSWORD_SALT=your_salt
SECURITY_TOTP_SECRETS=your_totp_secrets
# Registration settings
SECURITY_REGISTERABLE=true
SECURITY_CONFIRMABLE=false # Set true to require email confirmation
SECURITY_RECOVERABLE=true # Password reset via email
# Password policy
SECURITY_PASSWORD_LENGTH_MIN=8
# Session settings
SESSION_PROTECTION=strong
PERMANENT_SESSION_LIFETIME=86400 # 1 dayEmail Configuration
For password recovery and email confirmation:
# .env
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=true
MAIL_USERNAME=your_email
MAIL_PASSWORD=your_app_password
MAIL_DEFAULT_SENDER=noreply@yourdomain.comUser Model
from enferno.user.models import User
# Get user's workspaces
workspaces = user.get_workspaces()
# Get role in specific workspace
role = user.get_workspace_role(workspace_id)
# Check if superadmin
if user.is_superadmin:
# Platform admin access
passImportant Security Notes
WARNING
Email cannot be changed (SECURITY_EMAIL_CHANGEABLE=False). This prevents account takeover attacks in multi-tenant environments where email is used as the identity.
INFO
Sessions are cleared on login/logout to prevent workspace data from leaking between sessions.
CLI Commands
# Create admin user (interactive)
uv run flask install
# Create user with specific options
uv run flask create -e user@example.com -p password123
uv run flask create -e admin@example.com -p password123 --super-admin
# Reset password
uv run flask reset -e user@example.com -p newpassword
# Add platform role
uv run flask add-role -e user@example.com -r admin