Basics: Aces & Principals
Aces and principals are the default “permissions” system built into fxserver. It’s very easy to use, as long as you know the basics and you just start trying out some stuff.
It’s also very easy to use this from within resources. Just use
ExecuteCommand() to add/remove aces or principals, and use
IsPlayerAceAllowed() to check if a player is allowed access to an ace (either directly or via inherited permissions).
Let’s start by taking a look at what a Principal is, and how you can use it in the most simplistic way.
Principals are identifiers that hold permissions (aces). Those identifiers can either be player identifiers (ip, steam or license), or they can be made up identifiers (like:
The command used to add identifiers has the following syntax:
# Adds the child principal to the parent principal. add_principal <child_identifier> <parent_identifier> # Removes the child principal from the parent principal. remove_principal <child_identifier> <parent_identifier>
Let’s say we have 2 players. “Player A” and “Player B”. We’ll assume that their (fake) identifiers are:
player:b. We also have 2 groups, which are identified by:
To add “Player A” to the “snail” group, you can use the following command in the server console:
add_principal identifier.player:a snail
Now, all aces that get added to the “snail” group, will automatically be set for
identifier.player:a (so “Player A”).
Principals can also inherit from other principals. For example, if we want the “group.admin” group to also get all permissions from the “snail” group, you’d do this:
add_principal group.admin snail
NOTE There is an important catch with using inheritance, which will be explained in the Aces section.
builtin.everyone principal is a “group” that every single player is in. This means, if you allow builtin.everyone a specific ace, everyone will have that ace as allowed.
Even if you add someone to a specific group/principal, they will still always inherit all permissions from
At this point, the inheritance tree should look something like this:
builtin.everyone # (global parent of everything) | | .... snail # (parent & child) | | | .... +---- group.admin # (child, has all "snail" permissions) | | | .... +--- identifier.player:a # (child, has all "snail" permissions)
Aces can be seen as a “permission node”, which can either be allowed or denied.
By default, all aces are set to
deny. Which means, that if you were to check for an ace that was not setup, it will return
unset value can be overwritten by (manually) setting it to either
allow. Setting something to
deny will actually set it to
DENY-ALWAYS. Which means, it can NOT be overwritten by something like parent principals. Setting it to
allow will grant the ace and is also NOT able to be overwritten by parent principals. Basically it’s just a fist come first serve principle, the first permission to be set, cannot be overwritten by setting it to the opposite state after setting the first state.
# Adds the ace to the principal, and either "allows" or "denies" it. add_ace <principal_identifier> <ace_string> <allow|deny> # Removes the ace from the principal, note it only removes the "allow" or "deny" ace, depending on whichever one you select. remove_ace <principal_identifier> <ace_string> <allow|deny>
To illustrate this, take a look at the following example:
Let’s take Player A and Player B, snail and group.admin principals from the previous example.
In the previous example, we added PLayer A to the snail group, and we also set the group.admin group to inherit everything from the snail principal (group)
Let’s say that Player B has been added to the group.admin principal. (
add_principal identifier.player:b group.admin)
At this point, the inheritance tree looks like this:
builtin.everyone # (global parent of everything) | | .... snail # (parent & child) | | | .... +---- group.admin # (parent & child, has all "snail" permissions) | | | | .... | ... +--- identifier.player:b # (child, has all "group.admin" AND all "snail" permissions) | | | .... +--- identifier.player:a # (child, has all "snail" permissions)
If we want to give Player B the
i.am.cool ace, we 4 options to do so in this current setup.
- Add the ace to
- Add the ace to
- Add the ace to
- Add the ace directly to
However, we probably only want to add it to the 3rd or 4th option. Because adding it to 1 will grant it to everyone, and we don’t want that, and adding it to option 2 will allow everyone in the snail group to use it, which is also not what we want in this case.
So to add the
i.am.cool ace to the
group.admin principal, we’d do something like this:
add_ace group.admin "i.am.cool" allow
group.admin principal, and all of it’s child principals (in this case,
identifier.player:b), now have access to the
Of course, aces have wildcards!
So, let’s say we want to give Player A permission to every
i.am.*** ace, because Player A is
.snailsome as well. Then we can simply add the
i.am ace to
identifier.player:a, now player a has every
add_ace identifier.player:a "i.am" allow # Player a is now: cool, awesome and snailsome!
Player B however, is still only
cool. Let’s make Player B
snailsome as well, because they’re part of the
snail group after all. But we DON’T want to give them the
i.am.awesome ace. In this case, we could simply add the
i.am.snailsome ace to either the
identifier.player:b principals, but we’re going to do it slightly different, just because WE CAN. So how are we going to do it you may ask? Well just like this:
add_ace group.admin "i.am.awesome" deny add_ace group.admin "i.am" allow # Player b is now: cool & snailsome but NOT awesome!
Notice how we set the
deny for the
i.am.awesome first, and then we set the
i.am wildcard to allow. Remember what we said about the first come first serve principle?
Now, group.admin (and thus Player B) has access to all states
i.am.snailsome EXCEPT for one, which is the
i.am.awesome ace, because we set that to deny FIRST.
To summarize everything above, here’s a quick overview of all commands + 2 commands that aren’t listed above.
||Sets the ace for the specified principal identifier to either allow or deny.|
||Removes either the allow or deny ace for that principal.|
||Adds the child principal to the parent principal, giving the child all aces of the parent principal.|
||Removes the child principal from the specified parent principal (revoking all previously inherited permissions).|
||Will show a list of all aces, for each principal identifier and show’s the granted status (allow, deny(/unset) or deny-always)|
||Will show a list of all principals (child > parent)|