A User Roles and Permissions Matrix for Your First Product
Build a user roles and permissions matrix around actions, record ownership and lifecycle states, with negative tests for your first product.
Luka Abramovic3 min read

A user roles and permissions matrix needs more than an admin column and a user column. For every action, specify which records the person may act on and in which state. Two customers can have the same role while being forbidden from reading each other’s projects.
For a specialist product, begin with the roles in the actual service. A reviewer may inspect a submitted brief without being allowed to edit the original evidence. Turning both abilities into a single editor role changes the service’s decision boundary.
List actions against records
| Action | Owner | Invited reviewer | Unrelated customer |
|---|---|---|---|
| Read project | Own project | Explicitly invited project | Denied |
| Edit draft | Before submission | Denied | Denied |
| Approve output | If approval belongs to owner | Only with explicit approval role | Denied |
| Download attachment | Authorized project | Only shared attachments | Denied |
| Invite another person | If sharing is enabled | Denied by default | Denied |
Use this as an illustrative starting point and replace the approval rule with your own. Add exports, search results, notifications and generated reports to the resource list. A project screen can be restricted while an attached file remains accessible through a separate route.
Ask the developer to demonstrate denial
OWASP’s authorization guidance recommends denying access by default and validating permissions on every request. Ask for a demonstration of the server refusing an unauthorized action, not just the interface hiding a control.
Use a controlled test environment and accounts created for the test. Create a project with customer A, then try its recorded link while signed in as customer B. Both accounts should have the same normal customer role. This tests ownership separation that an admin-versus-user demonstration misses.
Repeat the check when relationships change
Invite a reviewer, open the project, then remove the invitation in a separate authorized session. Attempt to refresh, download an attachment and submit a previously opened action. Agree which operations must be denied after removal.
Also change the project state from draft to submitted. If the rule forbids editing after submission, an old open form must not overwrite the submitted version. The server needs the current state when deciding whether to accept the change.
Count coverage by action and relationship
In an illustrative matrix, five actions across three relationships create 15 basic decisions. Testing only that the owner can use all five actions covers five of those decisions. The ten remaining combinations include the denials that protect other users.
Add lifecycle cases separately. An owner editing their own draft and an owner editing their own submitted record are different tests. Mark the expected result before running them, then retain the request, observed outcome and test account labels without storing credentials in the report.
The completed deliverable is a matrix and a small set of repeatable negative tests. Update both when adding a role, sharing route or export. That makes the founder’s access expectations reviewable rather than leaving them implicit in screen designs.
Bring the user roles and one record that changes hands. We can turn the access expectations into a matrix your team can test. Discuss the first release with Adamant Code.