Access control is where a lot of business software becomes quietly frustrating, and the reason is almost always the same: the model is never explained, so when something does not work, the fastest fix anybody can see is to grant more access. Do that a few times and half the company are administrators, which is the state most organisations are actually in.
Here is the whole model, in order.
Three layers, checked in this sequence
One: is the App turned on for this workspace? If it is not, nothing else matters. Nobody sees it, including administrators. This is a workspace level decision about what you are paying for.
Two: does this person hold the permission? Permissions are specific rather than broad. Viewing customers and editing customers are two different keys. Raising an invoice and approving one are two different keys. A role is a named bundle of those keys, and roles are defined per workspace.
Three: is this particular record in their scope? Some Apps narrow further than a permission, so a manager holds the permission to view people and still sees only their own team.
An action happens when all three say yes. Where one says no, the control is not rendered at all rather than being rendered and failing when pressed.
Why controls are hidden rather than disabled
Two reasons, and the second is the one that matters.
A button that does nothing teaches people that the software is unreliable rather than that they lack access, so the next time something genuinely breaks they do not report it.
And a disabled control is still information. A menu full of screens you cannot open tells you exactly what exists, what other departments are doing, and what the company is working on. For a platform holding pay data and client information, that is a real leak wearing the costume of a usability decision.
The two mistakes people actually make
Granting a role when they meant to grant one permission. Somebody cannot export a report, so they are made an administrator, and now they can also change the billing plan and remove other people. The fix is to look at which permission that screen needs and add that one key to their existing role, or make a new role for the job.
Assuming a role means the same thing in two workspaces. It does not. Roles are per workspace, and two workspaces can each define a role called Manager to mean something different. If somebody has access in one and not the other, this is usually why.
How to build a role that lasts
Start from the task, not from the job title.
Write down the four or five things this person actually does in a week. Find the permissions those need. Build a role from exactly those, and name it after the work rather than the seniority. A role called Invoice approver still explains itself in two years. A role called Level 2 does not, and nobody will dare change it because nobody will be sure what it was for.
Review the roles when somebody changes job, not when somebody leaves. Leaving is handled by removing the account. It is the internal move that quietly accumulates access, because the new permissions get added and the old ones never get taken away.
Two things that are deliberately not permissions
Separation of duties. In the finance areas, the person who raised something cannot be the person who approves it. That is enforced on the actor rather than expressed as a permission key, and it has to be: an administrator holds every key by definition, so a rule written as a permission would let the one person holding everything approve their own work. It is the one place where holding more access gives you fewer options, and that is correct.
Access to your own record. Everybody can see their own details without a permission for it. A permission that can be granted can be removed, and nobody should be one configuration mistake away from losing access to their own payslip.
How to audit it
Every permission change writes an entry recording who made it, what changed and when. If somebody has access they should not, that record is where the answer is, and it is the answer rather than a reconstruction.
The useful habit is to read that log after any month with a reorganisation in it. That is when access drifts, and it is the one time the drift is easy to see.

