Documentation

Settings

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 rights
  • admin: 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

  1. Direct Access
// Check specific permission
if (await userHasPermission(user, 'create:note:own')) {
  // Allow operation
}
  1. Role-Based Check
// Check role membership
if (await userHasRole(user, 'admin')) {
  // Allow admin operation
}
  1. 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

  1. Keep permissions atomic
  2. Use clear naming conventions
  3. Document access patterns
  4. Maintain role hierarchy

Security Considerations

  1. Always verify server-side
  2. Never trust client state
  3. Audit access regularly
  4. Log permission changes

Role Management

  1. Limit admin access
  2. Review role assignments
  3. Document role purposes
  4. Regular access review

Production Setup

Initial Configuration

  1. Define base roles
  2. Set up permissions
  3. Create admin users
  4. 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.