Two questions, not one: how a request gets authorized
"May this role edit expenses?" is only half an access check. The other half — which expenses — is where most systems leak.
Most permission systems answer one question: may this role perform this action on this kind of record? It is a necessary question and an insufficient one. Answer only that, and every member of staff who may edit an expense may edit everyone's expenses.
The second question
Corveek asks a second question on every request: which records? Each grant carries a scope. "Own" means the records you created — your expenses, your leave requests, your drafts. "All" means everything in the organization, which is what a manager or an administrator gets. Where someone holds several roles, the widest scope wins.
Enforced where it cannot be skipped
The scope filter is applied in the shared data-access layer, not in individual endpoints. That placement is the whole point: a developer adding a new screen cannot forget to apply it, because there is no path to the data that bypasses it.
The consequence is visible from outside. Ask for a record id you do not own and you get "not found" — not "forbidden". A refusal that distinguishes the two confirms the record exists, which is precisely the fact an attacker was fishing for.
The interface is not the boundary
Buttons, menu items, fields and whole navigation groups are hidden when your roles do not allow them. That is a courtesy, not a control. Every one of those actions is checked again on the server, because a hidden button is still a URL.
The default is deny. A permission that has not been explicitly granted does not exist, and new modules inherit that default rather than opting into it.
See how this works on your data
We will set up a workspace with your modules and roles, and show you the parts that matter to your team.
Keep reading
Money that survives the trip to the screen
An amount can be stored perfectly and still be wrong by the time someone reads it. Three defects we found on the surface customers check most closely.
Eleven phases in, and what actually shipped
Corveek was built in a deliberate order: shared foundations, then the modules that depend on them. Here is what that produced.