NexusPermissions
Administration v1.1.0Permissions plugin with groups, inheritance, per-world and per-region contexts, timed permissions, Vault, PlaceholderAPI, and promote/demote ladders.
NexusPermissions
NexusPermissions is a permissions plugin. It provides groups, users, inheritance, per-world, per-server and per-region contexts, timed permissions, and promote/demote ladders, all managed from in-game commands and stored in plain YAML that you can read and edit by hand.
The design is simple: everything is a subject. Users and groups are both subjects, both hold permissions, both can have parents. A user’s effective permissions are the result of walking their parent chain from lowest-weight to highest-weight, then applying their own entries on top.
Work in progress. NexusPermissions is under active development. The core feature set is functional and tested, but the command surface and config schema may still change between releases. Back up your
groups.ymlandusers.ymlbefore upgrading.
Features
- Users and groups, both first-class subjects.
- Multi-parent inheritance with cycle detection.
- Per-world, per-server, and per-region contexts. A permission can be granted in one world, one WorldGuard region, or nowhere at all.
- Group weight determines priority (lower weight wins).
- Negation via a
-prefix in config files. - Timed permissions. Grant a node for a fixed duration and it expires on its own.
- Ladders for
promoteanddemote, with automatic ladder detection when only one is defined. - Options for prefix, suffix, weight, and any custom key you want.
- Wildcards like
essentials.*and*are supported through Bukkit’s native permission lookup. - Vault integration: registers as the server’s permission and chat provider when Vault is present.
- PlaceholderAPI expansion:
%nexus_prefix%and friends, for any plugin that prefers placeholders over Vault. - Public API:
Bukkit.getServicesManager().load(NexusAPI.class)for other plugins. - UUID-based user storage. Legacy name-keyed entries are migrated automatically the first time each player joins.
- Optional audit log so admins can see who changed what and when.
- YAML storage that you can read and hand-edit.
Commands
| Command | Description | Permission |
|---|---|---|
/nexus / /nexus help |
Show help | nexus.command |
/nexus reload |
Reload all config files and reapply to online players | nexus.command + nexus.reload |
/nexus debug |
Toggle debug mode | nexus.command + nexus.debug |
/nexus user <user> info |
Show a user’s groups, options, and permissions | nexus.command + nexus.user.info |
/nexus user <user> groups |
Show just a user’s groups | nexus.command + nexus.user.info |
/nexus user <user> has <node> |
Check whether a user has a permission | nexus.command + nexus.user.info |
/nexus user <user> perm <node> <true\|false\|unset> [context] [temp:7d] |
Set a user permission | nexus.command + nexus.user.perm.set |
/nexus user <user> parent add <group> |
Add a user to a group | nexus.command + nexus.user.parent.add |
/nexus user <user> parent remove <group> |
Remove a user from a group | nexus.command + nexus.user.parent.remove |
/nexus user <user> option <key> <value\|unset> |
Set a user option | nexus.command + nexus.user.option.set |
/nexus user <user> delete |
Delete a stored user entry | nexus.command + nexus.user.delete |
/nexus group <group> create |
Create a group | nexus.command + nexus.group.create |
/nexus group <group> info |
Show a group | nexus.command + nexus.group.info |
/nexus group <group> members |
List stored members of a group | nexus.command + nexus.group.info |
/nexus group <group> perm <node> <true\|false\|unset> [context] [temp:7d] |
Set a group permission | nexus.command + nexus.group.perm.set |
/nexus group <group> parent add <group> |
Add a parent group | nexus.command + nexus.group.parent.add |
/nexus group <group> parent remove <group> |
Remove a parent group | nexus.command + nexus.group.parent.remove |
/nexus group <group> option <key> <value\|unset> |
Set a group option | nexus.command + nexus.group.option.set |
/nexus group <group> weight <number> |
Set a group’s weight | nexus.command + nexus.group.weight.set |
/nexus group <group> delete |
Delete a group | nexus.command + nexus.group.delete |
/nexus rename user <old> <new> |
Rename a stored user | nexus.command + nexus.user.rename |
/nexus rename group <old> <new> |
Rename a group and fix all references | nexus.command + nexus.group.rename |
/nexus promote <user> [ladder] |
Move a user up a ladder | nexus.command + nexus.promote |
/nexus demote <user> [ladder] |
Move a user down a ladder | nexus.command + nexus.demote |
/nexus rank <ladder> add <group> |
Add a group to the top of a ladder | nexus.command + nexus.rank.manage |
/nexus who <node> |
List users and groups that have a permission | nexus.command |
/nexus search <term> |
Search groups and users by name | nexus.command |
Tab completion covers every subcommand, every argument, and every option the sender has permission to use.
Contexts
A context scopes a permission to a specific world, server, or WorldGuard region. The context argument accepts these forms:
| Input | Interpreted as |
|---|---|
(omitted) or global |
Applies everywhere |
world_nether |
Shorthand for world:world_nether |
world:world_nether |
Full form |
server:lobby |
Server-wide context |
region:spawn |
WorldGuard region context |
When resolving a player’s effective permissions, the plugin consults, in
order: server:<server-name>, world:<current-world>,
region:<region-name> for each region the player is standing in, then
global. Later entries in the list override earlier ones, so a region-level
grant overrides a world-level one.
Region contexts require WorldGuard and are toggled with
region-context.enabled in config.yml.
Configuration
config.yml
config-version: schema version for migration.debug: enable verbose logging.default-group: the group applied to users with no explicit parents.server-name: used to build theserver:<name>context.region-context.enabled: enable WorldGuard region contexts.audit-log.enabled: enable the audit log.timed-permission-sweep-seconds: how often to prune expired entries.ladders: named ladders for promote/demote.
ladders:
staff:
- "helper"
- "moderator"
- "admin"
- "owner"
donor:
- "supporter"
- "patron"
- "benefactor"
groups.yml
Every group’s definition. Keys use / as the YAML path separator, so
group names containing . are safe.
Each group supports:
options: arbitrary key-value pairs.weightandprefixare the two the plugin reads natively.permissions: a list of nodes. A leading-negates. A;suffix marks an expiry as epoch milliseconds. See the header comment in the bundled file for the exact format.contexts: a map of context name to permission list.parents: a list of parent group names.
groups:
default:
options:
prefix: "&7"
weight: 1000
parents: []
permissions:
- "essentials.spawn"
- "essentials.help"
- "-essentials.fly"
builder:
options:
prefix: "&a[Builder] &a"
weight: 500
parents:
- "default"
permissions:
- "essentials.gamemode.creative"
- "worldedit.wand"
contexts:
"world:creative":
- "essentials.fly"
moderator:
options:
prefix: "&8[&bMod&8] &b"
weight: 100
rank-ladder: "staff"
parents:
- "default"
permissions:
- "essentials.fly"
- "essentials.kick"
- "essentials.mute"
The bundled file also includes admin, supporter, and patron as
further examples, showing wildcards, negation, and a multi-tier donor
chain.
users.yml
Users are keyed by UUID. The name field is kept for readability. Users
who have never been edited live implicitly in the default group and have
no entry.
Legacy entries keyed by name are still read. The UUID is filled in the first time that player joins, and the entry is rewritten under the UUID on the next save.
users:
550e8400-e29b-41d4-a716-446655440000:
name: ExamplePlayer
parents:
- "default"
- "moderator"
550e8400-e29b-41d4-a716-446655440001:
name: ExampleDonor
options:
prefix: "&6&l[VIP] &6"
parents:
- "default"
- "patron"
550e8400-e29b-41d4-a716-446655440002:
name: ExampleRestricted
permissions:
- "-essentials.fly"
parents:
- "default"
- "patron"
Timed permissions
Any perm subcommand accepts an optional temp:<duration> argument.
/nexus user Chalwk perm essentials.fly true temp:7d
/nexus group moderator perm essentials.vanish true temp:30m
/nexus user Chalwk perm essentials.god true world_nether temp:1h
Supported duration suffixes are s (seconds), m (minutes), h (hours),
d (days), and w (weeks).
The expiry is enforced at resolution time, so the node stops applying the
moment it expires, even before the periodic sweep removes it from disk.
The sweep runs every timed-permission-sweep-seconds and also triggers a
save and online refresh when it removes anything.
To see the expiry of a node, use /nexus user <name> info or
/nexus group <name> info. The YAML stores it as a ; suffix on the
permission entry.
Vault and prefix display
When Vault is present, Nexus registers as both a permission provider and a chat provider. Plugins that read through Vault see the correct permissions and prefixes automatically.
Two things to be aware of when wiring this up to a chat or tab list plugin:
- Swap your plugin’s own prefix token for the Vault one. Some chat
plugins have a built-in prefix token (CMI’s
[prefix], for example) that reads from the plugin’s own rank system, not from Vault. Replace it with%vault_prefix%via PlaceholderAPI, or the native%nexus_prefix%described below. - Nexus returns prefixes with section-sign codes, not ampersands.
Consumers that translate
&codes themselves leave section signs alone. Consumers that don’t translate still render the colours.
PlaceholderAPI
When PlaceholderAPI is installed, Nexus registers a nexus expansion:
| Placeholder | Value |
|---|---|
%nexus_prefix% |
Resolved prefix, with section-sign colours |
%nexus_suffix% |
Resolved suffix, with section-sign colours |
%nexus_primary_group% |
Highest priority group name |
%nexus_groups% |
Comma separated group list, sorted by weight |
%nexus_group_count% |
Number of effective groups |
%nexus_has_<node>% |
true or false |
%nexus_option_<key>% |
Any option value |
Use these in CMI, tab list plugins, DeluxeMenus, and anywhere else that supports PAPI.
Public API
Other plugins can query Nexus directly:
NexusAPI api = Bukkit.getServicesManager().load(NexusAPI.class);
if (api != null) {
Map<String, Boolean> perms = api.getEffectivePermissions(player.getUniqueId(), player.getWorld().getName());
String prefix = api.getOption(player.getUniqueId(), "prefix");
List<String> groups = api.getGroups(player.getUniqueId());
}
Add softdepend: [NexusPermissions] to your plugin.yml. The API is
read-only. Mutations go through the /nexus commands.
Audit log
Set audit-log.enabled: true in config.yml to append a line to
plugins/NexusPermissions/audit.log for every mutation:
[2026-10-11 14:22:31] [Chalwk] user teddy perm essentials.fly true global
[2026-10-11 14:23:02] [Chalwk] group villager weight 200
[2026-10-11 14:24:15] [Chalwk] user teddy parent add artisan
Useful on servers with more than one admin.
Notes
- Users are keyed by UUID. Legacy name-keyed entries from earlier versions migrate automatically the first time each player joins after this update. Nothing is written on join; the entry is rewritten under the UUID the next time any command saves users.yml.
- Wildcards (
essentials.*,*) are left in the permission attachment as-is. Bukkit resolves them at query time. - Inheritance uses weight to order parents: lower weight applies first, so its entries are overridden by higher-weight parents and by the subject’s own permissions.
- Neither
config.yml,groups.yml, norusers.ymlis rewritten by a reload. Edits from/nexuscommands are written immediately; nothing else is. - If
groups.ymlorusers.ymlfails to parse on startup, the plugin logs the error and enters a locked state where saving is refused. Fix the YAML and run/nexus reloadto unlock. - Vault integration is strictly read-only. Any plugin that tries to add
or remove permissions, groups, prefixes, or suffixes through Vault will
get an
UnsupportedOperationException. - Region contexts require WorldGuard. If it’s absent or the lookup fails, the plugin falls back to server and world contexts only.
Dependencies
Bundles Adventure (adventure-platform-bukkit) inside its JAR,
relocated to com.chalwk.libs.adventure.
Optional integrations, all softdepend, none required:
- Vault. Registers as a permission and chat provider.
- PlaceholderAPI. Registers the
nexusexpansion. - WorldGuard. Enables region contexts.
Changelog
1.1.0
- Added timed permissions. Any perm subcommand accepts a
temp:<duration>argument, and expired entries are filtered at resolution time and swept everytimed-permission-sweep-seconds. - Added a native PlaceholderAPI expansion. Provides
%nexus_prefix%,%nexus_suffix%,%nexus_primary_group%,%nexus_groups%,%nexus_group_count%,%nexus_has_<node>%, and%nexus_option_<key>%. - Added a public read API. Registered under
NexusAPIvia the Bukkit services manager. Query effective permissions, options, groups, and reverse lookups. - Added WorldGuard region contexts. Players standing inside a region
resolve the
region:<name>context alongside server and world. - Added audit log, off by default, toggled with
audit-log.enabled. Every mutation writes a line toplugins/NexusPermissions/audit.log. - User storage is now keyed by UUID. Legacy name-keyed entries migrate automatically the first time each player joins.
- Added
/nexus user <user> deleteand/nexus group <group> delete, with safety checks that refuse to leave a config in a broken state. - Added
/nexus user <user> groups,/nexus user <user> has <node>,/nexus group <group> members,/nexus who <node>,/nexus search <term>,/nexus rename user <old> <new>, and/nexus rename group <old> <new>.
1.0.2
- Prefixes and suffixes returned through Vault now come back with section sign codes rather than ampersands.
1.0.1
- Added Vault integration. Read-only.
- Registered as Vault permission and chat provider.
1.0.0
- Initial release.