Multi-Factor Authentication (MFA)

Inmor supports Multi-Factor Authentication (MFA) to add an extra layer of security to administrator accounts. MFA is powered by django-allauth and supports multiple authentication methods.

Overview

MFA provides additional security beyond username and password by requiring a second factor for authentication. Inmor supports:

  • TOTP (Time-based One-Time Password) - Use authenticator apps like Google Authenticator, Authy, or 1Password

  • WebAuthn/Security Keys - Use hardware security keys like YubiKey or built-in platform authenticators (Touch ID, Windows Hello)

Accessing MFA Settings

After logging in, administrators can access MFA settings at:

/accounts/2fa/

Or through the Django admin interface by clicking the “MFA Settings” link.

MFA Settings Page

Two-Factor Authentication settings page

Setting Up TOTP

TOTP (Time-based One-Time Password) uses authenticator apps to generate 6-digit codes that change every 30 seconds.

  1. Navigate to MFA Settings (/accounts/2fa/)

  2. Click Activate under “Authenticator App”

  3. Scan the QR code with your authenticator app

  4. Enter the 6-digit verification code from your app

  5. Click Activate to complete setup

TOTP Activation Page

TOTP activation with QR code and secret key

Tip

Save the Secret Key shown below the QR code. You can use this to manually add the account to your authenticator app if QR scanning doesn’t work.

Setting Up Security Keys

WebAuthn security keys provide phishing-resistant authentication using hardware tokens or built-in platform authenticators.

  1. Navigate to MFA Settings (/accounts/2fa/)

  2. Click Add under “Security Keys”

  3. Follow your browser’s prompts to register your security key

  4. Give the key a memorable name

Security Keys Page

Security Keys management page

Supported Security Keys

  • YubiKey (USB-A, USB-C, NFC)

  • Google Titan (USB, Bluetooth)

  • Feitian keys

  • Platform authenticators:

    • Touch ID (macOS)

    • Face ID (iOS)

    • Windows Hello (Windows)

    • Fingerprint sensors (Android)

Recovery Codes

When you activate MFA, recovery codes are generated as a backup method. These codes can be used if you lose access to your authenticator app or security key.

Warning

Store recovery codes in a secure location separate from your password. Each code can only be used once.

To view or regenerate recovery codes:

  1. Navigate to MFA Settings

  2. Click on “Recovery Codes”

  3. Download or copy the codes to a secure location

Logging In with MFA

After MFA is enabled:

  1. Enter your username and password as usual

  2. You will be prompted for your second factor

  3. Either:

    • Enter the 6-digit code from your authenticator app, or

    • Insert and activate your security key

Re-authentication

For sensitive operations (like changing MFA settings), you may be asked to re-authenticate by entering your password again. This provides additional security for administrative actions.

Disabling MFA

To disable an MFA method:

  1. Navigate to MFA Settings

  2. Click Deactivate next to the method you want to disable

Danger

Disabling all MFA methods removes the extra security layer from your account. Consider keeping at least one MFA method active for administrative accounts.

Configuration

MFA is enabled by default in Inmor. To configure MFA settings, update your Django settings:

# Enable/disable MFA methods
MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes"]

# Require re-authentication for sensitive operations
MFA_PASSKEY_LOGIN_ENABLED = True

# WebAuthn relying party settings
MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = False  # Set True for localhost dev

For production deployments, ensure your site is served over HTTPS as WebAuthn requires a secure context.

TOTP Secret Encryption

Inmor encrypts TOTP secrets before storing them in the database using Fernet symmetric encryption. This ensures that TOTP secrets are not stored in plain text.

Encryption Key Configuration

The encryption key is configured via the MFA_ENCRYPTION_KEY setting or environment variable:

# In settings.py (default development key - DO NOT USE IN PRODUCTION)
MFA_ENCRYPTION_KEY = os.environ.get(
    "MFA_ENCRYPTION_KEY",
    "s098x330cQk5XaIdRWI2-bRsWiiy7ggvJfPrq8OKmQE=",
)

Generating a Production Key

Danger

You must generate a new encryption key for production deployments. The default key is for development only.

Generate a new Fernet key:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Set the key via environment variable in production:

export MFA_ENCRYPTION_KEY="your-generated-key-here"

Or in docker-compose.yml:

admin:
  environment:
    - MFA_ENCRYPTION_KEY=your-generated-key-here

Key Management Best Practices

  • Store the encryption key securely (e.g., in a secrets manager)

  • Never commit production keys to version control

  • Rotate keys periodically by:

    1. Decrypting all existing secrets with the old key

    2. Re-encrypting with the new key

    3. Updating the MFA_ENCRYPTION_KEY setting

  • Back up the encryption key - if lost, users will need to re-enroll MFA

How It Works

The custom EncryptedMFAAdapter in common/mfa_adapter.py overrides the default django-allauth adapter to encrypt/decrypt TOTP secrets:

from allauth.mfa.adapter import DefaultMFAAdapter
from cryptography.fernet import Fernet
from django.conf import settings

class EncryptedMFAAdapter(DefaultMFAAdapter):
    def encrypt(self, text: str) -> str:
        f = Fernet(settings.MFA_ENCRYPTION_KEY)
        return f.encrypt(text.encode()).decode()

    def decrypt(self, encrypted_text: str) -> str:
        f = Fernet(settings.MFA_ENCRYPTION_KEY)
        return f.decrypt(encrypted_text.encode()).decode()

The encrypted secret is stored in the mfa_authenticator table’s data JSON field.

Troubleshooting

QR code not scanning

Try manually entering the secret key shown below the QR code into your authenticator app.

Security key not detected

Ensure your browser supports WebAuthn (Chrome, Firefox, Safari, Edge). Check that the key is properly inserted or NFC is enabled.

Lost authenticator/security key

Use a recovery code to log in, then set up a new authentication method.

Time sync issues with TOTP

Ensure your device’s clock is synchronized. TOTP codes are time-sensitive and require accurate time.