esx_whitelist
Set up esx_whitelist for ESX Legacy. Identifier and Discord role whitelist, admin-only mode, bypass list, in-game panel, commands, config and SQL.
esx_whitelist controls who can connect to an ESX Legacy server. It checks players during playerConnecting against a database identifier list, Discord guild roles, or both, and adds an admin-only maintenance mode, an emergency bypass list, Discord webhook logging and an in-game admin panel. It ships disabled, so installing it changes nothing until you enable it.
Overview
| Fact | Value |
|---|---|
| Resource | esx_whitelist |
| Side | Server (connection check) + client (admin panel NUI) |
| Dependencies | oxmysql, esx_lib, es_extended |
| Database | esx_whitelist_config, esx_whitelist_identifiers (created automatically) |
| Version | 1.16.3 (shipped with ESX Legacy 1.16.4) |
Installation
Import the SQL (optional)
Import whitelist.sql. The resource also creates missing tables and indexes on start, so this step is optional.
Add convars and ensure the resource
Secrets must use set (server only). UI convars must use setr so the client can read them.
set discord:botToken "YOUR_DISCORD_BOT_TOKEN" # only for discord/both mode
set whitelist:webhook "https://discord.com/api/webhooks/..." # optional logging
setr esx:ui:logoUrl "https://example.com/logo.png" # optional panel logo
ensure oxmysql
ensure esx_lib
ensure es_extended
ensure esx_whitelistConfigure and enable
Edit config/main.lua: pick a Mode, add identifiers or Discord roles, then set Config.Whitelist.Enabled = true. You can also do all of this later in the /whitelist panel.
Never put the bot token in config or client files
The token is read only from the discord:botToken convar. Keep it out of config/main.lua (it is a shared script and is sent to clients) and out of public repositories.
How a connection is checked
Every connection runs through the same order. The first matching rule decides:
0. Whitelist disabled -> allow
1. Bypass identifiers -> allow (method: bypass)
2. Admin-only mode enabled -> allow/deny (skips everything below)
3. Cached admin group -> allow (method: admin_group)
4. Mode-specific check -> allow/deny
5. Default -> deny (fail closed)| Mode | Behavior |
|---|---|
identifier | One of the player's identifiers is in the whitelist list. |
discord | The player has a linked Discord identifier, is a member of GuildId, and has at least one role from AllowedRoles. |
both + CombinationMode = 'or' | Identifier match or Discord verification. |
both + CombinationMode = 'and' | Identifier match and Discord verification. |
Admin groups are read from the group column of the ESX users table (matched via the esx:identifier convar, default license) and updated live on esx:playerLoaded and esx:setGroup. If the database is not ready within 15 seconds, the player is rejected with a verification error.
Configuration
All keys live in config/main.lua. Values changed in the panel are saved to esx_whitelist_config and override the file.
General
| Key | Default | Description |
|---|---|---|
Config.Locale | GetConvar('esx:locale', 'en') | Language. Only en ships with the resource. |
Config.IdentifierTypes | { license2 = true, license = true, fivem = true } | Identifier prefixes accepted for access lists. ip is always rejected. |
Config.Debug | false | Print extra logs to the server console. |
Config.Whitelist
| Key | Default | Description |
|---|---|---|
Enabled | false | Master switch. When false, everyone may connect and no checks run. |
Mode | 'identifier' | 'discord', 'identifier' or 'both'. |
CombinationMode | 'or' | How both combines the checks: 'or' or 'and'. |
AllowedIdentifiers | {} | Initial identifier list, imported once into esx_whitelist_identifiers (type whitelist). |
Config.Discord
| Key | Default | Description |
|---|---|---|
Enabled | false | Perform Discord verification. |
GuildId | '' | Discord server id the player must be a member of. |
AllowedRoles | {} | Role ids; the member needs at least one. |
Timeout | 5000 | Per-request HTTP timeout (ms). |
CacheTTL | 60 | Seconds a verified result may be reused. 0 disables the cache. |
CacheMaxEntries | 10000 | Max cached Discord results. |
RequestsPerSecond | 40 | Outbound request smoothing, in addition to Discord rate-limit headers. |
MaxRetries | 2 | Retries for timeouts, 5xx and network errors. |
RetryBaseDelay | 750 | First retry delay (ms), doubled per attempt. |
RetryMaxDelay | 4000 | Max retry delay (ms). |
Config.Admin
| Key | Default | Description |
|---|---|---|
Groups | { admin = true, superadmin = true, owner = true } | ESX groups that may use the panel and commands, and that bypass the normal whitelist. |
IdentifierPriority | { 'license2', 'license', 'fivem' } | Order used to pick the stable identifier for cache keys. |
Cache.Enabled | true | Enable the admin group cache. |
Cache.SaveDelay | 5000 | Kept for panel compatibility. Admin decisions are not persisted. |
Config.AdminOnly
| Key | Default | Description |
|---|---|---|
Enabled | false | Maintenance mode: only these groups or identifiers may connect. |
Groups | { admin = true, superadmin = true, owner = true } | Groups allowed in admin-only mode. |
AllowedIdentifiers | {} | Identifiers allowed in admin-only mode (imported once, type admin_only). |
Config.Bypass
| Key | Default | Description |
|---|---|---|
AllowedIdentifiers | {} | Emergency list checked before everything else, even admin-only mode (imported once, type bypass). Keep it tiny. |
Config.Logging
The webhook URL comes from the whitelist:webhook convar.
| Key | Default | Description |
|---|---|---|
Enabled | true | Send events to the webhook (only if the convar is set). |
MinInterval | 1200 | Minimum ms between webhook requests. |
BatchSize | 5 | Events sent per cycle. |
QueueLimit | 250 | Max queued events; the oldest are dropped. |
Levels | { info = true, warning = true, error = true, security = true } | Severities that are sent. |
Config.Performance
| Key | Default | Description |
|---|---|---|
DiscordConcurrency | 10 | Max simultaneous Discord API requests. |
DiscordQueueLimit | 4096 | Max pending Discord verifications. |
VerificationTimeout | 120000 | Hard limit (ms) for one connection check. |
PanelRateLimit | 10 | Panel actions allowed per window. |
PanelRateWindow | 5000 | Rate-limit window (ms). |
Config.Panel
| Key | Default | Description |
|---|---|---|
Command | 'whitelist' | Command name for the panel and subcommands. |
Subcommands | Panel = 'panel', Status = 'status', Reload = 'reload', Cache = 'cache', CacheClear = 'clear', Test = 'test', Add = 'add', Remove = 'remove' | Names of the subcommands. |
Commands
All commands work in the server console. In-game, the player's ESX group must be in Config.Admin.Groups; unauthorized attempts are logged as security events.
| Command | Description |
|---|---|
/whitelist or /whitelist panel | Open the admin panel (in-game only). |
whitelist status | Mode, admin-only state, Discord readiness and decision counters. |
whitelist reload | Reload runtime config and admin cache from the database, clear the Discord cache. |
whitelist cache | Cache and queue statistics. |
whitelist cache clear | Clear the Discord verification cache. |
whitelist test <serverId> | Run the full check against an online player. |
whitelist add <identifier> [type] | Add an identifier. type is whitelist (default), admin_only or bypass. |
whitelist remove <identifier> [type] | Remove an identifier from that list. |
whitelist add license2:1234567890abcdef1234567890abcdef12345678
whitelist add license:abcdef1234567890abcdef1234567890abcdef12 bypass
whitelist statusAdmin panel
/whitelist opens a NUI panel with the tabs Dashboard, Whitelist, Discord, Admins and Logging & Performance. Changes are validated on the server, rate limited, persisted to esx_whitelist_config and logged. The panel refuses changes to admin groups that would remove your own current group, so you cannot lock yourself out. Theme convars: esx:ui:logoUrl, esx:ui:primaryColor, esx:ui:secondaryColor, esx:ui:backgroundColor, esx:ui:accentColor (all setr).
Discord bot setup
- Create an application and bot at the Discord developer portal.
- Invite the bot to your guild with the
botscope. No special permissions are required; role checks use the guild member endpoint. - Enable Developer Mode in Discord, then copy the guild id and role ids into
GuildIdandAllowedRoles(or the panel). - Set
Config.Discord.Enabled = trueandConfig.Whitelist.Mode = 'discord'or'both'.
Players must have Discord running and linked to FiveM, otherwise they have no discord: identifier and are denied.
Database schema
CREATE TABLE IF NOT EXISTS `esx_whitelist_config` (
`setting_key` VARCHAR(64) NOT NULL,
`setting_value` LONGTEXT NOT NULL,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`setting_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `esx_whitelist_identifiers` (
`identifier` VARCHAR(128) NOT NULL,
`type` VARCHAR(32) NOT NULL DEFAULT 'whitelist',
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`identifier`, `type`),
KEY `idx_type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;type is one of whitelist, admin_only or bypass.
Exports and events
esx_whitelist has no public exports. Its net events (prefix esxwl:) are internal to the panel and command bridge. It listens to playerConnecting, playerDropped, esx:playerLoaded and esx:setGroup.
Common issues
Config.Whitelist.Enabled is false by default. Enable it in the config or panel, then check whitelist status. A value saved in the panel wins over the file.
The config lists are imported into the database only on the first start. After that, use whitelist add or the panel. Also make sure the prefix is allowed by Config.IdentifierTypes (default license2, license, fivem).
Check whitelist status for Discord: NOT READY. Common causes: missing or wrong discord:botToken, bot not in the guild, wrong GuildId, Config.Discord.Enabled = false, or the player has no linked Discord identifier. Discord failures fail closed.
Add your identifier from the server console: whitelist add license2:... bypass. Bypass is checked before admin-only mode.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_textui
esx_textui reference for ESX Legacy. Show a persistent help prompt like "Press E to open" with ESX.TextUI and ESX.HideUI, types, events and pitfalls.
esx_loadingscreen
esx_loadingscreen for ESX Legacy explained. How the loading screen works, how to change the logo, tips and texts, and how shutdown with multicharacter works.