Role-Based Access Control (RBAC) is a crucial security mechanism that restricts system access to authorized users based on their roles. Implementing RBAC in TypeScript enhances type safety and maintainability, making it a popular choice for modern web applications.

Understanding RBAC in TypeScript

RBAC assigns permissions to roles rather than individual users. Users are then assigned roles, simplifying permission management. TypeScript's static typing helps enforce correct role and permission usage, reducing runtime errors.

Basic Components of RBAC

  • Roles: Define user categories, such as Admin, Editor, Viewer.
  • Permissions: Specific actions users can perform, like 'create', 'edit', 'delete'.
  • User Assignments: Linking users to roles.

Implementing RBAC in TypeScript

Let's explore a practical example of implementing RBAC in TypeScript, covering role definitions, permission checks, and user role assignments.

Defining Roles and Permissions

First, define roles and permissions using TypeScript enums for type safety.

enum Role {
  Admin = 'ADMIN',
  Editor = 'EDITOR',
  Viewer = 'VIEWER'
}

enum Permission {
  Create = 'CREATE',
  Read = 'READ',
  Update = 'UPDATE',
  Delete = 'DELETE'
}

Assigning Permissions to Roles

Create a mapping between roles and their permissions.

const rolePermissions: Record = {
  [Role.Admin]: [Permission.Create, Permission.Read, Permission.Update, Permission.Delete],
  [Role.Editor]: [Permission.Read, Permission.Update],
  [Role.Viewer]: [Permission.Read]
};

Defining User Roles

Represent users with their assigned roles.

interface User {
  id: number;
  name: string;
  role: Role;
}

const users: User[] = [
  { id: 1, name: 'Alice', role: Role.Admin },
  { id: 2, name: 'Bob', role: Role.Editor },
  { id: 3, name: 'Charlie', role: Role.Viewer }
];

Permission Check Function

Create a function to verify if a user has a specific permission.

function hasPermission(user: User, permission: Permission): boolean {
  const permissions = rolePermissions[user.role];
  return permissions.includes(permission);
}

// Example usage:
console.log(hasPermission(users[0], Permission.Delete)); // true
console.log(hasPermission(users[2], Permission.Delete)); // false

Practical Applications

RBAC can be integrated into various parts of a web application, such as route guards, UI components, and API endpoints, to ensure secure access control.

Example: Protecting API Endpoints

Implement middleware or guards that check user permissions before granting access to resources.

function authorize(user: User, permission: Permission): boolean {
  return hasPermission(user, permission);
}

// Usage in an API route:
if (authorize(currentUser, Permission.Delete)) {
  // Proceed with delete operation
} else {
  // Return access denied response
}

Conclusion

Implementing RBAC in TypeScript provides a robust, type-safe way to manage user permissions. By defining roles, permissions, and user assignments clearly, developers can build secure and maintainable applications.