Create a custom role β
The three default roles cover most cases, but every church eventually needs something that doesn't fit them β a treasurer who can record donations but can't see member addresses, a worship leader who manages one ministry, a volunteer coordinator who handles attendance during the week but never touches giving. Custom roles let you build exactly the bundle of permissions you want and give it a name your team recognises.

Open the create-role dialog β
From Users & Roles β Roles & Permissions, click the Add role button in the top right of the Manage roles card. The Roles & Permissions tab is only visible to users with users.manage β if you don't see it, you're probably signed in as a Leader or Viewer; switch to an Administrator account.
Fill in the three fields β
Role name β
What the role is called everywhere it appears β the chip on a user's profile, the column header in the permission matrix, the option in the role-picker when you're inviting a user. Use the title your church actually uses out loud: Treasurer, Worship Leader, Visitor Greeter, Sunday School Coordinator. Two or three words is the sweet spot.
Role key β
A short, machine-safe identifier the database and audit log use to reference the role. If you leave it blank, GCM derives one from the name β lowercase, spaces replaced with underscores, punctuation stripped. Worship Leader becomes worship_leader; Sunday School Coordinator becomes sunday_school_coordinator.
You can override it if you want something shorter (treasurer instead of church_treasurer), but pick carefully β the key is what shows up in error logs, in the audit trail, and in any custom integrations that query the role table. Once a user has been assigned the role, changing the key would orphan the assignment, so the UI doesn't let you edit it after creation. Delete and recreate if you need a different key.
TIP
Stick to lowercase letters, digits, and underscores. The auto-deriver enforces this, and the database has a unique index on (organization_id, key) so two roles in your workspace can't share a key.
Description β
A one-line note for the next admin to read. "Records donations and manages funds, but can't see member addresses or other members' giving history." Optional, but appreciated β it shows under the role name in the role list and in the column tooltip on the permission matrix.
Save and pick permissions β
Click Create. The role is inserted into roles_v2 with is_system = false (which is what makes it deletable later) and immediately appears as a new column in the permission matrix below. It starts with zero permissions checked β the matrix is your blank canvas.
Scroll the matrix and toggle on what the role needs. Each switch writes to role_permissions_v2 the moment you flip it; there's no save button. See Granting permissions for the full catalogue and common combinations.
WARNING
A custom role with zero permissions is functionally useless β assign it to a user and they can sign in but every page returns a permission-denied banner. The UI lets you create empty roles deliberately (you might want to grant permissions later) but don't leave them empty in production.
The is_system flag β
The three seeded roles have is_system = true. Yours will have is_system = false. This matters in two places:
- The role list hides the delete button on system roles. You can still toggle their permissions on or off β that's safe β but you can't remove them entirely.
- A database trigger also enforces this on the backend. Even if you bypass the UI and call the delete endpoint directly, the SQL rejects the request with a
cannot delete system roleerror.
The is_system flag is set at insertion time and can't be flipped afterwards. There's no supported way to convert a custom role into a system one, or vice versa. If you need that, contact support and we'll handle it via a platform-admin impersonation session.
Deleting a custom role β
Click the red trash icon on the row in the role list. Two checks run:
- If any users are still assigned the role, the delete is rejected with a count of how many. Reassign or remove those users first β see Invite a user for the assignment dialog.
- If the delete succeeds, every row in
role_permissions_v2for that role is also removed in the same transaction. Nothing is soft-deleted; this is a hard cleanup.
If you delete by accident, you'll need to recreate the role and re-grant the permissions. Custom roles are not in the recycle bin.
Naming patterns that work β
A few patterns we've seen pay off:
- Treasurer β
giving.view,giving.record,giving.manage,reports.view. Nothing else. Great for the cash counter and the audit committee. - Worship Leader β
members.view,events.view,events.create,events.edit,messaging.send. Scoped to the Worship Team ministry, they manage rehearsals without seeing the broader directory. - Visitor Greeter β
members.view,members.create,forms.submit. Lets the welcome-desk volunteer add new visitors during the service. - Auditor β every
viewpermission and nothing else. Same shape as Viewer but named for context so the audit log shows Auditor signed in rather than Viewer signed in.
Next β
- Granting permissions β the matrix in detail.
- Scoped permissions β restrict the role to one branch.
- Audit log of role changes β see who creates and edits roles.