Settings & Administration
Members & Roles

Members & Roles

The Team Members page (/settings/members) manages who has access to the current workspace and what permissions they have.

Role Hierarchy

Gordon CRM uses a three-tier role system:

RoleBadgePermissions
OwnerCrown (amber)Full access. Can invite members, change roles, transfer ownership, remove members, and manage all workspace settings. One owner per workspace.
AdminShield (emerald)Can invite members, manage operational settings (sending domains, integrations), and access all CRM data. Cannot change roles or remove members.
MemberUser (slate)Standard CRM access — manage contacts, campaigns, tasks, deals, events, etc. Cannot modify workspace settings or team membership.

Single-owner rule: Each workspace has exactly one owner at any time. Ownership is transferred, never promoted — see Ownership Transfer below.

Inviting Members

Owners and Admins can invite new users via the Invite Member button.

Invite Flow

  1. Click Invite Member to open the invite dialog
  2. Enter the recipient's email address
  3. Select a role — Admin or Member (Owner is not available for invitations)
  4. Click Send Invitation

The system:

  • Checks if the email is already a workspace member → error: "This user is already a member of this workspace."
  • Checks if a pending invitation already exists → error: "An invitation has already been sent to this email."
  • Creates a row in workspace_invitations with a unique token
  • Sends an invitation email with an Accept Invitation button linking to /api/invitations/accept?token=[token]

Invitation Acceptance

When the recipient clicks the link:

  • Existing user — They are added to the workspace with the invited role
  • New user — They are redirected to sign up, and the invitation is accepted automatically after signup

Pending Invitations

Owners and Admins see a Pending Invitations section below the members list. Each pending invitation shows the email, invited role, and a Cancel button to revoke the invitation.

Role Changes

The workspace Owner can change any other member's role via the action menu (⋮) on each member row. The available actions depend on the member's current role:

Current RoleAvailable Actions
AdminMake Member, Remove
MemberMake Admin, Remove
OwnerNo actions (ownership is transferred, not demoted)

Guards

  • Self-change prevention — The owner cannot change their own role. The action menu is not shown for the owner's own row.
  • Owner protection — The owner row has no action menu at all — it cannot be demoted or removed through the standard role change flow.

Ownership Transfer

Ownership transfer is a dedicated operation that atomically moves the owner role from one user to another.

How It Works

  1. The current owner opens the action menu (⋮) on any non-owner member
  2. Selects Transfer Ownership (Crown icon)
  3. Confirms the transfer

The system performs an atomic two-step operation:

  1. Demote all current owners to Admin (UPDATE ... SET role = 'admin' WHERE role = 'owner')
  2. Promote the target user to Owner (UPDATE ... SET role = 'owner' WHERE user_id = target)

Important: This is a transfer, not a promotion. The previous owner becomes an Admin. There is never more than one owner at any time. This prevents ambiguity about who holds the final authority for the workspace.

Guard Rails

RuleBehavior
Self-transferCannot change your own role (server-side guard)
Non-owner initiatorOnly the current owner (or a super-admin) can initiate transfers
Atomic operationBoth the demote and promote happen in sequence — if either fails, the operation returns an error

Removing Members

The workspace owner can remove any member (except themselves) via the action menu. A confirmation dialog appears before removal. Removing a member deletes their workspace_users row — they lose all access to the workspace immediately.

Super-Admin Bypass

Users with the is_super_admin flag on their user_profiles record bypass all workspace-level role checks. The requireRole() function checks for super-admin status before evaluating workspace membership.

This means a super-admin can:

  • Transfer ownership on any workspace (even if they are not a member)
  • Change roles for any member in any workspace
  • Perform any owner-level operation without being the workspace owner

Super-admin status is set directly in the database (user_profiles.is_super_admin = true). There is no UI to grant or revoke super-admin status — it is a platform-level flag managed by the database administrator.

Data Model

workspace_users

ColumnTypeDescription
iduuidPrimary key
workspace_iduuidFK to workspaces.id
user_iduuidFK to user_profiles.id (and auth.users.id)
roletext'owner', 'admin', or 'member'
created_attimestamptzWhen the user joined the workspace

workspace_invitations

ColumnTypeDescription
iduuidPrimary key
workspace_iduuidFK to workspaces.id
emailtextInvited email address
roletext'admin' or 'member' (owners cannot be invited)
tokenuuidUnique token used in the acceptance URL
invited_byuuidFK to the user who sent the invitation
accepted_attimestamptzNULL while pending, set when accepted
created_attimestamptzWhen the invitation was created