promotional bannermobile promotional banner
premium banner
Granular permission system for NeoForge — grant vanilla commands to non-op players

Description

Minecraft 1.21.1 | NeoForge 21.1.221+ | Java 21 | MIT License | Version 1.0.0


Why this mod

Vanilla Minecraft has a binary system: a player is either op (every command) or non-op (no management commands). No middle ground.

CustomPerm lets you grant precisely the commands you want to non-op players, without giving them full op.

Examples:

  • You want a player to use /gamemode spectator but not /op? Done.
  • Grant /give to a VIP rank without enabling /ban? Done.
  • Build macros (aliases) that chain multiple commands into one? Done.
  • Keep the original safety checks of sensitive modded commands while still using CustomPerm permission nodes? Done.

The mod natively integrates with LuckPerms if installed, otherwise it ships its own JSON-backed grade system.


Features

  • Granular permissions on any command — vanilla or third-party mod, no patching required.
  • LuckPerms soft-dependency — uses LP automatically when present, otherwise uses the internal JSON backend.
  • Secure LuckPerms fallback — if LuckPerms is present but unavailable, CustomPerm fails closed by default.
  • Configurable fallback mode — choose deny or internal through settings.json.
  • Original command safety preservation — sensitive commands can keep their original Brigadier requires predicate with preserveOriginalRequires.
  • Wildcardscustomperm.command.* covers every exposed command.
  • Aliases and macros — create freely-named commands such as /fly, /heal, /spawn that fire one or many commands.
  • Hot-reload — every config change applies through /customperm reload, no server restart needed.
  • Auto re-sync — when a permission changes via LuckPerms, the player's command tree is refreshed automatically.
  • Diagnostic tooling/customperm debug, /customperm test, /customperm scan, /customperm status.
  • Op preserved — operators always retain access to all vanilla commands; the mod never strips their rights.
  • Server-side only — no client mod required.
  • Battle-tested — 28 automated GameTests plus a 24-step manual release procedure.

Installation

Requirements

  • Minecraft 1.21.1
  • NeoForge 21.1.221 or newer
  • Java 21
  • Optional: LuckPerms 5.4.150+ for NeoForge

Steps

  1. Download customperm-1.0.0.jar from the Files tab on this page.
  2. Drop the jar into your server's mods/ folder.
  3. Optional: drop the LuckPerms jar for NeoForge 1.21.1 alongside.
  4. Start the server.

At boot you will see one of these lines depending on configuration:

  • [CustomPerm] LuckPerms detected — using LuckPerms backend.
  • [CustomPerm] LuckPerms not present — using internal JSON grade backend.

Followed by the readiness summary:

  • [CustomPerm] Ready — backend=LuckPerms dispatcherCommands=89 exposed=0 aliases=0 grades=0

If you see neither line, the mod failed to load. Check your logs for stack traces.


Quick start

With LuckPerms

  1. Run customperm command add gamemode
  2. Run lp creategroup vip
  3. Run lp group vip permission set customperm.command.gamemode true
  4. Run lp user Steve parent add vip

Steve can now use /gamemode creative even though he is not op.

Without LuckPerms

  1. Run customperm command add gamemode
  2. Run customperm grade create vip
  3. Run customperm grade addperm vip customperm.command.gamemode
  4. Run customperm grade assign Steve vip

Same outcome: Steve can use /gamemode.


Commands

All admin commands live under /customperm and require op level 2.

Command exposure

Command Description
/customperm command add <name> Exposes <name> to the system.
/customperm command remove <name> Removes the command and reverts to vanilla/modded behavior.
/customperm command list Lists currently exposed commands.

Aliases and macros

Command Description
/customperm alias add <name> <cmd1; cmd2; ...> Creates an alias. Inner commands are separated by ;.
/customperm alias addstep <name> <cmd> Appends a step, creating the alias if absent.
/customperm alias removestep <name> <index> Removes the step at the given 0-based index.
/customperm alias steps <name> Shows all steps with their indices.
/customperm alias remove <name> Deletes the alias entirely.
/customperm alias list Lists all defined aliases.

Grades

Internal grade commands are available only when LuckPerms is not active. When LuckPerms is active, use /lp instead.

Command Description
/customperm grade create <name> Creates an empty grade.
/customperm grade delete <name> Deletes a grade and unassigns it from every user.
/customperm grade addperm <grade> <node> Adds a permission node to the grade.
/customperm grade removeperm <grade> <node> Removes a node.
/customperm grade assign <player> <grade> Assigns the grade to a player.
/customperm grade unassign <player> <grade> Unassigns a grade from a player.
/customperm grade list Lists defined grades.

Diagnostics and utilities

Command Description
/customperm test <player> <node> Verifies whether a player holds a permission node. Returns GRANTED or DENIED.
/customperm debug <player> <command> Detailed report: dispatcher presence, exposure state, op-level, permission result, preserveOriginalRequires, and wrapper decision.
/customperm status Global snapshot: backend, fallback mode, wrapped commands, exposed commands, aliases, grades.
/customperm scan [pattern] Lists every command in the dispatcher with its state. Optional substring filter.
/customperm reload Reloads config files from disk.

Permission nodes

Node Description
customperm.command.<name> Authorizes command <name>, only effective if exposed. Example: customperm.command.gamemode.
customperm.command.* Wildcard: covers every exposed command.
customperm.alias.<name> Authorizes alias <name>. Example: customperm.alias.fly.
customperm.alias.* Alias wildcard.
* Global wildcard. Use with extreme caution.

Important: customperm.command.<name> only grants <name> if it has been exposed via /customperm command add <name>. Otherwise the command keeps its vanilla/modded behavior.


Configuration files

Configuration files are stored in config/arcadia/customperm/.

If an older config/customperm/ directory exists and the new directory does not, CustomPerm copies the known config files into the new location without deleting the old files.

Main files:

  • grades.json: internal grades and player assignments
  • aliases.json: custom command aliases and macro steps
  • commands.json: exposed commands and command safety options
  • settings.json: runtime safety settings

settings.json

Recommended default for public servers:

{"luckPermsFallbackMode":"deny"}

Available fallback modes:

  • deny: recommended default. Permission checks fail closed if LuckPerms is present but unavailable.
  • internal: compatibility mode. Falls back to the internal grades.json backend.

commands.json

Example:

{"grantedCommands":["gamemode","time","adminpanel"],"preserveOriginalRequires":{"gamemode":false,"time":false,"adminpanel":true}}

preserveOriginalRequires lets sensitive commands keep their original Brigadier permission predicate in addition to the CustomPerm permission node.

Behavior in this example:

  • /gamemode and /time are available to players with the corresponding CustomPerm permission, or to op level 2+ sources.
  • /adminpanel requires both the CustomPerm permission and the command's original Brigadier requires predicate.
  • Missing preserveOriginalRequires entries default to false.

aliases.json

Example:

{"aliases":{"fly":["gamemode spectator"],"heal":["effect give @s minecraft:instant_health 10 100","effect give @s minecraft:saturation 1 100","say healed!"]}}

grades.json

Internal mode only. When LuckPerms is active, permissions are managed through LuckPerms instead.

Example:

{"grades":{"vip":{"name":"vip","permissions":["customperm.command.gamemode","customperm.alias.fly"]},"staff":{"name":"staff","permissions":["customperm.command.*","customperm.alias.*"]}},"userGrades":{"<player1-uuid>":["vip"],"<player2-uuid>":["staff","vip"]}}}


Common workflows

Grant /gamemode to a VIP rank

With LuckPerms:

  1. Run customperm command add gamemode
  2. Run lp creategroup vip
  3. Run lp group vip permission set customperm.command.gamemode true
  4. Run lp user <player> parent add vip

Without LuckPerms:

  1. Run customperm command add gamemode
  2. Run customperm grade create vip
  3. Run customperm grade addperm vip customperm.command.gamemode
  4. Run customperm grade assign <player> vip

Create a /fly shortcut that switches to spectator

With LuckPerms:

  1. Run customperm alias add fly gamemode spectator
  2. Run lp group vip permission set customperm.alias.fly true

Without LuckPerms:

  1. Run customperm alias add fly gamemode spectator
  2. Run customperm grade addperm vip customperm.alias.fly

Healing macro with several effects

  1. Run customperm alias add heal effect give @s minecraft:instant_health 10 100; effect give @s minecraft:saturation 1 100; effect give @s minecraft:regeneration 30 2
  2. Run lp group vip permission set customperm.alias.heal true

Grant several commands at once

  1. Run customperm command add gamemode
  2. Run customperm command add give
  3. Run customperm command add tp
  4. Run customperm command add effect
  5. Run lp group staff permission set customperm.command.* true

Allow only /gamemode spectator, not creative

  1. Run customperm alias add spec gamemode spectator
  2. Run lp group vip permission set customperm.alias.spec true

Players use /spec instead of /gamemode spectator. The real /gamemode can remain unexposed.

Preserve the original safety check of a sensitive command

In commands.json, use:

{"grantedCommands":["adminpanel"],"preserveOriginalRequires":{"adminpanel":true}}

With this setting, /adminpanel requires both:

  • customperm.command.adminpanel
  • the command's original Brigadier requires predicate

Use this for sensitive modded commands that perform their own permission or context checks.


Security considerations

Everything inside an alias runs with op-4 authority. Never put commands inside an alias that you would not trust the player to execute with full operator power, for example:

  • op @s — the player permanently becomes op
  • whitelist remove ..., ban ... — moderation tooling
  • gamerule keepInventory false — mutates server-wide state
  • data modify ... — mutates entities or blocks

Best practice: regularly audit your aliases with customperm alias list and customperm alias steps <name>.

customperm.command.* covers every exposed command. If you expose /op or /whitelist, the wildcard covers them too. Prefer explicit nodes for sensitive commands.

For public servers using LuckPerms, keep {"luckPermsFallbackMode":"deny"} in settings.json.

This avoids accidentally granting access through the internal backend if LuckPerms is present but unavailable.


Diagnostics and troubleshooting

The mod isn't loading

Check the boot log. The line [CustomPerm] Ready — must appear.

If LuckPerms is present but initialization fails, settings.json decides the behavior:

  • deny: fail closed
  • internal: fallback to grades.json

Check that your LuckPerms version is compatible: 5.4.150+.

An exposed command doesn't work for an authorized player

Run /customperm debug <player> <command>.

This shows whether the command exists, whether it is exposed, whether the player has the permission node, whether preserveOriginalRequires is active, and whether the final wrapper allows the command.

Verify a permission is actually granted

Run /customperm test <player> <node>.

Player can't see the command in autocomplete

The mod auto-resyncs when permissions change. If needed, the player can disconnect/reconnect, or the admin can run /customperm reload.


Known limitations

  • No sub-command granularity: customperm.command.gamemode covers every sub-mode. To split behavior, use aliases.
  • No alias parameters: an alias is a no-argument command. Use selectors like @p or create multiple explicit aliases as a workaround.
  • No GUI: administration is command-driven. For a graphical interface, use the LuckPerms web editor.

Compatibility

  • Minecraft 1.21.1
  • NeoForge 21.1.221+
  • Java 21
  • LuckPerms 5.4.150+ optional

License

MIT — see the GitHub repository for the full license text.


Credits

  • NeoForge for the modding framework.
  • LuckPerms for the inspiration and clean integration API.
  • Brigadier by Mojang for the underlying command system.