Appearance
Permissions & CASL
Authorization is implemented with CASL, an isomorphic authorization library. The TenantGuard resolves the caller's role and builds an AppAbility object that is checked against @CheckAbility decorators.
Roles
| Role | Who has it |
|---|---|
superadmin | Users in the super_admins table — cross-tenant admin |
admin | Users in the tenant_admins table for the requested tenant |
responsible | Users who are the responsibleId on at least one project in the tenant |
user | All other authenticated tenant members |
Role resolution
TenantGuard resolves roles in this priority order:
- SuperAdmin — check
super_adminstable - Admin — check
tenant_adminstable - Responsible — check if the user is a
responsibleIdon any project - User — default for all other authenticated tenant members
API key authentication always grants admin access to the key's own tenant.
Permission matrix
| Subject | Action | superadmin | admin | responsible | user |
|---|---|---|---|---|---|
Tenant | create | ✓ | — | — | — |
Tenant | read | ✓ | ✓ (own) | ✓ (own) | ✓ (own) |
Tenant | update | ✓ | ✓ (own) | — | — |
TenantUser | manage | ✓ | ✓ | — | — |
TenantUser | read | ✓ | ✓ | ✓ | ✓ |
Entry | manage | ✓ | ✓ | ✓ | own only |
Invoice | manage | ✓ | ✓ | ✓ | create + read |
Project | manage | ✓ | ✓ | — | — |
Project | read | ✓ | ✓ | ✓ | ✓ |
TaskList | manage | ✓ | ✓ | — | — |
TaskList | read | ✓ | ✓ | ✓ | ✓ |
Vehicle | manage | ✓ | ✓ | — | — |
Vehicle | read | ✓ | ✓ | ✓ | ✓ |
Sync | manage | ✓ | ✓ | — | — |
ApiKey | manage | ✓ | ✓ | — | — |
Webhook | manage | ✓ | ✓ | — | — |
Notification | manage | ✓ | own | own | own |
all | manage | ✓ | — | — | — |
Using @CheckAbility
Apply @CheckAbility on a controller method to require a specific permission:
typescript
import { CheckAbility } from '../../casl/decorators'
@Get()
@CheckAbility({ action: 'read', subject: 'Entry' })
findAll() { ... }
@Post()
@CheckAbility({ action: 'create', subject: 'Invoice' })
create() { ... }
@Delete(':id')
@CheckAbility({ action: 'delete', subject: 'Project' })
remove() { ... }If the caller's ability does not satisfy the requirement, TenantGuard returns 403 Forbidden.
Available actions and subjects
Actions: manage | create | read | update | delete
(manage implies all other actions)
Subjects: Tenant | TenantUser | TenantAdmin | Entry | Invoice | Project | TaskList | Vehicle | Notification | Sync | ApiKey | Webhook | all