
CustomPerm
Granular permission system for NeoForge — grant vanilla commands to non-op players
About this Mod
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 spectatorbut not/op? Done. - Grant
/giveto 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
denyorinternalthroughsettings.json. - Original command safety preservation — sensitive commands can keep their original Brigadier
requirespredicate withpreserveOriginalRequires. - Wildcards —
customperm.command.*covers every exposed command. - Aliases and macros — create freely-named commands such as
/fly,/heal,/spawnthat 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
- Download
customperm-1.0.0.jarfrom the Files tab on this page. - Drop the jar into your server's
mods/folder. - Optional: drop the LuckPerms jar for NeoForge 1.21.1 alongside.
- 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
- Run
customperm command add gamemode - Run
lp creategroup vip - Run
lp group vip permission set customperm.command.gamemode true - Run
lp user Steve parent add vip
Steve can now use /gamemode creative even though he is not op.
Without LuckPerms
- Run
customperm command add gamemode - Run
customperm grade create vip - Run
customperm grade addperm vip customperm.command.gamemode - 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 assignmentsaliases.json: custom command aliases and macro stepscommands.json: exposed commands and command safety optionssettings.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 internalgrades.jsonbackend.
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:
/gamemodeand/timeare available to players with the corresponding CustomPerm permission, or to op level 2+ sources./adminpanelrequires both the CustomPerm permission and the command's original Brigadierrequirespredicate.- Missing
preserveOriginalRequiresentries default tofalse.
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:
- Run
customperm command add gamemode - Run
lp creategroup vip - Run
lp group vip permission set customperm.command.gamemode true - Run
lp user <player> parent add vip
Without LuckPerms:
- Run
customperm command add gamemode - Run
customperm grade create vip - Run
customperm grade addperm vip customperm.command.gamemode - Run
customperm grade assign <player> vip
Create a /fly shortcut that switches to spectator
With LuckPerms:
- Run
customperm alias add fly gamemode spectator - Run
lp group vip permission set customperm.alias.fly true
Without LuckPerms:
- Run
customperm alias add fly gamemode spectator - Run
customperm grade addperm vip customperm.alias.fly
Healing macro with several effects
- 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 - Run
lp group vip permission set customperm.alias.heal true
Grant several commands at once
- Run
customperm command add gamemode - Run
customperm command add give - Run
customperm command add tp - Run
customperm command add effect - Run
lp group staff permission set customperm.command.* true
Allow only /gamemode spectator, not creative
- Run
customperm alias add spec gamemode spectator - 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
requirespredicate
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 opwhitelist remove ...,ban ...— moderation toolinggamerule keepInventory false— mutates server-wide statedata 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 closedinternal: fallback togrades.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.gamemodecovers every sub-mode. To split behavior, use aliases. - No alias parameters: an alias is a no-argument command. Use selectors like
@por 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.
Available Versions
How to Install CustomPerm on Your Server
Order Server
Order a Minecraft Java server with at least 3 GB RAM (4 GB recommended).
Set neoforge Loader
In the panel under "Egg", select the neoforge loader and matching Minecraft version (1.21.1).
Install Mod
Open the mod browser in the dashboard and search for "CustomPerm". Click "Install" – done! Alternatively, upload the .jar via SFTP to the /mods folder.
Compatibility
Mod Loaders
Minecraft Versions
1.21.1
Server-side
✓ RequiredRecommended RAM
4 GB(min. 3 GB)Frequently Asked Questions
CustomPerm server crashes on startup – what to do?
Most common cause: wrong neoforge version or insufficient RAM. Check the server log (latest.log) for "OutOfMemoryError" or "Mixin" errors. With Mado Hosting: ensure at least 3 GB RAM is allocated and the loader matches the mod version (1.21.1). You can switch loaders with one click in the panel.
Is CustomPerm compatible with neoforge?
CustomPerm officially supports neoforge for Minecraft 1.21.1. The Mado dashboard automatically detects incompatible loader combinations.
Server lagging with CustomPerm – how to optimize performance?
Recommended RAM: 4 GB (per 8 players). Use /spark profiler to check if CustomPerm consumes the most tick time. Common fixes: reduce server view-distance to 8-10, install "performant" or "starlight" as supplementary mods on Forge. With Mado Hosting, your server runs on NVMe SSDs with dedicated CPU cores for minimal latency.
Rent Modded Server
Install CustomPerm with just one click on your server.