Define your access matrix
in under 60 seconds.
Enter roles and permissions, toggle a checkbox grid, export to Excel, CSV, Markdown, or JSON. No account. No backend. Ephemeral by design.
One per line or comma-separated. Max 50.
One per line or comma-separated. Max 100.
Enter roles and permissions, then click Generate Matrix
RBAC reference: starter templates, model comparison, permission verbs, export formats
Most teams reach for RBAC before they can name a single role, then discover the hard part is deciding which roles exist, what each verb means, and when a flat role list stops scaling. Here are six ready-to-use role based access control matrix template examples for common application shapes (SaaS, CMS, e-commerce, corporate, Kubernetes, and API/microservices), a quick-decision grid for choosing RBAC vs ABAC vs PBAC, the standard permission vocabulary, how to map a finished matrix onto Casbin model.conf / policy.csv, and the structure of each export format with examples.
Quick-decision grid: RBAC vs ABAC vs PBAC
| If your access decisions need... | Use |
|---|---|
| To depend only on the user's role(s) | RBAC (Role-Based) |
| To depend on attributes of the user, resource, or environment (department, time of day, IP range) | ABAC (Attribute-Based) |
| To be expressed as policies in a high-level language (Rego, Cedar) and evaluated at runtime | PBAC (Policy-Based) |
| To depend on the user's relationship to the resource (owner, collaborator, viewer) | ReBAC (Relationship-Based, e.g., Google Zanzibar) |
| To combine multiple of the above | Hybrid; most production systems are RBAC + ABAC |
RBAC is the default starting point. Add ABAC when role explosion sets in (you have 50+ roles to express simple distinctions like "engineer in EU region"). Move to PBAC or ReBAC when access logic involves complex policy or graph-shaped relationships (Google Drive sharing, GitHub repo permissions).
Standard permission verbs (CRUD + extensions)
| Verb | Meaning | Common alternatives |
|---|---|---|
| read | View resource content | view, get, list |
| create | Add new resource | add, insert, post |
| update | Modify existing resource | edit, patch, put, modify |
| delete | Remove resource | remove, destroy |
| list | Enumerate resources | index, query |
| share | Grant access to others | invite, add_collaborator |
| transfer | Change ownership | assign, reassign |
| approve | Authorize a workflow step | sign_off, validate |
| export | Extract data outside the system | download, extract |
| audit | View access logs / history | view_audit_log, inspect |
| admin | Full control of the resource | manage, owner |
The read / create / update / delete core (plus list) covers ~80% of business application permissions. Reach for the others when the domain genuinely needs them.
Template 1: SaaS B2B app (4 roles × 8 permissions)
Common starting point for multi-tenant SaaS. Each customer has their own tenant; users inside a tenant have one of these roles.
| Permission | Owner | Admin | Member | Viewer |
|---|---|---|---|---|
| account.read | ||||
| account.update | ||||
| billing.read | ||||
| billing.update | ||||
| users.invite | ||||
| users.remove | ||||
| data.read | ||||
| data.write |
Owner is exactly one user per tenant. Admin can manage users but not billing (so a fired admin can't remove the credit card). Member is the working role most users have. Viewer is read-only; useful for stakeholders who shouldn't edit.
Template 2: Content management system (5 roles × 10 permissions)
Editorial workflow with draft/review/publish stages.
| Permission | Super Admin | Editor | Author | Contributor | Subscriber |
|---|---|---|---|---|---|
| posts.create | |||||
| posts.edit_own | |||||
| posts.edit_others | |||||
| posts.publish | |||||
| posts.delete | own only | own only | |||
| comments.moderate | |||||
| media.upload | |||||
| users.manage | |||||
| themes.manage | |||||
| comments.read |
Mirrors WordPress's role structure. Contributor can write but not publish (Editor must approve). Author can publish their own posts but not others'.
Template 3: E-commerce platform (4 roles × 12 permissions)
Storefront with order management and customer service workflows.
| Permission | Owner | Manager | Customer Service | Fulfillment |
|---|---|---|---|---|
| products.create | ||||
| products.edit | ||||
| products.delete | ||||
| orders.read | ||||
| orders.update_status | ||||
| orders.refund | ||||
| orders.cancel | ||||
| customers.read | ||||
| customers.edit | ||||
| inventory.read | ||||
| inventory.adjust | ||||
| reports.financial |
Customer Service can refund and cancel orders but can't adjust inventory directly (prevents fraud). Fulfillment can adjust inventory (mark items as picked/shipped) but can't issue refunds.
Template 4: Internal corporate tool (5 roles × 8 permissions)
Read-mostly internal app with departmental access scoping.
| Permission | IT Admin | Department Head | Manager | Employee | Contractor |
|---|---|---|---|---|---|
| app.access | |||||
| documents.read_all | |||||
| documents.read_dept | dept-scoped | ||||
| documents.create | |||||
| documents.share_external | |||||
| users.read | dept-scoped | ||||
| reports.run | dept-scoped | ||||
| settings.modify |
"Dept-scoped" indicates a permission that requires ABAC layering on top of the role; the role grants access only within the user's department, evaluated at runtime against the resource's department attribute.
Template 5: Kubernetes RBAC (4 roles × verbs on resources)
Kubernetes RBAC binds verbs (get/list/watch/create/update/patch/delete) to API resources (pods, deployments, secrets) inside a namespace. This matrix is the source for the rules: block of a Role or ClusterRole. Cells list the verbs granted on that resource.
| Resource | cluster-admin | developer | ci-deployer | read-only |
|---|---|---|---|---|
| pods | * | get/list/watch | get/list | get/list/watch |
| pods/log | * | get | get | get |
| deployments | * | get/list/watch/update/patch | get/update/patch | get/list/watch |
| services | * | get/list/watch/create/update | get/update | get/list/watch |
| secrets | * | get | ||
| configmaps | * | get/list/create/update | get/update | get/list |
| namespaces | * | get/list | get | get/list |
In Kubernetes the matrix is verbs-per-resource rather than a single boolean. * denotes all verbs (a ClusterRole). developer is a namespaced Role with no access to secrets. ci-deployer gets the narrow patch/update set a CI pipeline needs to roll out images, plus read-only secrets for pulling registry credentials. Each non-empty cell becomes one rules entry: {apiGroups, resources, verbs}.
Template 6: API / microservices roles × OAuth scopes (5 roles × 9 scopes)
For a service-to-service or public API, the "permission" axis is OAuth2 scopes (resource:action) and the "role" axis is client/token type. This matrix is the source for the scopes you stamp into a JWT or grant to an API key.
| Scope | service-admin | backend-service | mobile-app | partner-api | public-readonly |
|---|---|---|---|---|---|
| orders:read | |||||
| orders:write | |||||
| orders:delete | |||||
| users:read | scoped | ||||
| users:write | self only | ||||
| payments:charge | rate-limited | ||||
| payments:refund | |||||
| webhooks:manage | |||||
| metrics:read |
Each row maps to one OAuth scope string. backend-service is a trusted machine token with near-full access; mobile-app can only write its own user record; partner-api gets a narrow, often rate-limited slice; public-readonly is anonymous read access. Stamp the granted scopes as the scope claim of the access token and check them in middleware.
Export format reference
The matrix you build in Rolemat exports to three formats. Examples below for the SaaS template above.
Markdown (paste-ready for GitHub/wiki)
| Permission | Owner | Admin | Member | Viewer |
|---|---|---|---|---|
| account.read | ✓ | ✓ | ✓ | ✓ |
| account.update | ✓ | ✓ | | |
| billing.read | ✓ | ✓ | | |
...CSV (paste-ready for spreadsheets)
Permission,Owner,Admin,Member,Viewer
account.read,1,1,1,1
account.update,1,1,0,0
billing.read,1,1,0,0
billing.update,1,0,0,0JSON (paste-ready for code)
{
"roles": ["Owner", "Admin", "Member", "Viewer"],
"permissions": ["account.read", "account.update", "billing.read", "billing.update"],
"matrix": {
"account.read": { "Owner": true, "Admin": true, "Member": true, "Viewer": true },
"account.update": { "Owner": true, "Admin": true, "Member": false, "Viewer": false },
"billing.read": { "Owner": true, "Admin": true, "Member": false, "Viewer": false },
"billing.update": { "Owner": true, "Admin": false, "Member": false, "Viewer": false }
}
}The JSON shape is the most useful starting point for code: most authorization libraries accept a similar matrix as input or can be wrapped around one.
NIST RBAC reference (formal model)
For projects that need to align with the NIST INCITS 359-2004 RBAC standard:
| Level | What's added | When to use |
|---|---|---|
| RBAC₀ (Core) | Users, roles, permissions, sessions | Most applications stop here |
| RBAC₁ (Hierarchical) | Role inheritance (Manager inherits from Employee) | When roles compose naturally; reduces matrix maintenance |
| RBAC₂ (Constrained) | Separation-of-duty constraints (no user can be both Approver and Requestor) | Compliance-driven environments (SOX, healthcare) |
| RBAC₃ (Symmetric) | RBAC₁ + RBAC₂ combined | Highly regulated systems |
Most application-level RBAC implementations operate at RBAC₀ or RBAC₁. Higher levels are typically enforced by enterprise identity systems (Okta, Azure AD) rather than application code.
Map your matrix to Casbin
A Rolemat matrix is a design artifact, not an enforcement engine. Once the roles are settled, the most common next step is feeding the matrix into Casbin, which checks enforce(sub, obj, act) at request time. Casbin splits authorization into two files: a model.conf (the grammar: request, policy, role, matchers) and a policy.csv (the data: one line per granted cell). The matrix maps directly onto the policy file.
Worked example: a small RBAC matrix
Take this 3-role × 3-permission matrix on the posts object. The mapping below turns each checked cell into one Casbin policy line.
| Permission | admin | editor | viewer |
|---|---|---|---|
| posts:read | |||
| posts:write | |||
| posts:delete |
Each ✓ becomes a p (policy) line of p, role, object, action. Role-to-user assignment lives in separate g (grouping) lines.
model.conf: RBAC grammar (request / policy / role / matchers)
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.actpolicy.csv: one p line per checked cell, plus g lines for role assignment
# p, role, object, action: one line per checked cell
p, admin, posts, read
p, admin, posts, write
p, admin, posts, delete
p, editor, posts, read
p, editor, posts, write
p, viewer, posts, read
# g, user, role: role assignment (the "g" grouping lines)
g, alice, admin
g, bob, editor
g, carol, viewerThe translation is mechanical: every checked cell (role, permission) becomes a p, role, object, action line. If your permission names already use the object:action shape (like the API-scopes template above), split on the colon to fill the obj and act columns. Add g, user, role lines to bind real users to roles. Cerbos, OPA/Rego, and Oso accept the same matrix shape with different syntax.
Role explosion: when to escalate beyond RBAC
Watch for these signals that pure RBAC is breaking down:
- You have more than ~30 roles for a single application
- Role names start including conditions:
Engineer-EU,Engineer-US,Engineer-EU-Admin - You're cloning roles to express scope:
Manager-Sales,Manager-Marketing,Manager-Engineering - Permission grants involve "if" clauses that aren't in the matrix itself
When 2+ of these are true, layer ABAC (attributes for region, department, scope) on top of RBAC, or switch to a policy engine (OPA/Rego, Cedar, Permify).
Related concepts
- Principle of least privilege. Each role should have the minimum permissions needed. Default to deny; grant explicitly. Audit role assignments quarterly.
- Separation of duties. No single role should both initiate and approve sensitive actions (financial transfers, code deploys). Often expressed as a constraint across two roles rather than within one.
- Time-bound roles. Some compliance regimes (PCI-DSS, HIPAA) require certain elevated permissions to be granted only for the duration of a specific task. PAM (Privileged Access Management) tools handle this.
- Audit logging. Every permission check should be logged for sensitive resources. The audit log is often consulted more than the matrix itself.