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.
gcgj-dify-1.7.0/MFA.md

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_required or success with tokens

MFA Management

  • GET /console/api/account/mfa/status - Get MFA status
  • POST /console/api/account/mfa/setup - Initialize MFA setup
  • POST /console/api/account/mfa/setup/complete - Complete setup with TOTP verification
  • POST /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

  1. User navigates to Account Settings → Two-Factor Authentication
  2. Clicks "Enable" button
  3. QR code and manual key displayed
  4. User scans QR code with authenticator app
  5. User enters 6-digit TOTP code
  6. System validates code and generates backup codes
  7. User saves backup codes
  8. MFA is enabled

2. Login with MFA

  1. User enters email/password
  2. System returns {"result": "fail", "code": "mfa_required"}
  3. Frontend displays MFA input screen
  4. User enters TOTP code or backup code
  5. System validates and logs user in

3. MFA Disable

  1. User navigates to Account Settings → Two-Factor Authentication
  2. Clicks "Disable" button
  3. Enters password for verification
  4. System disables MFA and clears settings

Error Handling

API Errors

  • mfa_required: MFA code needed for login
  • mfa_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: MFAService handles all MFA operations
  • Controllers: LoginApi, MFASetupInitApi, MFASetupCompleteApi, MFADisableApi
  • Models: AccountMFASettings model with SQLAlchemy

Frontend (React/TypeScript)

  • Components: MFAPage, MFAVerification components
  • State Management: React Query for API calls
  • UI: Headless UI Modal components with proper z-index handling

Error Handling

  • Custom Handler: ExternalApi.handle_error() in libs/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

  1. MFA setup flow with QR code scanning
  2. Login with valid/invalid TOTP codes
  3. Login with backup codes
  4. MFA disable functionality
  5. Error handling for various scenarios

Integration Points

  • Database migration for account_mfa_settings table
  • 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 sent mfa_code
  • Solution: Updated API to use mfa_code consistently

3. Error Message Conversion

  • Problem: binascii.Error became generic invalid_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 verification
  • qrcode: QR code image generation
  • binascii: 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