Roles & Permissions
Comprehensive guide to the three roles in CodeCourier projects - Owner, Admin, and Member - with a full permission matrix and best practices.
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
| Action | Member | Admin | Owner |
|---|---|---|---|
| View project resources | Yes | Yes | Yes |
| Create sandboxes and runs | Yes | Yes | Yes |
| Create/edit workflows | Yes | Yes | Yes |
| Create/edit personas | Yes | Yes | Yes |
| Start issue sessions | Yes | Yes | Yes |
| View member list | Yes | Yes | Yes |
| View analytics and usage | Yes | Yes | Yes |
| Invite new members | No | Yes | Yes |
| Remove members | No | Yes (not owners) | Yes |
| Cancel invitations | No | Yes | Yes |
| Configure project settings | No | Yes | Yes |
| Configure API keys | No | Yes | Yes |
| Change member roles | No | No | Yes |
| Remove other owners | No | No | Yes |
| Delete the project | No | No | Yes |
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
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