Roles & Permissions
SkaleData defines four org-level roles, managed through Clerk. Each user in an org has exactly one role. Roles are hierarchical — higher roles inherit all permissions of lower roles.
Role hierarchy
| Level | Role | Description | Typical user |
|---|---|---|---|
| 4 | Owner | Full control — billing, org settings, destroy clusters, manage members | Founder, CTO |
| 3 | Admin | Manage clusters, clouds, apps, API keys. No billing or org deletion | Data lead, platform engineer |
| 2 | Operator | Deploy apps, manage DAGs, view logs, restart apps, terminal access | Data engineer, analytics engineer |
| 1 | Viewer | Read-only access to all resources in the org | Stakeholder, new hire |
Permission matrix
Owner only
| Action | Endpoint |
|---|---|
| Update org settings | PATCH /orgs/me |
| Manage billing (subscribe, cancel, change plan) | POST /billing/* |
| Create Stripe portal session | POST /billing/portal-session |
Admin and above
| Action | Endpoint |
|---|---|
| Create cluster | POST /clusters |
| Update cluster config | PATCH /clusters/{id} |
| Upgrade cluster version | POST /clusters/{id}/upgrade |
| Apply cluster (re-run terraform) | POST /clusters/{id}/apply |
| Retry failed cluster | POST /clusters/{id}/retry |
| Destroy cluster | DELETE /clusters/{id} |
| Manage node pools | POST/PATCH/DELETE /node-pools/* |
| Link/unlink cloud accounts | POST/DELETE /clouds/* |
| Verify cloud | POST /clouds/{id}/verify |
| Cancel jobs | POST /jobs/{id}/cancel |
| Create/revoke API keys | POST/DELETE /api-keys/* |
| GitHub integration | GET/POST /github/* |
Operator and above
| Action | Endpoint |
|---|---|
| Deploy custom image | POST /clusters/{id}/deploy-image |
| Upload DAGs | POST /applications/{id}/dags |
| Restart application | POST /applications/{id}/restart |
| Retry failed app | POST /applications/{id}/retry |
| Update app config | PATCH /applications/{id} |
| Delete application | DELETE /applications/{id} |
| Add app to cluster | POST /clusters/{id}/add-app |
| Get deploy script | GET /clusters/{id}/deploy-script |
| Create registry token | POST /clusters/{id}/registry-token |
| Dev credentials | POST /applications/{id}/dev-credentials |
| Terminal pod setup | POST /clusters/{id}/terminal/setup |
Viewer (all authenticated users)
| Action | Endpoint |
|---|---|
| List/get clusters | GET /clusters, GET /clusters/{id} |
| List/get applications | GET /applications, GET /applications/{id} |
| View application health | GET /applications/{id}/health |
| List/get jobs | GET /jobs, GET /jobs/{id} |
| View pod list and logs | GET /clusters/{id}/pods, GET /clusters/{id}/pods/{name}/logs |
| List clouds | GET /clouds, GET /clouds/{id} |
| View billing status | GET /billing/subscription |
| View org info | GET /orgs/me |
Backwards compatibility
If a Clerk JWT does not contain a role claim (e.g., older Clerk configurations), the user defaults to the admin role. This ensures existing users are not locked out when RBAC is first enabled.
Setting up roles in Clerk
Create these four custom roles in your Clerk Dashboard under Organizations > Roles:
owner— assign to org creatorsadmin— default for existing membersoperator— for engineers who deploy but don’t manage infrastructureviewer— for read-only stakeholders
Clerk automatically includes the role in the JWT’s o.rol field.
Last updated on