Roles & Permissions

Comprehensive guide to the three roles in CodeCourier projects - Owner, Admin, and Member - with a full permission matrix and best practices.

5 min read
rolespermissionsaccess-control

CodeCourier uses a role-based access control (RBAC) system with three distinct roles: Owner, Admin, and Member. Each role inherits all permissions of the roles below it, creating a clear hierarchy. This page documents exactly what each role can do and provides recommendations for role assignment.

Role Hierarchy

The permission model follows a strict hierarchy:

Owner > Admin > Member

Each role includes all permissions of the roles below it. An Owner can do everything an Admin can do, and an Admin can do everything a Member can do.

Role Definitions

Owner

The Owner is the creator of the project and has unrestricted access to all features and settings. A project always has at least one owner, and this constraint is enforced at the database level - the last remaining owner cannot be removed or demoted.

Owner-exclusive capabilities:

  • Change any member's role (including promoting others to Owner)
  • Remove other owners from the project
  • Delete the project entirely
  • Transfer ownership by promoting another member and demoting themselves

Admin

Admins are trusted team members who can manage day-to-day project operations including member management and settings configuration. They have nearly all the permissions of an Owner, except for role changes and owner-level destructive actions.

Admin capabilities (in addition to Member):

  • Invite new members to the project
  • Remove members from the project (except owners)
  • Cancel pending invitations
  • Configure project settings (API keys, system prompts, environment variables)

Member

Members are regular team participants who can use all project features but cannot manage the team or critical settings. This is the default role for new invitations.

Member capabilities:

  • View all project resources (sandboxes, runs, workflows, personas, issue sessions, learnings)
  • Create and manage their own sandboxes and runs
  • Create and configure workflows and personas
  • Start and manage issue sessions
  • View and accept/decline their own invitations
  • View the member list
  • Access project analytics and usage data

Permission Matrix

ActionMemberAdminOwner
View project resourcesYesYesYes
Create sandboxes and runsYesYesYes
Create/edit workflowsYesYesYes
Create/edit personasYesYesYes
Start issue sessionsYesYesYes
View member listYesYesYes
View analytics and usageYesYesYes
Invite new membersNoYesYes
Remove membersNoYes (not owners)Yes
Cancel invitationsNoYesYes
Configure project settingsNoYesYes
Configure API keysNoYesYes
Change member rolesNoNoYes
Remove other ownersNoNoYes
Delete the projectNoNoYes

Enforcement Mechanism

Permissions are enforced server-side in every Convex query and mutation. The backend uses shared authentication helper functions that verify both identity and authorization before executing any operation:

  • getProjectForMember(ctx, projectId) - Verifies the current user is an active (non-pending) member of the project. Used by queries that need basic project access.
  • requireProjectAdmin(ctx, projectId) - Verifies the current user is an admin or owner of the project. Used by mutations that manage members and settings.
  • requireProjectOwner(ctx, projectId) - Verifies the current user is an owner of the project. Used by mutations that change roles and perform destructive operations.

These checks run on every request, ensuring that even if the frontend fails to hide a button, the backend rejects unauthorized operations.

Client-Side vs Server-Side

The frontend uses role information to show or hide UI elements (like the invite button and action menus), but this is purely a UX convenience. All actual permission enforcement happens server-side. Never rely on frontend checks alone for security.

Safety Constraints

Several safety rules prevent accidental lockout scenarios:

  • Last owner protection - If only one owner remains, that owner cannot be removed or demoted. The system checks the owner count before allowing demotion or removal.
  • Self-demotion guard - An owner can demote themselves, but only if there is at least one other owner to maintain project governance.
  • Cross-role removal guard - A non-owner admin cannot remove an owner. Only owners can remove other owners.

Best Practices

Start with Least Privilege

Assign the Member role by default when inviting new users. Promote to Admin only when the person needs to manage the team or configure project settings. Reserve Owner for users who need full project control.

Maintain Multiple Owners

For production projects, assign at least two owners. This ensures project access is maintained even if one owner becomes unavailable. It also enables ownership transfer without external intervention.

Review Membership Regularly

Periodically review the member list and remove users who no longer need access. Unlike some systems, CodeCourier does not have automatic role expiration, so manual review is the recommended approach.

Custom Roles

CodeCourier currently supports three fixed roles (Owner, Admin, Member). Custom role definitions with granular permission sets are not yet available. The three-role model covers the most common team structures and keeps the permission model easy to understand.

Next Steps