Preamble

The ACL is just one part of the whole aragonOS, but along with the Kernel is one of the most important contracts in the stack. This is what allows an organization to have permissions, effectively enabling governance models depending on the permissions set on the organization. Here we'll see what exactly is a permission, how the ACL actually looks like internally, and the fundamental methods needed to enable the powerful patterns that the ACL can allow.

First of all, what's a permission?

While we get a fancy description in hack.aragon.org about what a permission is, you can just see it as if an account had a specific role on an app, effectively allowing that account to execute some action.

Now, we can identify that role with a name, and an app with its address. The cool thing about this is that we group these things together to form a unique identifier for this permission, meaning that a certain combination of an (address, role, appAddress) will always have a unique identifier. If one of these 3 things change, the unique identifier will change as well. This will be our "key", which will always be unique.

Going a bit deep: The address will always be an account public key, a role is the keccak256 hash of the role name, as in keccak256("MANAGE_PROFILE_ROLE"), and the appAddress is the app proxy address. The resulting unique identifier is the keccak256 hash of the concatenated arguments.

Got my key, now, how do I check if I can do stuff?

This is where things get interesting: we got a unique identifier for permissions, which means we can use this to access information! The ACL has a data structure called a mapping, which is like a large street with houses in them, and every house can be accessed with one of the keys we've created. With these, the ACL can access the house and see if the user has permission by checking the contents inside of it or place contents inside of the house. If a house has never been accessed by the ACL before, there's a special key that indicates so and comes with the house by default.

Now, let's say we wanna check if we have permission to do something with our key: we can give it to the ACL, and it will check it for us by going inside the house and looking at the key stored inside. If a key that is not the special key used for signaling that we've not entered this house before, we will know that:

We won't get into the deep rabbit hole of the rules required to perform an action, because if not, this won't be an ELI5, but a primer on ACL engineering!

<aside> 💡 Going a bit deep: we can access this mapping (let's call it permissions) via permissions[keccak256(abi.encodePacked(_address, _role, appAddress))], and if this has not **been assigned any value, it will return bytes32(0), which can be visualized as a string with 64 zeroes and a prefix of "0x". If not, it will return either a special empty params hash defined on the contract that has no rules, or a params hash that encodes the rules for the user to perform this action. This hash will later be used to actually determine if a user has the required permission. We can invoke this flow for checking permissions with the hasPermission() function.

</aside>