# ACE permissions in FiveM: add_ace, add_principal and groups

> How FiveM ACE permissions work: add_ace and add_principal line by line, group inheritance, IsPlayerAceAllowed inside a script, and test_ace in the console.

Source: https://fam-tools.com/guides/fivem-ace-permissions · FAM Tools · published 2026-09-11 · updated 2026-09-11 · about 11 min

**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.

## Key points

- `add_ace principal object allow|deny` — deny wins.
- `add_principal child parent` — players into groups, groups into groups.
- Identify players by license, fivem or discord identifiers.
- Restricted commands need `command.<name>`.
- Test with `test_ace` before blaming the script.

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.

## 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

*permissions.cfg — exec it from server.cfg*

```cfg
# 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.moderator
```

`add_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.

> **Which identifier?** — `license` (Rockstar licence) is always present. `discord` exists only when Discord is running and linked; `fivem` only when the player is logged in to Cfx.re. For staff, the licence is the most reliable. See [player identifiers](https://fam-tools.com/guides/fivem-player-identifiers).

## Restricted commands

*server.lua*

```lua
RegisterCommand('announce', function(source, args)
    TriggerClientEvent('chat:addMessage', -1, { args = { 'Staff', table.concat(args, ' ') } })
end, true) -- true = restricted, needs command.announce
```

A restricted command is allowed for anyone with `command.announce` — or `command`, which covers all commands.

## Checking permissions in scripts

*server.lua*

```lua
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](/guides/txadmin-admins-permissions) |

## Testing and debugging

*Server console*

```cfg
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 `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?

On the server: `IsPlayerAceAllowed(source, 'object')`.

### Why does my admin command say access denied?

The command is restricted and the player lacks `command.<name>`. Test with `test_ace`.

### Does deny override allow?

Yes. A deny on the same object wins over an allow.

## Related

- https://fam-tools.com/guides/txadmin-admins-permissions
- https://fam-tools.com/guides/fivem-player-identifiers
- https://fam-tools.com/guides/fivem-server-cfg
- https://fam-tools.com/guides/fivem-discord-whitelist-script
