ACE permissions on a FiveM server
ACE (access control entries) is FiveM’s built-in permission system. It decides who can run which commands and what scripts consider “admin”. Almost every framework and admin menu builds on it, so a few lines in server.cfg control a lot.
Short answer: A permission is add_ace <principal> <object> <allow|deny>: the principal is a group or player (group.admin, identifier.license:…), the object is what they may do (command.car, myres.admin). Put players into groups with add_principal identifier.<type>:<id> group.admin, and groups into other groups for inheritance. Scripts check with IsPlayerAceAllowed(src, 'object'); test_ace tests from the console.

#The vocabulary
| Term | Meaning | Example |
|---|---|---|
| Principal | Who | group.admin, identifier.license:abc…, builtin.everyone |
| Object | What | command, command.quit, myres.openmenu |
| ACE | A rule | add_ace group.admin command allow |
| Inheritance | Membership | add_principal identifier.fivem:1 group.admin |
#A typical admin setup
# Groups
add_ace group.admin command allow
add_ace group.admin command.quit deny
add_principal group.admin group.moderator
add_ace group.moderator command.kick allow
add_ace group.moderator myres.staffmenu allow
# People
add_principal identifier.license:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b group.admin
add_principal identifier.discord:123456789012345678 group.moderator
add_principal identifier.fivem:1234567 group.moderatoradd_principal group.admin group.moderator makes admins inherit everything moderators can do. deny always beats allow, which is why command.quit deny still blocks admins from shutting the server down from chat.
#Restricted commands
RegisterCommand('announce', function(source, args)
TriggerClientEvent('chat:addMessage', -1, { args = { 'Staff', table.concat(args, ' ') } })
end, true) -- true = restricted, needs command.announceA restricted command is allowed for anyone with command.announce — or command, which covers all commands.
#Checking permissions in scripts
RegisterNetEvent('staff:openMenu', function()
local src = source
if not IsPlayerAceAllowed(src, 'myres.staffmenu') then return end
TriggerClientEvent('staff:menu', src)
end)Check on the server. A client-side check alone can be bypassed.
#How frameworks use ACE
| Framework | Admin setup |
|---|---|
| ESX Legacy | Player group stored in the database (users.group); ESX needs add_ace resource.es_extended command.add_ace allow (and the related lines from its docs) so it can manage principals |
| QBCore | ACE groups such as qbcore.god, qbcore.admin, qbcore.mod: add_principal identifier.license:… qbcore.admin |
| Qbox | Standard groups like group.admin via add_principal |
| txAdmin | Its own permission system — see txAdmin permissions |
#Testing and debugging
test_ace group.admin command.announce
test_ace identifier.license:1a2b3c… myres.staffmenu- Permissions from server.cfg apply at start — changes typed into the console apply immediately but are lost on restart.
- Check for typos in identifiers; one wrong character silently fails.
- Make sure the permission file is actually
exec’d.
Questions
How do I make myself admin on a FiveM server?
add_principal identifier.license:<your licence> group.admin and give group.admin the ACEs you need, then restart.What is the difference between add_ace and add_principal?
add_ace grants or denies an object to a principal; add_principal makes one principal inherit another (a player into a group).How do I check a permission in Lua?
IsPlayerAceAllowed(source, 'object').Why does my admin command say access denied?
command.<name>. Test with test_ace.Does deny override allow?
Ready to pick a map?
Twelve themes on three base map styles, $8 each, instant download.