Skip to main content

RBAC Architecture

Role-Based Access Control (RBAC) in Clue2App manages who can access what resources and perform which actions.

Overview

Clue2App uses a hierarchical permission model:

Account
└── Groups
└── Roles
└── Permissions

User Types

TypeDescriptionScope
SYSTEMPlatform administratorsAccess to all accounts
ACCOUNTAccount-level usersLimited to their account

Roles

Clue2App splits roles across two scopes: account (who can manage the account, its users, and its projects) and project (who can do what inside a specific project).

Account-scope roles

RolePermissions
ACCOUNT_ADMINFull account management: users, projects, limits, billing
MEMBERBelong to the account; access grants come via project roles

Project-scope roles

RolePermissions
PROJECT_ADMINFull project control (apps, secrets, domains, members)
CONTRIBUTORCreate/edit apps, deploy, view logs
VIEWERRead-only access to project resources

These are the roles the invitation flow (c2a user invite -P <project> -r <role>) grants.

Permission Matrix

PermissionACCOUNT_ADMINPROJECT_ADMINCONTRIBUTORVIEWER
Manage account users / limits
Add project members
Create / delete apps
Edit apps + env
View apps + logs

Data model note. As of V56 (account_user_roles, SCK-475) and V57 (account_limit_overrides, SCK-481), account-scope role grants and limit overrides carry created_by / updated_by / created_at / updated_at audit columns.

Architecture

How Groups Work

  1. Users belong to Groups - A user can be in multiple groups
  2. Groups have Roles - Each group is assigned one role
  3. Roles grant Permissions - The role determines what actions are allowed
  4. Permissions are additive - Users get the union of all their groups' permissions

Example

User: alice@example.com
└── Groups: [DevTeam, QATeam]
├── DevTeam → APPLICATION_ADMIN
│ └── Permissions: addApplications, editApplications
└── QATeam → APPLICATION_DEVELOPER
└── Permissions: readOnly

Result: Alice can create, edit, and view applications

Invitation Flow

The operational way users get onboarded is via invite-by-email, either from the CLI or the console.

# CLI: invite alice as a contributor on the "clues" project
c2a user invite -e alice@corp.com -P clues -r CONTRIBUTOR

# Invite bob as a project admin across two projects
c2a user invite -e bob@corp.com -P clues -P entrada -r PROJECT_ADMIN

Behind the scenes:

  1. POST /api/accounts/{accountId}/members creates the account membership and the project role grants atomically. The invitee is placed into the project's owning account, not the caller's account (SCK-475).
  2. A SoloInvitation record is issued and emailed to the invitee.
  3. When the invitee signs in via Google/OAuth for the first time, the redeem path (SCK-436) resolves the SoloInvitation — the sha256Hex of the invitee's email is compared as lowercase-hex on both sides — and completes the account + project bindings.

Legacy direct-create (POST /api/user/account/{accountId}) still works for LOCAL users but is not the recommended onboarding path.

API Endpoints

User Management

MethodEndpointDescription
GET/api/user/account/{accountId}List account users
POST/api/user/account/{accountId}Legacy: create user directly
PUT/api/user/{userId}Update user
DELETE/api/user/{userId}Delete user

Account Members & Invitations

MethodEndpointDescription
POST/api/accounts/{accountId}/membersInvite by email with atomic project grants (preferred)
GET/api/accounts/{accountId}/membersList account members and their project roles
DELETE/api/accounts/{accountId}/members/{userId}Remove a member from the account

Group Management

MethodEndpointDescription
GET/api/group/account/{accountId}List account groups
POST/api/group/Create group
PUT/api/group/{groupId}Update group
DELETE/api/group/{groupId}Delete group
GET/api/group/{groupId}/membersList group members
POST/api/group/{groupId}/membersAdd member(s) to group
DELETE/api/group/{groupId}/members/{userId}Remove member

Role Management

MethodEndpointDescription
GET/api/role/List available roles
GET/api/account-user-roles/{userId}Account-scope role grants for a user (audited: created_by / updated_by since V56)

Best Practices

Principle of Least Privilege

  • Assign users the minimum permissions needed
  • Use APPLICATION_DEVELOPER for read-only users
  • Reserve ACCOUNT_ADMIN for account owners

Group Organization

  • Create groups by team or function (e.g., "Backend Team", "DevOps")
  • Avoid assigning roles directly to users
  • Use groups to manage permissions at scale

Account Structure

  • One account per organization or project
  • Use SYSTEM type only for platform operations
  • Account owners should be ACCOUNT_ADMIN

Planned Improvements

Future enhancements to the RBAC system:

  1. Resource-Level Permissions - Control access to specific apps/services
  2. Custom Roles - Create account-specific roles
  3. Role Hierarchy - Inherit permissions from parent roles
  4. Audit Logging - Track all permission changes
  5. Temporary Elevation - Time-limited permission grants

Need help? Contact support or visit our GitHub Issues.