You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.7 KiB
5.7 KiB
Multi-Factor Authentication (MFA) Implementation
Overview
Dify implements TOTP-based Multi-Factor Authentication with backup codes for enhanced account security.
Features
1. TOTP Authentication
- Standard: RFC 6238 compliant
- Library:
pyotp(Python) - Apps: Compatible with Google Authenticator, Authy, etc.
- Code Length: 6 digits
- Validity Window: 30 seconds ±1 window
2. Backup Codes
- Count: 8 codes per account
- Format: 8-character hex strings (uppercase)
- Usage: One-time use, automatically removed after use
- Storage: JSON array in database
3. QR Code Generation
- Format: Base64 encoded PNG image
- Size: 200x200 pixels
- Error Correction: Low level
- Contents:
otpauth://totp/Dify:user@example.com?secret=...&issuer=Dify
API Endpoints
Authentication
POST /console/api/login- Login with MFA support- Parameters:
email,password,mfa_code,is_backup_code - Response:
mfa_requiredor success with tokens
- Parameters:
MFA Management
GET /console/api/account/mfa/status- Get MFA statusPOST /console/api/account/mfa/setup- Initialize MFA setupPOST /console/api/account/mfa/setup/complete- Complete setup with TOTP verificationPOST /console/api/account/mfa/disable- Disable MFA with password verification
Database Schema
account_mfa_settings Table
CREATE TABLE account_mfa_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID NOT NULL REFERENCES accounts(id),
enabled BOOLEAN DEFAULT FALSE,
secret VARCHAR(255),
backup_codes TEXT, -- JSON array of backup codes
setup_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
User Flow
1. MFA Setup
- User navigates to Account Settings → Two-Factor Authentication
- Clicks "Enable" button
- QR code and manual key displayed
- User scans QR code with authenticator app
- User enters 6-digit TOTP code
- System validates code and generates backup codes
- User saves backup codes
- MFA is enabled
2. Login with MFA
- User enters email/password
- System returns
{"result": "fail", "code": "mfa_required"} - Frontend displays MFA input screen
- User enters TOTP code or backup code
- System validates and logs user in
3. MFA Disable
- User navigates to Account Settings → Two-Factor Authentication
- Clicks "Disable" button
- Enters password for verification
- System disables MFA and clears settings
Error Handling
API Errors
mfa_required: MFA code needed for loginmfa_token_invalid: Invalid MFA code format (binascii.Error)mfa_token_required: Invalid or expired MFA token
Frontend Errors
- Token length validation (must be 6 digits)
- Network error handling
- Invalid authentication code display
Security Features
1. Rate Limiting
- Login attempts are rate-limited per email
- MFA verification includes existing rate limiting
2. Secret Security
- Secrets are base32 encoded
- Stored directly in database (encrypted at rest)
- Generated using
pyotp.random_base32()
3. Backup Code Security
- Each code can only be used once
- Codes are removed from database after use
- Stored as JSON array in database
Implementation Details
Backend (Python/Flask)
- Services:
MFAServicehandles all MFA operations - Controllers:
LoginApi,MFASetupInitApi,MFASetupCompleteApi,MFADisableApi - Models:
AccountMFASettingsmodel with SQLAlchemy
Frontend (React/TypeScript)
- Components:
MFAPage,MFAVerificationcomponents - State Management: React Query for API calls
- UI: Headless UI Modal components with proper z-index handling
Error Handling
- Custom Handler:
ExternalApi.handle_error()inlibs/external_api.py - binascii.Error: Converted to
mfa_token_invalid(lines 44-54) - ValueError: Non-base32 errors handled specifically (lines 55-69)
Internationalization (i18n)
Supported Languages
- English (
en-US) - Japanese (
ja-JP) - Chinese Simplified (
zh-Hans) - German (
de-DE)
Translation Keys
// mfa.ts
{
title: 'Two-Factor Authentication',
enable: 'Enable',
disable: 'Disable',
next: 'Next',
copy: 'Copy',
copied: 'Copied',
done: 'Done',
// ... more keys
}
Testing
Manual Testing
- MFA setup flow with QR code scanning
- Login with valid/invalid TOTP codes
- Login with backup codes
- MFA disable functionality
- Error handling for various scenarios
Integration Points
- Database migration for
account_mfa_settingstable - Docker container rebuilds required for code changes
- nginx-proxy restart may be needed for routing
Known Issues and Solutions
1. Click Blocking Issue
- Problem: Dialog component (z-index: 40) blocked by overlays
- Solution: Use Modal component (z-index: 70) instead
2. Parameter Mismatch
- Problem: Backend expected
mfa_token, frontend sentmfa_code - Solution: Updated API to use
mfa_codeconsistently
3. Error Message Conversion
- Problem:
binascii.Errorbecame genericinvalid_param - Solution: Added specific error handling in
ExternalApi
Maintenance
Regular Tasks
- Monitor MFA usage and error rates
- Update backup code generation if needed
- Review security of secret storage
Dependencies
pyotp: TOTP generation and verificationqrcode: QR code image generationbinascii: Base32 encoding/decoding
Future Enhancements
Potential Features
- SMS-based MFA as alternative
- Hardware token support (U2F/WebAuthn)
- MFA recovery via admin
- MFA enforcement policies
- Audit logging for MFA events
Last updated: 2025-07-09
Implementation completed and tested successfully