Minecraft Authentication Plugin

PSGLogin

Secure, modern authentication for offline-mode Minecraft servers. Supports Paper, Purpur, Spigot, Velocity, BungeeCord and more.

Paper 1.18 – 1.21.x
Purpur
Spigot
Velocity 3.x
BungeeCord
Java 17+
SQLite & MySQL
Get Started View Commands

Everything you need
Built for security, performance and full customization
🔐

BCrypt Password Hashing

Industry-standard bcrypt hashing. Passwords are never stored in plain text.

IP Auto-Login

Players who reconnect from the same IP are automatically authenticated. Expiry is fully configurable.

👑

Premium Auto-Login

Mojang-verified players skip login automatically when premium mode is enabled.

🪨

Bedrock / Floodgate

Bedrock players via Geyser + Floodgate are auto-authenticated without a password.

🔑

2FA / TOTP

Optional two-factor authentication using any standard authenticator app.

🛡️

Brute-Force Protection

Account lockout and IP banning after too many failed login attempts.

🤖

Anti-Bot

Blocks IPs that join too many times in a short window to prevent bot attacks.

🌐

VPN Detection

Optionally block VPN and proxy connections using proxycheck.io.

🎨

Fully Customizable

Every message, title, color and timing is configurable. Supports hex colors and gradients.

🗄️

SQLite & MySQL

SQLite for single servers, MySQL for shared data across a full network.

🔗

Proxy Support

Full Velocity and BungeeCord proxy support with NanoLimbo integration.

📊

Session Management

Track active sessions, view alt accounts, and manage IP bans from one command.


Setup Guide
Choose your server type below
1

Install the plugin

Download PSGLogin-paper.jar and place it in your /plugins/ folder. Start the server once to generate config files, then stop it.

2

Configure config.yml

Open plugins/PSGLogin/config.yml and set your preferences:

# Make sure proxy is disabled for standalone
proxy:
  enabled: false

main:
  auth-time: 60         # seconds to login before kick
  min-password-length: 6
  max-password-length: 32

auto-login:
  enabled: true
  expiry-seconds: 86400  # 24h, set 0 for unlimited

bedrock:
  auto-login: true      # Floodgate players skip login

database:
  type: SQLITE           # or MYSQL
3

Customize messages.yml

Edit plugins/PSGLogin/messages.yml to change any title, chat message, color or timing. Supports &a legacy codes and &#FF5733 hex colors.

4

Start & set spawn

Start your server, log in as admin and run /psglogin setspawn where you want players to land after login.

Network Layout
Players authenticate on NanoLimbo, then get sent to your lobby
👤
Player
Velocity
PSGLogin-velocity
🌑
NanoLimbo
Login / Register
🏠
Lobby
PSGLogin-paper
Other Servers
PSGLogin-paper
1

Set up NanoLimbo

Download and run NanoLimbo on port 65535 (or any free port). It needs no extra configuration — it is just a blank void world.

2

Configure velocity.toml

[servers]
limbo = "127.0.0.1:65535"
lobby = "127.0.0.1:25577"

try = [
  "limbo"   # unauthenticated players land here
]
3

Install PSGLogin on Velocity

Drop PSGLogin-velocity.jar into Velocity's /plugins/ folder. Start once to generate config, then stop.

4

Configure velocity-config.yml

limbo-server: limbo     # must match velocity.toml
main-server:  lobby     # must match velocity.toml
auth-time:    60

premium:
  enabled: true

bedrock:
  auto-login: true

auto-login:
  enabled: true
  expiry-seconds: 86400

# Generate any random 64-character string
access-token: "YOUR_SECRET_TOKEN_HERE"

database:
  type: MYSQL   # recommended for networks
5

Install PSGLogin on every Paper backend

Drop PSGLogin-paper.jar into each Paper server's /plugins/ folder. Start once to generate config, then stop.

6

Enable proxy mode on each Paper server

proxy:
  enabled: true
  access-token: "YOUR_SECRET_TOKEN_HERE"
  # Must match exactly what you set in velocity-config.yml

database:
  type: MYSQL
  mysql:
    host: your-db-host
    database: psglogin   # same DB as Velocity
    username: youruser
    password: yourpassword
7

Start everything in order

  • 1. Start NanoLimbo
  • 2. Start all Paper backend servers
  • 3. Start Velocity
1

Install PSGLogin on BungeeCord

Drop PSGLogin-bungee.jar into BungeeCord's /plugins/ folder. Start once to generate config, then stop.

2

Configure bungee-config.yml

limbo-server: limbo
main-server:  lobby
auth-time:    60
access-token: "YOUR_SECRET_TOKEN_HERE"
3

Add servers to BungeeCord config.yml

servers:
  limbo:
    address: localhost:65535
    restricted: false
  lobby:
    address: localhost:25577
    restricted: false

listeners:
  - priorities:
    - limbo
4

Enable proxy mode on each Paper backend

Same as Velocity — set proxy.enabled: true and the matching access-token in each Paper server's config.yml.


Commands
All commands available to players and admins

Player Commands

/register <pass> <pass>Create a new account
/login <password>Login to your account
/logoutLog out and return to limbo
/changepassword <old> <new>Change your password
/unregister <password>Delete your account
/2fa enableEnable two-factor authentication
/2fa disable <code>Disable two-factor authentication

Admin Commands — psglogin.admin

/psglogin reloadReload all config files
/psglogin status <player>View player auth status
/psglogin sessionsView active session count
/psglogin unregister <player>Force unregister a player
/psglogin forcepassword <p> <pass>Force change a password
/psglogin tempbanip <player>Temporarily ban player's IP
/psglogin unbanip <ip>Unban an IP address
/psglogin listbansList all banned IPs
/psglogin resetattempts <player>Reset failed login attempts
/psglogin ipinfo <ip>Show accounts from an IP
/psglogin alts <player>Show alt accounts
/psglogin setspawnSet the post-login spawn
/psglogin antibot <on|off>Toggle anti-bot protection

Customization
Full color, gradient and message control from messages.yml

Color Codes

&a Green &c Red &e Yellow &6 Gold &b Aqua &7 Gray &f White &9 Blue

Hex Colors (1.16+)

# Format: &#RRGGBB
"&#FF4500&lPSGLogin"
"&#00E676Welcome back!"
"&#FFD700Gold text"

Multiline Messages

login-success: |
  &f
  &8[&a&l»&8] &7Welcome back, &a%player%&7!
  &f

register-success: |
  &f
  &8[&a&l»&8] &7Hi &a%player%&7! Useful commands:
  &f  &a&l» &7/changepassword <old> <new>
  &f  &a&l» &7/logout
  &f

Available Placeholders

%player%Player's username
%time%Time remaining (seconds)
%attempts_left%Login attempts left
%min%Min password length
%max%Max password length
%token%2FA secret token
%codes%2FA recovery codes
%ip%Player IP address

Full Setup Guide
Everything explained in detail — files, configs, and what each setting does

📄 Install PSGLogin on Paper

For a standalone Paper/Purpur/Spigot server with no proxy.
server/plugins/PSGLogin-paper.jar
  1. Download PSGLogin-paper.jar from the releases page.
  2. Place it inside your server's /plugins/ folder.
  3. Start the server once — it will generate all config files.
  4. Stop the server before editing configs.
📁 Config files are generated at plugins/PSGLogin/

⚙️ Paper — config.yml

Main settings file. Controls auth time, passwords, security, database and more.
plugins/PSGLogin/config.yml
# ── PROXY MODE ── set false for standalone Paper
proxy:
  enabled: false

# ── AUTH TIME ── seconds player has to login before kick
# Set 0 to disable the time limit entirely
main:
  auth-time: 60
  min-password-length: 6
  max-password-length: 32
  register-confirm-password: true  # /register <p> <p> or /register <p>
  ip-limit-registrations: 3       # max accounts per IP

# ── AUTO LOGIN ── same IP reconnect skips login
auto-login:
  enabled: true
  expiry-seconds: 86400  # 86400=24h  43200=12h  0=unlimited

# ── PREMIUM ── Mojang accounts skip login (online-mode only)
premium:
  enabled: false  # set true only if server is in online-mode

# ── BEDROCK ── Floodgate/Geyser players skip login
bedrock:
  auto-login: true

# ── SECURITY ──
security:
  brute-force:
    max-attempts: 5       # failed logins before account lock
    lock-duration: 300    # seconds account stays locked
    ip-max-attempts: 10   # failed logins before IP ban
    ip-ban-duration: 600  # seconds IP stays banned
  anti-bot:
    enabled: true
    max-joins-per-ip: 3   # max joins from one IP per window
    time-window: 10       # seconds for the window

🎨 Paper — messages.yml

Every message, title, boss bar and action bar is configurable here. Supports hex colors.
plugins/PSGLogin/messages.yml
# Change the plugin prefix shown in chat
prefix: "&8[&cPSGLogin&8]&r "

# Title shown after successful login (%player% = player name)
titles:
  success:
    title: "&a&lHi %player%"
    subtitle: "&aLogged in"
    fadeIn: 30   # ticks (20 ticks = 1 second)
    stay: 100
    fadeOut: 30

# Multiline chat message after login
messages:
  login-success: |
    &f
    &8[&a&l»&8] &7Welcome back, &a%player%&7!
    &f
  register-success: |
    &f
    &8[&a&l»&8] &7Welcome, &a%player%&7! Here are your commands:
    &f  &a&l» &7/changepassword &f  &a&l» &7/logout
    &f
💡 Use &#FF5733 for hex colors and | (pipe) in YAML for multiline messages.

📍 Set the Spawn Location

Where players are teleported after login. Stand at the location and run the command.
/psglogin setspawn       # sets spawn where you're standing
/psglogin setloginarea   # sets a separate login area (optional)
✔ After setting spawn, players will teleport there automatically after login or register.

⚡ Velocity + Paper — How It Works

In proxy mode, Velocity handles all authentication. Paper backends just receive a signal confirming the player is authenticated.
1. 👤 Player connects to Velocity
2. ⚡ Velocity sends them to NanoLimbo (blank void world)
3. 🌑 Player types /register or /login on NanoLimbo
4. ✅ Velocity authenticates them and sends them to Lobby (Paper)
5. 📨 Velocity sends an AUTH plugin message to the Paper server
6. 🏠 Paper marks the player as authenticated and shows the welcome message
⚠ Paper's LoginCommand and RegisterCommand are never triggered in proxy mode — auth happens entirely on Velocity.

🌑 Set Up NanoLimbo

NanoLimbo is a lightweight standalone limbo server. Players land here while unauthenticated.
nanolimbo/config.yml
  1. Download NanoLimbo.jar from its GitHub releases page.
  2. Create a new folder called nanolimbo and place the jar inside.
  3. Start it once: java -jar NanoLimbo.jar — it generates a config.
  4. Default port is 65535. Change it in config if needed.
  5. No other configuration is needed — it is just a void world.
⚠ Start NanoLimbo before Velocity. If Velocity starts first and NanoLimbo is offline, players will get kicked.

📋 Configure velocity.toml

Add your servers and set the try list so unauthenticated players land on NanoLimbo first.
velocity/velocity.toml
[servers]
# Name on the left must match limbo-server in velocity-config.yml
limbo  = "127.0.0.1:65535"  # NanoLimbo port
lobby  = "127.0.0.1:25577"  # Paper lobby port
pvp    = "127.0.0.1:25578"  # other Paper servers (optional)

# Players are sent here first when they connect
try = [
  "limbo"
]

# Must be false for offline-mode authentication to work
online-mode = false
⚠ The server names in [servers] must exactly match limbo-server and main-server in velocity-config.yml.

⚡ Install PSGLogin on Velocity

velocity/plugins/PSGLogin-velocity.jar
  1. Download PSGLogin-velocity.jar from the releases page.
  2. Place it in Velocity's /plugins/ folder.
  3. Start Velocity once to generate config files, then stop it.
  4. Config files are created at plugins/psglogin/

⚙️ Velocity — velocity-config.yml

Main config for Velocity. Controls which servers to use, auth time, security and database.
velocity/plugins/psglogin/velocity-config.yml
# ── SERVERS ── must match names in velocity.toml [servers]
limbo-server: limbo
main-server:  lobby

# ── AUTH TIME ── seconds before unauthenticated player is kicked
# Set 0 to disable
auth-time: 60

# ── DELAY ── ms to wait before sending AUTH to Paper after login
# Increase if players arrive on Paper before receiving the AUTH message
post-auth-message-delay: 1000

# ── PREMIUM ── Mojang accounts auto-login (Velocity online-mode)
premium:
  enabled: true

# ── BEDROCK ── Floodgate players auto-login
bedrock:
  auto-login: true

# ── AUTO LOGIN ── reconnect from same IP skips login
auto-login:
  enabled: true
  expiry-seconds: 86400  # 0 = never expires

# ── ACCESS TOKEN ── must match every Paper server's config.yml
# Generate any random 64-character string and paste it here
access-token: "CHANGE_ME_TO_A_RANDOM_64_CHAR_STRING"

# ── DATABASE ── SQLite for single server, MySQL for networks
database:
  type: MYSQL
  mysql:
    host: localhost
    port: 3306
    database: psglogin
    username: root
    password: yourpassword

🎨 Velocity — velocity-messages.yml

All messages shown on NanoLimbo while the player is authenticating. Fully customizable.
velocity/plugins/psglogin/velocity-messages.yml
# Prefix shown in all chat messages
prefix: "&8[&#FF4500&lPSGLogin&8]&r "

# Title shown while player needs to register
titles:
  register:
    title: "&#FF4500&lREGISTER"
    subtitle: "&#FFD700Use /register <password> <password>"
    interval: 4   # repeat every 4 seconds
  login:
    title: "&#FF4500&lLOGIN REQUIRED"
    subtitle: "&#FFD700Use /login <password>"
    interval: 4
  success:
    title: "&#00E676&lHi %player%"
    subtitle: "&#69F0AE&oLogged in"

# Chat message shown after login (multiline supported)
messages:
  login-success: |
    &f
    &8[&a&l»&8] &7Welcome back, &a%player%&7!
    &f
  register-success: |
    &f
    &8[&a&l»&8] &7Welcome, &a%player%&7!
    &f  &a&l» &7/changepassword  &a&l» &7/logout
    &f

📄 Install PSGLogin on Paper Backends

Every Paper server in your network needs PSGLogin installed and proxy mode enabled.
paperserver/plugins/PSGLogin-paper.jar
  1. Download PSGLogin-paper.jar and drop it into each Paper server's /plugins/ folder.
  2. Start each Paper server once to generate config files, then stop.
  3. Edit plugins/PSGLogin/config.yml on each server — see next step.
  4. Repeat for every backend: lobby, survival, pvp, creative, etc.
💡 You need PSGLogin-paper on every backend server, not just the lobby. All servers in the network need to be able to receive the AUTH message.

⚙️ Paper Backend — config.yml

Enable proxy mode and set the access token on every Paper backend server.
paperserver/plugins/PSGLogin/config.yml
# ── PROXY MODE ── MUST be true for Velocity setup
proxy:
  enabled: true
  # Must match access-token in velocity-config.yml EXACTLY
  access-token: "CHANGE_ME_TO_A_RANDOM_64_CHAR_STRING"

# ── DATABASE ── use same MySQL DB as Velocity for shared data
database:
  type: MYSQL
  mysql:
    host: localhost
    port: 3306
    database: psglogin   # same database name as Velocity
    username: root
    password: yourpassword
⚠ When proxy.enabled: true, Paper will NOT show any login prompts. All auth UI is handled by Velocity on NanoLimbo. Paper only waits for the AUTH signal.
✔ The messages.yml on Paper still controls what the welcome message looks like after the player arrives on the lobby server.

🚀 Start Order

Always start your servers in this order to avoid connection errors.
1

Start NanoLimbo

Must be online before Velocity tries to connect to it.

2

Start all Paper backends

Lobby, survival, pvp — all Paper servers must be up before Velocity.

3

Start Velocity

Velocity connects to all backends on startup. Players can now join.

✔ Players can now join through Velocity, authenticate on NanoLimbo, and be sent to your lobby automatically.

🗄️ Database — SQLite

Default option. No setup needed. Data is stored in a local file. Best for single Paper servers.
database:
  type: SQLITE
⚠ SQLite cannot be shared between servers. If you have multiple Paper backends, use MySQL instead.

🗄️ Database — MySQL

Recommended for Velocity networks. All servers share the same database so player data is consistent everywhere.
database:
  type: MYSQL
  mysql:
    host: localhost       # your database server IP
    port: 3306           # default MySQL port
    database: psglogin  # database name (create it first)
    username: root
    password: yourpassword
    pool-size: 10
✔ Use the exact same database name, username and password on Velocity AND all Paper backends so they all read/write the same data.

FAQ
Common questions and answers
How do I generate a 64-character access token?
You can generate one using any of these methods:

Online: Go to generate.plus/en/base64 or uuidgenerator.net and generate a random string of at least 64 characters.

Windows (PowerShell):
-join ((48..57+65..90+97..122) | Get-Random -Count 64 | % {[char]$_})

Linux / Mac (terminal):
openssl rand -hex 32

Paste the result as access-token in both velocity-config.yml and every Paper server's config.yml. They must match exactly.
Players get kicked saying "limbo server not found"
Make sure NanoLimbo is running before Velocity starts. The server name in velocity.toml [servers] must exactly match limbo-server in velocity-config.yml.
Players authenticate but still can't move on the Paper server
Make sure proxy.enabled: true is set in Paper's config.yml and the access-token matches exactly between Velocity and Paper.
/psglogin status shows "not registered" in proxy mode
This resolves itself after the player logs in once. The first AUTH message from Velocity syncs their data into Paper's database automatically.
I have multiple Paper servers — do they share player data?
Yes, if you configure MySQL and point all servers to the same database. With SQLite each server has its own local file and data is not shared.
Does this work with Geyser / Floodgate (Bedrock players)?
Yes. Set bedrock.auto-login: true and Bedrock players are automatically authenticated without needing a password.
Can I use this on 1.21.x / latest Paper builds?
Yes. PSGLogin supports Paper 1.18 through the latest 1.21.x builds including the new Paper build numbering format (e.g. 26.1.2).
Does it work on Purpur or Spigot?
Yes. Purpur, Pufferfish and Spigot are all supported. Paper is recommended for best performance.
How do I set up 2FA?
Players run /2fa enable, scan the QR code URL in an authenticator app (Google Authenticator, Authy, etc.), then use /login <password> <code> to login with 2FA.