RE:NODE

Minecraft12 min read

Minecraft whitelist and permissions: ops, groups and roles

Why operator is not a role, how the whitelist and ops.json really work, and a LuckPerms group ladder that survives a community growing.

Updated

0 readers

Operator is not a role. It is total control - stop the server, edit the world, grant operator to somebody else - and handing it out because a friend needed to change the time of day is how servers get wrecked by people who meant well. The setup that works is three things: a whitelist so there are no strangers, a permissions plugin so ranks are groups rather than a list of exceptions, and exactly as few operators as the server actually needs, which is usually one.

This post covers all three with the real files and the real commands: whitelist.json and ops.json, the four operator levels and why Bukkit ignores most of them, LuckPerms from install to a working group ladder, the nodes you will type most often, and how to find out which permission is actually missing instead of guessing.

Operator is not a permission system#

Vanilla has four operator levels, set per player in ops.json:

LevelWhat it unlocks
1Bypasses spawn protection. Nothing else
2/gamemode, /give, /tp, /summon, /setblock, /effect, /gamerule, command blocks
3/ban, /kick, /op, /deop, /whitelist, /pardon
4/stop, /save-off, /debug - everything
ops.json
[  {    "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",    "name": "Notch",    "level": 2,    "bypassesPlayerLimit": false  }]

/op <player> always grants at the level in op-permission-level in server.properties, which defaults to 4. To give somebody level 2 you edit the file. function-permission-level (default 2) is the separate level that functions and datapacks run at, and bypassesPlayerLimit lets that player in when the server is full.

Here is the part that makes the whole tier system close to useless on a real server: Bukkit, Spigot and Paper do not honour the levels for plugin permissions. Almost every plugin declares its permissions with a default of op, which means any operator has all of them regardless of whether they are level 1 or level 4. Op your new moderator at level 2 to be careful and you have also given them WorldEdit, every EssentialsX command, and the ability to roll back the world with CoreProtect.

So the rule is simple and it is worth being strict about it. Operators are for the person who administers the box. Everybody else - moderators, builders, donors, trusted regulars - gets a group in a permissions plugin and no operator status at all. When you need to run something once, run it from the panel console: the console is always level 4 and holds every permission, so you never need to op yourself for a single command. Reading the console covers what else it is good for, and the server command cheatsheet has the commands themselves.

The whitelist, exactly#

A whitelisted server has no griefing problem because it has no strangers. For a server run for friends, that one setting replaces most of the plugin list people install instead. It is the cheapest moderation there is.

server.properties
white-list=trueenforce-whitelist=trueonline-mode=true

white-list turns it on. enforce-whitelist is the one people miss: with it false, turning the whitelist on or reloading it does not remove anyone who is already connected, so the player you just took off the list stays until they log out. Set it true and a reload kicks everyone not on the list immediately.

CommandWhat it does
whitelist on / whitelist offToggles enforcement, and writes white-list back to the properties file
whitelist add <name>Looks the name up, resolves the UUID, appends to whitelist.json
whitelist remove <name>Removes the entry
whitelist listPrints the current names
whitelist reloadRe-reads whitelist.json from disk after a hand edit

The file itself is small:

whitelist.json
[  { "uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5", "name": "Notch" }]

Two behaviours worth knowing. Operators bypass the whitelist entirely, which is convenient and also means an old operator entry is a way in that the whitelist will not close - audit ops.json when you audit the whitelist. And whitelist off does not clear the list, so turning it back on restores exactly the same set of people; there is no reason to delete entries when opening the server for an event.

UUIDs, offline mode and the whitelist that will not work

whitelist add works for a player who has never joined because the server asks Mojang for the UUID behind the name. That lookup needs the server to reach the internet, and it needs the name to exist. "That player does not exist" is almost always a typo, a name that was changed, or a Bedrock gamertag being typed at a Java server.

With online-mode=false nothing is verified. UUIDs are generated from the username instead of being issued by Mojang, so a whitelist entry written while online-mode was on will not match the same player after you switch it off, and anybody can connect as any name that is on the list. Offline mode belongs behind a proxy with proper forwarding and nowhere else. If you are running one, read what a reverse proxy does and get the forwarding secret right before you touch online-mode.

Bedrock players arriving through Geyser and Floodgate are a third case: they get a generated UUID and a prefixed username, so pasting their gamertag into whitelist.json by hand will not match. Floodgate ships its own whitelist command for exactly this reason - Geyser and Bedrock crossplay has the setup.

LuckPerms: groups, then permissions, then people#

LuckPerms is the permissions plugin. Install is a jar in plugins/ and a restart; it works on Paper, Velocity, Fabric, Forge and NeoForge, and it stores its data in an H2 file under plugins/LuckPerms/ by default. That default is fine for one server. If you run several that should share ranks, change storage-method in plugins/LuckPerms/config.yml to a SQL backend and point it at the credentials from the panel's database slot; a single shared store beats copying files between servers every time.

The model is three layers, and keeping them separate is the entire trick:

  1. A group holds permissions.
  2. A group can inherit another group, so you describe the difference rather than repeating the list.
  3. A user is put into a group and given nothing directly.

Define a small number of groups, give each the specific commands it needs, and put people in groups. It takes twenty minutes once and saves you from a list of individual exceptions nobody can audit six months later. The moment you find yourself granting a node to one person, ask what group that person is really in.

The first five minutes
lp creategroup trustedlp creategroup moderatorlp creategroup adminlp group trusted parent add defaultlp group moderator parent add trustedlp group admin parent add moderatorlp group trusted setweight 10lp group moderator setweight 50lp group admin setweight 100lp user Alex parent set moderator

default is the group everyone is in and cannot be deleted. Weight decides which group's prefix and suffix win when somebody is in several; it has nothing to do with which permissions apply, which is decided by inheritance and by explicit false nodes beating inherited true ones.

/lp editor is worth knowing about before you type fifty permission set commands. It uploads your current setup to a one-time web page, you drag permissions around in a table, and you paste the code back as /lp applyedits <code>. Nothing is public and nothing is stored beyond the edit. The full tour is in the LuckPerms guide.

A group ladder that works#

Four groups cover almost every community. Add more only when someone can say which specific permission the new group has that the one below it does not.

GroupWhoWhat they can do
defaultEveryonePlay. Chat, /spawn, one home
trustedRegulars, after a whileQuality-of-life commands, more homes, kits
moderatorStaffKick, mute, tempban, inspect who did what
adminYou, and maybe one otherEverything except the panel account
Filling them in
lp group default permission set essentials.spawn truelp group default permission set essentials.home truelp group default permission set essentials.sethome truelp group trusted permission set essentials.sethome.multiple.trusted truelp group trusted permission set essentials.tpa truelp group trusted permission set essentials.back truelp group moderator permission set essentials.kick truelp group moderator permission set essentials.mute truelp group moderator permission set essentials.vanish truelp group moderator permission set coreprotect.inspect truelp group moderator permission set coreprotect.lookup truelp group admin permission set coreprotect.rollback truelp group admin permission set worldedit.* true

Three deliberate choices in that list. Moderators can look at the block log but not roll it back, because a rollback with the wrong radius is worse than the grief it was meant to undo. Nobody below admin gets WorldEdit, because WorldEdit is a world editor and an accident with //set is permanent. And essentials.gamemode is in neither list - creative mode on a survival server is an admin decision every time, not a convenience.

The permission nodes you will actually type#

Nodes are plugin-specific, so the authoritative list is always the plugin's own page. These are the ones that come up constantly:

NodeGives
minecraft.command.<name>A vanilla command on Paper, e.g. minecraft.command.gamemode
essentials.tp, essentials.tphereTeleport to and summon players
essentials.home, essentials.sethome.multiple.<group>Homes, and how many
essentials.kit.<name>One named kit
essentials.kick, essentials.ban, essentials.muteThe moderation trio
essentials.vanishLog in without announcing it
coreprotect.inspect, coreprotect.lookupRead the block log
coreprotect.rollback, coreprotect.restoreChange the world with it
worldedit.*All of WorldEdit
luckperms.*Manage permissions, including their own

Two tricks that save time. A node set to false beats the same node inherited as true, so you can build moderator on top of trusted and then take one thing back:

code
lp group moderator permission set essentials.tphere false

And a whole plugin can be switched off for a group in one line by negating its wildcard, then switching individual commands back on. That is usually cleaner than listing thirty nodes.

Contexts, tracks and time-limited access#

Contexts attach a permission to a condition - a world, a server in a proxy network, a game mode. They are how one LuckPerms setup serves a survival world and a creative world without two sets of groups:

code
lp group builder permission set worldedit.* true world=creativelp group default permission set essentials.fly true world=creative

Tracks are an ordered list of groups, which turns promotion into one command and makes the ladder visible:

code
lp createtrack memberslp track members append defaultlp track members append trustedlp track members append moderatorlp user Sam promote members

Temporary grants are the underrated feature. A guest builder for a weekend, a moderator covering while you are away, a donor rank with a month on it - all of them expire on their own, which means you do not have to remember to remove them:

code
lp user Sam parent addtemp moderator 14dlp user Guest permission settemp worldedit.* true 48h

That habit is the same one worth having on the hosting account itself, where access should be granted for as long as the job takes and no longer. Subusers and least privilege makes the same argument about the panel.

When somebody says they do not have permission#

Do not guess the node. LuckPerms will tell you which one was checked:

code
lp verbose on

Have the player run the command that fails, then:

code
lp verbose paste

You get a link listing every permission check that happened, who it was for, the node, and whether it returned true or false. The failing node is in there, spelled correctly, including the ones with a name or a number baked into them like essentials.sethome.multiple.5. Switch it off afterwards with lp verbose off, because it is chatty.

Other checks, in the order they usually pay off:

  • lp user <name> info shows their groups, their weight, their prefix, and any temporary entries with a countdown.
  • lp group <group> permission info lists what that group actually holds, including inherited nodes.
  • lp user <name> permission check <node> answers the direct question.

The four causes behind most of these tickets: the player is an operator so plugin defaults grant them everything and your groups are not doing anything; a second permissions plugin is installed and the two are fighting - pick one; the node is granted in a context that does not match the world they are standing in; or Vault is missing, so the chat plugin cannot read the prefix even though the permissions are correct.

Panel access is a different question#

In-game rank and hosting access are two separate systems, and conflating them is a real risk. A moderator needs to mute people. They do not need to be able to delete the server, read the billing page, or download the world.

On RE:NODE that separation is built in. A role holds permissions - console only, files only, no billing - a team holds people, and a grant joins a team to a server. Access can be time-boxed, invitations go out by link, join code or email, and every server keeps its own activity log, so "who restarted it at 2am" has an answer. Give your builder the file manager and nothing else; give your co-owner console and backups; keep billing to yourself. Add two-factor on the account and the worst case stops being catastrophic.

The same logic applies to RCON. If a Discord bot needs to run commands, it gets an RCON password on a restricted port, not an operator account - using RCON safely covers what that costs you if you get it wrong. And before you open the server to strangers at all, the rest of the list is in the SMP launch checklist and grief protection and anti-cheat.

FAQ#

Do I need a permissions plugin if I only play with friends?

If everyone is trusted and nobody needs commands, no - a whitelist and one operator is a complete setup. Install LuckPerms the first time you want someone to have /tp without also having /stop, which for most groups is about a month in.

Does the whitelist stop people who already joined?

Only with enforce-whitelist=true. With it off, the whitelist is checked at login, so anyone currently connected stays connected until they disconnect. Turn it on and whitelist reload removes them the moment you say so.

How do I whitelist someone who has never played on my server?

whitelist add <name> is enough. The server resolves the UUID from the name itself, so they do not need to join first. It fails only if the name is misspelled, the account does not exist, or the server cannot reach the internet.

Can a player be an operator and still be restricted by LuckPerms?

Not in any way you can rely on. Operator status satisfies the op default that most plugin permissions use, so an op passes almost every check before your groups are consulted. Deop your staff and give them a group instead.

What happens to permissions when the server restarts?

They persist - LuckPerms writes to its own storage immediately, not at shutdown. The files that are rewritten at shutdown are the vanilla ones: ops.json, whitelist.json and the ban lists. Edit those with commands, or with the server stopped.

Should moderators be able to roll back the world?

Give them the lookup and inspect permissions and keep the rollback for admins. Reading the log is how you find out what happened; rolling back is a destructive edit with a radius and a time window, and getting either wrong undoes legitimate building along with the grief.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000