CMS User Roles and Permissions: A Practical Guide

Least privilege, six role archetypes, and the access mistakes that bite real content teams

July 1, 2026 · 14 min read
CMS User Roles and Permissions: A Practical Guide

Most CMS security incidents don't start with a clever exploit — they start with an account that had more access than it needed. Getting CMS user roles and permissions right is the cheapest security win available to any content team.

TL;DR: Give every person the minimum role that lets them do their job. Map your team to six standard archetypes (super admin, admin, editor, author, contributor, viewer), separate module access ("can they see the blog section?") from action permissions ("can they delete?"), and review the user list every quarter. Never share logins, and remove accounts the day someone leaves. This guide walks through the archetypes, the permission models, setup steps, and the pitfalls that bite real teams — with UnfoldCMS as the worked example (disclosure: we build it).


What are CMS user roles and permissions?

A role is a named bundle of permissions — "Editor," "Author" — assigned to a user. A permission is a single allowed action, like publishing a post or deleting a media file. Role-based access control (RBAC) means you grant roles to people instead of stacking individual permissions one by one.

The distinction matters because permissions don't scale as a management unit. A mid-size CMS exposes dozens of discrete actions: create post, edit post, publish post, delete post, manage users, change settings, install plugins. Assigning those one-by-one to fifteen people is error-prone and impossible to audit. Roles compress that into a handful of named bundles you can reason about: "Sara is an Editor" tells you almost everything about what Sara can do.

Two principles drive the whole topic:

  • Least privilege — every account gets the minimum access needed for its job, nothing more. A guest blogger doesn't need access to site settings. Your SEO consultant doesn't need to delete users.
  • Auditability — when something changes (a post vanishes, a setting flips), you should be able to answer "who did this, and when?" That requires individual accounts and an activity log, which we'll get to.

If you're still comparing platforms, role granularity is one of the criteria worth testing hands-on — we covered the full checklist in how to evaluate a CMS beyond the marketing page.


Why does RBAC matter for content teams?

RBAC limits the blast radius of mistakes and compromised accounts. If an author's password leaks, the attacker can draft posts — not wipe your database. It also creates accountability: every change traces to a named person, which keeps blame off the table and makes incident review fast.

Think about the failure modes without it:

  • Everyone is an admin. One phished password = total site compromise. One misclick in settings = broken production site. No way to tell who did what.
  • The freelancer who never left. A contractor wraps up in March; their admin account is still active in November. Stale accounts are a top entry point in real-world breaches.
  • The shared "[email protected]" login. Five people, one password, zero accountability. When a post gets edited badly, the activity log says "content team" — useless.

RBAC fixes all three structurally. Tight roles cap the damage from any single account. Individual accounts plus an activity log give you a real audit trail. And a defined offboarding step (covered below) closes the stale-account hole.

There's also a quieter benefit: confidence. Authors work faster when they can't accidentally break the homepage. Removing dangerous options from someone's UI isn't a restriction — it's guardrails.


The six role archetypes (and who gets each)

Almost every CMS converges on the same six roles, whatever it names them. Super admin owns the system, admin runs the site, editor owns all content, author owns their own content, contributor drafts without publishing, and viewer reads without touching. Start with these; add custom roles only when a real gap appears.

Role Edit own content Edit all content Publish Manage media Manage users Site settings
Super admin
Admin ✅ (scoped)
Editor
Author ✅ (own) ✅ (own)
Contributor ✅ (drafts)
Viewer

A few notes on the boundaries:

  • Super admin vs admin — the super admin typically bypasses permission checks entirely and can't be locked out. There should be exactly one or two of these, ideally held by whoever owns the infrastructure. Day-to-day site management belongs in the admin role, which can still be constrained.
  • Editor vs author — the editor's defining power is editing other people's content and publishing anything. Authors stay in their own lane.
  • Contributor — the underused gem. Guest writers, interns, and new hires draft freely but can't push anything live. An editor reviews and publishes. You get a review step without any workflow machinery.
  • Viewer — for stakeholders who want to preview drafts or check analytics. Read-only access means they can't be the source of an incident.

Module-level vs action-level permissions: what's the difference?

Module-level permissions gate whole areas of the admin — blog, users, settings, SEO. Action-level permissions gate verbs inside a module — create, edit, delete, publish. A good CMS layers both: first "can you enter this room?", then "what can you touch once inside?"

The two layers answer different questions:

  • Module-level: "Can this user see the Users section at all?" If not, it shouldn't even appear in their sidebar. This keeps the UI clean and removes temptation.
  • Action-level: "Inside the blog module, can this user delete posts, or only create and edit?" Delete is the classic action to restrict — most content mishaps are deletions, not edits.

In UnfoldCMS this maps directly to middleware. Routes are wrapped in module checks like permission.module:blog or permission.module:users, and destructive routes add an action check such as action.delete on top. So a role can grant blog access without granting blog deletion — the two are independent switches, enforced at the route layer rather than hidden in controller code.

Why care as a developer? Because middleware-level enforcement means the rule holds everywhere — admin UI, API endpoints, any future surface — instead of relying on each screen to remember to check. It's the same "boring and predictable beats clever" principle we argued for in what makes a CMS developer-friendly.


How to set up roles for a content team (step by step)

Inventory the humans first, then create the smallest set of roles that covers them. Assign people to roles (never raw permissions), test each role with a real login, and write down who owns role changes going forward. The whole exercise takes under an hour for most teams.

  1. List every person who needs access — name, job, and the specific tasks they do in the CMS. Not their title; their tasks.
  2. Map each person to the weakest archetype that covers their tasks. When in doubt, go lower — upgrading later is one click; cleaning up after an over-granted account isn't.
  3. Create the roles in your CMS. In UnfoldCMS, that's the /admin/roles UI: name the role, tick module and action permissions, save. No code or config files involved.
  4. Assign users to roles. One role per user is the sane default. If someone seems to need two roles, you probably need a third role with the union of the right permissions.
  5. Log in as each role and verify. Create a test user per role and click around. Confirm the contributor can't publish and the author can't touch others' posts. Five minutes per role, and it catches misconfiguration before it matters.
  6. Document the ownership. One sentence in your team wiki: "Role changes go through [name]." Permission sprawl starts the day anyone can grant anything.

Want to see what this looks like in a real admin panel? UnfoldCMS ships RBAC in every tier — spin it up and build a custom role in about two minutes.


Multi-author workflows without approval chains

You don't need a formal approval-chain feature to run a review process — roles alone can enforce one. Contributors draft, editors publish: the permission boundary is the workflow. This covers most teams up to about ten writers without any extra machinery.

Here's the honest part: UnfoldCMS does not ship approval or workflow chains. When a user with publish permission hits publish, the post goes live (or gets scheduled) — there is no pending-review state, no sign-off step, no multi-stage pipeline. Same for revisions: there's no version history to roll back to. If your organization needs legally mandated multi-step sign-off, you need a different class of tool, and you should know that before adopting — not after.

But for typical content teams, role-based gating gets you a working review flow:

  • Writers get the contributor role. They create and edit drafts. The publish action simply isn't available to them.
  • Editors get publish. A draft goes live only when someone with the editor role decides it does. That's a human review gate, enforced by permissions instead of workflow software.
  • Scheduling covers the calendar. An editor can set a future publish date, and the scheduler flips the post live at that time — useful for queueing a week of reviewed posts in one sitting.
  • The activity log covers accountability. UnfoldCMS includes an activity log (Spatie's activitylog package), so changes are traceable to a user after the fact.

The trade-off is real: nothing forces an editor to read carefully before publishing, and there's no second approver. You're trusting roles plus process, not software-enforced pipelines. For a six-person blog, that's the right amount of machinery. For a bank's legal team, it isn't.


How UnfoldCMS implements RBAC (worked example)

UnfoldCMS builds its RBAC on Spatie's laravel-permission package — the de facto standard in the Laravel ecosystem — with a super admin bypass, custom roles managed from the admin UI, and two-layer middleware enforcement. Disclosure up front: UnfoldCMS is our product, so treat this section as a worked example, not a neutral review.

The concrete pieces:

  • Spatie laravel-permission underneath. Roles and permissions live in the database, not in code, so they're editable at runtime. Any Laravel developer already knows this package's API ($user->can(), hasRole()), which means zero learning curve for customization.
  • Super admin bypass. The super admin role skips permission checks entirely. This is deliberate: it guarantees you can never lock yourself out of your own site by misconfiguring a role. Keep it to one or two trusted humans.
  • Custom roles via /admin/roles. Create a role, name it, tick the modules and actions it should have, assign users. A "Guest Blogger" or "SEO Consultant" role takes a couple of minutes, no deployment needed.
  • Module + action middleware. As covered above, routes enforce permission.module:{name} for area access and action middleware like action.delete for destructive operations. Enforcement lives at the route layer.
  • Activity log. Spatie laravel-activitylog is installed, giving you the who-changed-what trail that makes individual accounts worth having.
  • Account hardening toggles. Two settings round out the picture: 2FA via email OTP can be switched on from admin settings, and public registration can be disabled entirely so accounts only exist when an admin creates them.

What it deliberately doesn't have: approval chains, content revisions, and SSO/SAML. Those are honest gaps, and the docs say so. Full setup details live in the docs.


Onboarding and offboarding checklists

Access lifecycle is where role systems succeed or rot. Onboarding should grant the minimum role plus 2FA on day one; offboarding should remove access the same day someone leaves — not at the end of the month. Put both in a checklist so they survive staff changes.

Onboarding a new team member:

  • Create an individual account with their work email — never add them to a shared login
  • Assign the weakest archetype that covers their actual tasks (default new writers to contributor, not author)
  • Have them enable 2FA before their first real session
  • Show them where drafts live and who publishes — two minutes of process beats a wiki page
  • Note the grant: who got which role, and why, with a date

Offboarding (same day, not "soon"):

  • Disable or delete the account immediately — if they authored content, most systems let you reassign posts before deletion
  • Rotate any credentials they had access to (API tokens, shared service passwords)
  • Check the activity log for unusual recent actions — standard practice, not an accusation
  • Remove them from adjacent systems: analytics, email tools, the CMS's server if they had SSH
  • Record the removal next to the original grant

Quarterly, for everyone:

  • Read the full user list out loud. Anyone unrecognized or departed? Remove them.
  • Anyone holding admin who hasn't needed it in months? Downgrade.
  • Confirm super admin is still held by exactly the one or two people who should have it.

Security pitfalls that actually bite

The common failures are organizational, not technical: shared logins that erase accountability, roles granted "to be safe" that never get reviewed, and accounts that outlive their owners. Each has a structural fix that takes minutes to apply.

  • Shared logins. One password for the "content team" means no audit trail, no individual 2FA, and a password that's only as safe as the sloppiest member's password manager. Fix: individual accounts, always. Accounts are free.
  • Over-granted roles. "Just make them admin so they stop asking" is how every team ends up with nine admins. Each unnecessary admin multiplies your phishing surface. Fix: default to the lower role; upgrades are cheap.
  • Stale accounts. The most boring and most exploited gap. Fix: same-day offboarding plus the quarterly review above.
  • Open registration left on. If public signup is enabled and a role-assignment bug or misconfiguration exists, strangers can create accounts on your admin domain. If your site doesn't need public accounts, turn registration off — in UnfoldCMS it's a single settings toggle.
  • No second factor on privileged accounts. A password alone protecting an admin account is 2015-era security. Turn on 2FA at minimum for admin and editor roles.
  • Permissions only checked in the UI. Hiding a button isn't enforcement — the API route behind it must check too. This is why middleware-level enforcement matters; test your API endpoints with a low-privilege token, not just the admin panel.

Roles are one layer of a self-hosted security posture — server hardening, updates, and backups are the others, and we covered those in the self-hosted CMS security guide.

If you'd rather see all of this than read about it, try UnfoldCMS — roles, permissions, activity log, and the 2FA toggle ship in every tier, and pricing is on /pricing.


FAQ

How many roles should a small content team have?

Three is usually enough: one admin, one editor role for whoever reviews and publishes, and author or contributor for writers. Add custom roles only when someone's real tasks don't fit — a fourth role for an SEO consultant is common. More than six roles on a ten-person team is a smell.

What's the difference between a super admin and an admin?

A super admin bypasses permission checks entirely — in UnfoldCMS, that's by design, so you can never lock yourself out. An admin manages the site day-to-day but can still be constrained by role settings. Keep super admin to one or two people and use admin for everyone else who runs the site.

Can I run an editorial review process without a workflow feature?

Yes, with roles: give writers a contributor-style role that can draft but not publish, and reserve publish for editors. The permission boundary becomes the review gate. The limit is that nothing in software forces the review to be thorough — it's role-enforced, not pipeline-enforced. UnfoldCMS works exactly this way, since it has no approval chains.

How often should I audit CMS user accounts?

Quarterly for a standing review of the full user list, plus immediately whenever someone leaves the team. The quarterly pass checks three things: unknown or departed accounts, over-granted roles that should be downgraded, and the super admin list. Fifteen minutes, four times a year.

Sources

Free & Open Source

Own your CMS. No subscriptions.

Unfold CMS is free to download and self-host. Built on Laravel + React, full source code included.

Share this post:

Discussion

Comments (0)

Leave a Comment

Please log in to leave a comment.

Don't have an account? Register here

No comments yet. Be the first to share your thoughts!

Keep Reading

Related Posts

Back to all posts
Powered by UnfoldCMS