How should a B2B SaaS product design roles and permissions?
Admin and Member no longer fit, and support keeps making people Admin. A role model, a readable permission matrix, no-access states, safe role changes and an audit trail for a B2B SaaS product.
After a renewal call, a customer’s security team sends three requests. They want a billing contact who sees invoices and nothing else, a contractor who can edit one project for 30 days, and an auditor who can read everything and change nothing. The product has two roles, Admin and Member. Sales has promised custom roles “next quarter,” and support keeps making people Admin as a workaround, so one account has 14 admins. The scene is illustrative, but the pattern is common: permissions grew one feature at a time, and nobody drew the model.
Humbleteam, a digital product design agency, publishes this guide. Settle the model first, then design six screens: the role editor, the admin matrix, the invitation, the no-access state, the role change and the audit log.
What should the role model contain?
GitHub defines a permission as the ability to perform a specific action, and a role as a set of permissions assigned to people or teams. That matches the NIST role-based access control model: each user holds one or more roles, and each role carries one or more privileges. Four building blocks cover most products.
- Default roles. Ship a short set every customer gets, ordered from least to most access. GitLab lists eight, from Minimal Access to Owner.
- Custom roles. Let admins fill the gaps. GitLab builds each one on a default role and does not let you change that base later. GitHub limits custom organization roles to Enterprise Cloud and Slack to Enterprise plans, so custom roles are partly a packaging decision.
- Permission bundles. Salesforce advises one permission set per finite task, grouped into permission set groups that stand for a persona such as a sales rep.
- Scope. One role can mean different things in different places. In GitLab a user can hold a different role in each group and project and keeps the highest one. Linear separates workspace owners from team owners.
Roles multiply. GitLab’s custom-role page lists a prerequisite of fewer than 10 custom roles, and Google Workspace caps an organization at 750. A workable rule, which is judgment and not a standard: build a custom role only when a customer needs a combination that two default roles cannot express.
Engineering needs one rule early. WorkOS notes that checking permissions in code, not role names, lets teams add or change roles without changing the application. OWASP adds that a new account should have minimal or no access by default.
How should the admin screen show who can do what?
GitLab publishes its permissions as a table with roles as columns and actions as rows, and GitHub pairs each custom-role permission with a one-line description. Build that into the product as a live screen.
- One row per permission, worded the way a customer’s IT lead would say it (“Export customer data”) and grouped by area.
- One column per role, with the number of people assigned. GitLab’s roles page lists users per custom role.
- Cell values in words: Allowed, Not allowed, Own items only, Assigned projects only. WCAG says color should not be the only way to convey information, so a green and red grid fails some readers.
- A per-person view that answers “why can she do this?” Salesforce’s View Summary lists every permission a user has and how access is granted. With stacked roles, show which one supplies each permission.
Two failure cases. A 60-row grid is unreadable without search, area filters and a way to compare two roles (design suggestions, not documented patterns). And one checkbox can quietly cross a role boundary: GitLab states that a custom permission can allow actions normally limited to Maintainers or Owners, so the editor should flag any permission that reaches past the role it extends.
How should an invitation assign a role?
- Put the role in the invite form, with the least-privileged one selected. Linear lets admins pick the role and the teams at invite time on paid plans.
- Put scope and expiry next to role. Slack admins who add a guest name the channels and can set a time limit, and Salesforce assignments can carry an expiration date.
- Show one line from the matrix before sending.
- Cap grants at the inviter’s own level. In Slack’s table, workspace Admins can promote other Admins but cannot promote Owners.
One case breaks the simple form: roles that come from an identity provider. WorkOS notes that assignments can come from IdP group mappings, so a manual edit may be overwritten. Show those roles as read-only, with a note on where to change them.
What should someone see when access is missing?
Jakob Nielsen describes three patterns for an inactive control: show it as normal and explain on click, show it disabled, or hide it. He prefers disabled controls with an explanation, except for features a user can never have. HashiCorp’s Helios design system recommends avoiding disabled elements, and research from the US Web Design System lists an unauthorized user as a reason to hide a control. For permissions, all three agree on hiding what a role never includes. The table turns that into a decision.
| Situation | Show | Say | Limit |
|---|---|---|---|
| A control the person’s role never includes (billing, for a Viewer) | Hide it | Nothing on screen; list it in the role description and help | People who expect it may conclude the feature does not exist |
| An action the person might get, and someone in the account can grant it | Keep the control visible | On click: “Viewers can’t edit this report. Ask Priya Rao or request edit access,” with a button | Needs a real approver; an empty owner list is a dead end |
| A link to a page or project the person cannot open | An access screen, not a blank error | The kind of item, who can grant access, a Request access button with an optional note | Do not echo the item’s title or contents |
| A resource whose existence is sensitive, such as a client project | The same response as “not found” | “This page doesn’t exist, or you don’t have access” | Costs clarity; support needs the audit log to explain |
| A feature locked by plan, not role | Admins who can upgrade see the path; others see who to ask | Name the plan, then the person | Keep it to one prompt per screen |
The rows rest on documented behavior. Notion notifies a page’s creators or editors of an access request and lets a viewer ask for edit access. GitHub returns 404 instead of 403 for private resources so it does not confirm that they exist. Helios says to explain why a page is unavailable and give a way forward.
Hiding is a design choice, not protection. OWASP says client-side checks may improve the experience but must never decide access. Our guide to restructuring B2B SaaS navigation covers one menu tree filtered by permission; this section covers the edge of that filter.
How do you change a role without locking people out?
A role edit is the riskiest screen, because one save changes access for everyone who holds the role.
Preview the effect. Google Cloud’s Policy Simulator replays access attempts from the last 90 days under the current and the proposed policy, then lists access revoked and gained. Most products cannot build that. The minimum is a before-and-after permission diff plus the names of affected people. Google’s tool can return “unknown,” so say “unknown” when you do not know, not “no impact.”
Protect the last admin. GitHub recommends at least two owners and does not let owners change their own role. GitLab lets anyone leave a group unless they are its only Owner. Google Workspace needs at least one super admin and recommends two. The design rule: warn at one person and block at zero, checking who holds the permission to change roles, since a custom role may hold it. Say why the save is blocked.
Refuse unsafe deletes. GitLab will not delete a custom role still assigned to a user, and Salesforce blocks deleting an assigned permission set. Offer a reassign step instead.
Add a second approver where the stakes justify it. Google’s multi-party approval lets another admin review role changes, and a request expires after 3 days. The same page says to turn it off when only one super admin exists, because the approval would block. Also, Google admits that admins editing at the same time can overwrite each other with no warning, so show “last edited by” and refuse a stale save.
What belongs in the audit trail?
NIST’s audit control AU-3 asks that each record establish what type of event occurred, when, where, its source, its outcome, and the identity of anyone involved. For permissions, that becomes a field list:
- What: invite sent, role created, edited, assigned or removed, access requested, approved or denied.
- Who and whom: the actor, the affected person, and for a role edit the permissions before and after.
- Where and when: workspace, project or team, with a time zone.
- Source: the screen, the API or an identity provider sync.
- Outcome: done, blocked, pending approval or expired.
GitHub’s organization log is a useful reference. Each entry shows the actor, the affected user, the repository, the action, the country and the time, and search filters cover actor and operation. It covers the last 180 days and is open to owners only, so enterprise buyers will ask about your retention period and who can read the log. Record blocked attempts, not only successes.
Separate the people who change access from the people who read the log. NIST’s separation-of-duties guidance says that security staff who administer access control should not also administer audit. Slack ships a Roles Admin and an Audit Logs Admin as separate system roles. Shared admin accounts defeat the log: Google notes that you cannot tell which administrator did what.
Last, give admins a review screen. NIST’s least-privilege enhancement AC-6(7) calls for periodic review of assigned privileges, and OWASP calls the failure privilege creep. A list of everyone with Admin, with last sign-in and an “expires” column, covers most of it.
What does a small version look like?
This example is illustrative and uses an invented product, Fieldnote, a project reporting tool. It resolves the opening scene, and the worksheet below is the matrix, filled in.
| Permission | Owner | Admin | Member | Billing contact (custom) | Contractor (custom) | Auditor (custom) |
|---|---|---|---|---|---|---|
| View projects | Allowed | Allowed | Allowed | Not allowed | Assigned projects only | Allowed |
| Edit reports | Allowed | Allowed | Allowed | Not allowed | Assigned projects only | Not allowed |
| Export customer data | Allowed | Allowed | Own reports only | Not allowed | Not allowed | Not allowed |
| Invite people | Allowed | Allowed | Not allowed | Not allowed | Not allowed | Not allowed |
| Change roles | Allowed | Up to Admin | Not allowed | Not allowed | Not allowed | Not allowed |
| View invoices and plan | Allowed | Not allowed | Not allowed | Allowed | Not allowed | Not allowed |
| View audit log | Allowed | Not allowed | Not allowed | Not allowed | Not allowed | Allowed |
Reading it:
- Each custom role answers one customer request. The Contractor assignment is scoped to one project, Atlas, and expires in 30 days.
- Admins can change roles but not read the audit log, following the separation-of-duties logic above. Some customers will want it reversed, so make it a setting.
- Before saving a change that removes “Export customer data” from Admin, the screen reads: “6 people hold Admin. 2 used export in the last 30 days.” Those figures are invented.
- The workspace has three Owners. A save that would leave zero people with “Change roles” is blocked, and one that would leave one gets a warning.
What should you ask a design agency?
If you scope outside help, these questions show whether a proposal covers the work above:
- Which roles will you interview? Include a customer’s IT or security admin, not only everyday users.
- Do you start from an inventory of every action in the product, before drawing screens?
- Which states will you design: last admin, pending approval, expired access, conflicting edits, roles managed by an identity provider?
- What do engineers receive: permission names, scope and inheritance rules, and the checks the server must enforce?
- How will you test? Ask for tasks such as “give a contractor one project for 30 days” and “remove the last admin,” run with admins and non-admins.
- Which past cases show admin settings and roles, and what can the agency not show because of an NDA?
To compare agencies that publish this kind of platform work, see which UX/UI agencies design complex B2B SaaS platforms, where every agency, Humbleteam included, is judged by the same criteria.
With an action inventory, a filled matrix and a list of events to log, a team can run this itself or check an agency’s proposal against it.
