Security

RBAC Enforcement

Role-based access control with centralized permission checks across UI and API layers.

Problem this solves

Permission checks duplicated across components and handlers become inconsistent and unsafe.

When to use it

  • You have owner/admin/member roles or enterprise permission tiers.
  • Different users should see or edit different resource scopes.
  • You need auditable permission decisions.

Code snippet

typescript
// lib/authz.ts
type Role = 'owner' | 'admin' | 'member';
type Action = 'project:read' | 'project:write' | 'member:invite';

const ALLOW: Record<Role, Action[]> = {
  owner: ['project:read', 'project:write', 'member:invite'],
  admin: ['project:read', 'project:write', 'member:invite'],
  member: ['project:read'],
};

export function can(role: Role, action: Action): boolean {
  return ALLOW[role].includes(action);
}

export function assertCan(role: Role, action: Action) {
  if (!can(role, action)) {
    throw new Error('Forbidden');
  }
}

Integration guide

  1. Define a single permission matrix and keep it versioned.
  2. Use `assertCan` in every sensitive server-side entry point.
  3. Gate UI affordances with the same `can` checks for consistency.
  4. Log denied attempts for security monitoring and audits.

Next step

Explore the full documentation and variants for this pattern.

Open full docs