Permissions
The Ellemment Stack implements Role-Based Access Control (RBAC) for fine-grained permission management. This system provides flexible, scalable access control through roles and permissions.
Core Concepts
Permission Structure
- Users have roles
- Roles have permissions
- Permissions are cumulative
- Most permissive access wins
Default Permissions
The system includes granular permissions for:
- Actions:
create
,read
,update
,delete
- Resources:
user
,note
- Access levels:
own
,any
Default Roles
user
: Basic access rightsadmin
: Extended privileges
Implementation
Server-Side Utilities
// Permission check const userCanDeleteAnyUser = await requireUserWithPermission( request, 'delete:user:any' )
// Role check const userIsAdmin = await requireUserWithRole(request, 'admin')
Client-Side Utilities
// In components const user = useUser() ,[object Object],
// Role check const userIsUser = userHasRole(user, 'user')
Permission Management
Database Schema
model Permission {
id String @id @default(cuid())
action String // create, read, update, delete
entity String // resource type
access String // own, any
description String @default("")
roles Role[]
@@unique([action, entity, access])
}
model Role {
id String @id @default(cuid())
name String @unique
description String @default("")
users User[]
permissions Permission[]
}
Access Patterns
- Direct Access
// Check specific permission if (await userHasPermission(user, 'create:note:own')) { // Allow operation }
- Role-Based Check
// Check role membership if (await userHasRole(user, 'admin')) { // Allow admin operation }
- Combined Checks
// Complex permission logic if ( await userHasPermission(user, 'update:note:any') || (await userHasPermission(user, 'update:note:own') && note.authorId === user.id) ) { // Allow operation }
Best Practices
Permission Design
- Keep permissions atomic
- Use clear naming conventions
- Document access patterns
- Maintain role hierarchy
Security Considerations
- Always verify server-side
- Never trust client state
- Audit access regularly
- Log permission changes
Role Management
- Limit admin access
- Review role assignments
- Document role purposes
- Regular access review
Production Setup
Initial Configuration
- Define base roles
- Set up permissions
- Create admin users
- Configure access patterns
Database Seeding
See the deployment documentation for:
- Production seeding steps
- Role configuration
- Permission setup
- Access initialization
Utilities
Server-Side
// Permission middleware export async function requirePermission( request: Request, permission: string ) { const user = await authenticateUser(request) if (!await userHasPermission(user, permission)) { throw new ForbiddenError() } return user }
Client-Side
// Permission hook export function usePermission(permission: string) { const user = useUser() return userHasPermission(user, permission) }
For more information about security implementation, see the security documentation.