Skip to content

Two Factor Authentication

Ali Arslan edited this page Apr 11, 2026 · 3 revisions

Two-Factor Authentication (2FA)

The 2FA system requires linked players to approve their Minecraft login through Discord before they can play. If they deny or do not respond in time, they are kicked (or banned).


How It Works

Player joins server
        │
        ▼
Is the player linked?
   No  → Allow join normally
   Yes ▼
        │
Freeze player (restrict movement, commands, interaction)
Generate 6-digit session code
Send 2FA embed to Discord (DM or configured channel)
        │
        ▼
Wait for response (up to `timeout` seconds)
        │
   ┌────┴────┐
 Approve   Deny / Timeout
   │           │
   ▼           ▼
Unfreeze    Kick or Ban player
player      Notify admins

Requirements

  • Player must have a linked account.
  • The bot must be able to DM the player or post in the configured channel.

Configuration

All 2FA settings live in two-factor.yml:

two-factor:
  enabled: false           # Set to true to activate

  timeout: 120             # Seconds the player has to respond (default: 2 minutes)

  # IP whitelist — players connecting from these IPs skip 2FA
  ip-whitelist:
    enabled: false
    ips:
      - "127.0.0.1"
      - "192.168.1.0/24"

  # Optional: detect and show the player's geographic location in the 2FA embed
  geoip:
    enabled: false
    database-path: "plugins/UxmDiscordSync/GeoLite2-City.mmdb"

  # What happens when the player denies or times out
  on-deny:
    action: kick          # "kick" or "ban"
    kick-message: "Login denied via Discord 2FA."
    ban-duration: 0       # Seconds. 0 = permanent ban (only relevant if action is "ban")

  on-timeout:
    action: kick
    kick-message: "2FA timed out. Please try again."

  # Restrict what the frozen player can do while waiting for approval
  freeze-player:
    enabled: true
    allow-chat: false
    allow-commands: false
    allow-movement: false
    allow-damage: false
    allow-interaction: false

  # Admin notification when a login is denied
  notify-admins:
    enabled: true
    permission: "uxmdiscordsync.2fa.notify"   # Permission to receive notifications

  # The 2FA prompt sent to Discord
  embed:
    title: "Login Verification Required"
    description: "Someone is attempting to log in to **%server_name%** as **%player_name%**."
    color: "#FF9900"
    fields:
      - name: "IP Address"
        value: "%player_ip%"
      - name: "Location"
        value: "%player_location%"     # Requires GeoIP enabled
    approve-button:
      label: "Approve"
      emoji: ""
    deny-button:
      label: "Deny"
      emoji: ""

Delivery Method

The 2FA embed is sent as a Discord DM to the linked user. If DMs are disabled by the user, the plugin falls back to posting in the configured fallback channel:

two-factor:
  fallback-channel-id: "CHANNEL_ID"

GeoIP Location Detection

Optional location detection uses the MaxMind GeoLite2 database. This shows the approximate city and country of the connecting IP in the 2FA embed, helping the player recognise if the login is suspicious.

Setup:

  1. Download the free GeoLite2-City.mmdb from maxmind.com.
  2. Place the file at the path configured in geoip.database-path.
  3. Set geoip.enabled: true.

IP Whitelist

Players connecting from whitelisted IPs bypass 2FA entirely. Useful for admins connecting from a trusted home or office network. Supports both exact IPs and CIDR ranges:

ip-whitelist:
  enabled: true
  ips:
    - "203.0.113.42"          # Exact IP
    - "10.0.0.0/8"            # CIDR range

Player Experience

  1. Player joins the server.
  2. An in-game message tells them to check Discord.
  3. Their screen is effectively locked (movement, commands, interaction disabled).
  4. They see an embed in Discord DMs with Approve and Deny buttons.
  5. If they click Approve: they are unfrozen and can play normally.
  6. If they click Deny or the timer expires: they are kicked (or banned).

Placeholders in Embed

Placeholder Description
%player_name% Minecraft username
%player_uuid% Minecraft UUID
%player_ip% Connecting IP address
%player_location% Country / City from GeoIP
%server_name% Server name from config
%timestamp% Current date and time

Security Considerations

  • Session codes are single-use and expire when the player disconnects.
  • The 2FA approval button is unique per session — a previous message's button cannot be used for a new login.
  • Admin notifications help staff spot credential theft attempts.
  • Consider pairing 2FA with the IP whitelist to reduce friction for trusted admins.

Clone this wiki locally