Roles and permissions

BackendTier 2 · build and shipPhase 3 · Give customers accounts

Grouping what users can do into roles (customer, staff, admin) so access is managed cleanly instead of person by person.

As a team and product grow, granting powers one person at a time becomes unmanageable and inconsistent: who can refund, who can edit prices, who can see personal data. Ad hoc access drifts into a security mess. Roles and permissions exist to bundle powers into named roles you assign to people, so access is granted in consistent, auditable groups instead of case by case.

Rather than granting each person individual powers, you define roles: a customer role, a staff role, an admin role, each with a set of permissions. Assigning someone a role gives them exactly that set.

When a new staff member joins, you give them the staff role and they instantly have the right access. Roles keep permissions consistent and auditable as teams grow.

A junior PM, stuck

During an access review I found out that support agents can edit menu prices, and now I have to propose the corrected role model without being able to read the current one properly. I am looking at a grid of roles and permissions with true and false everywhere and I cannot tell which cells are the mistake and which are supposed to be there. I do not want to propose a fix that breaks something support legitimately needs.

A role model is just a grid: roles down one side, the things a person can do across the other, and a true or false in every cell. Reading it is a matter of going permission by permission and asking "should this role be able to do this," and the over-permission almost always stands out once you do. Below is the current matrix and the one-cell fix, so you can point at exactly the cell that is wrong and propose a change that touches only it.

The staff permission matrix, and the one cell to fix
role_permissions: three roles against eight permissions
permission | customer | support | admin
view_own_orders | true | true | true
place_order | true | false | false
view_customer_pii | false | true | true
issue_refund | false | true | true
edit_menu_prices | false | true | true
edit_customer_data | false | true | true
manage_staff | false | false | true
view_reports | false | true | true
the fix: turn off one cell, leave the rest
UPDATE role_permissions SET allowed = false
WHERE role = 'support' AND permission = 'edit_menu_prices';
UPDATE 1
SELECT allowed FROM role_permissions
WHERE role = 'support' AND permission = 'edit_menu_prices';
false

Click a step to see the lines it points at.

Granting powers person by person instead of by role. Handing one agent price access "just this once" is how the matrix drifts; roles exist so access is consistent and auditable, and one-off grants defeat that.
Flipping a permission on for convenience and never off. edit_menu_prices on support was almost certainly a shortcut that outlived its reason; over-broad roles are a standing security and mistake risk.
Fixing the whole row instead of the wrong cell. Support legitimately needs refunds and customer edits; yank those too and you break real work. Change only the cell that fails the "should never" test.
Putting sensitive powers on the base staff role. Editing prices, issuing large refunds, and managing staff belong to higher roles; loading them onto the role everyone gets makes the blast radius of one mistake huge.
Never actually reviewing the matrix. Permissions accrete silently as features ship; if no one reads the grid against "who should not be able to do this," the drift is only found after something goes wrong.

Propose to the review: "One cell is wrong: support has edit_menu_prices set to true. Pricing is an admin decision, so we turn that off for support and leave their refund and customer-edit access intact." You read a role matrix cell by cell and isolated the over-permission, which is the skill.

Designing the role model (who can see and do what) is squarely a PM job when building any internal tool or multi-user product.
Over-broad roles are a security and mistake risk; "why can support edit prices?" is a role-design question.

"Refunds should be a manager permission, not on the base staff role."

Appears in Phase 3, Give customers accounts.