Role‐Based Access Control (RBAC) - sonuprajapati15/Authentication-Authorization GitHub Wiki

System Design: Role-Based Access Control (RBAC) Authentication & Authorization

1. Overview

Role-Based Access Control (RBAC) is an authorization model where users are assigned roles, and roles have specific permissions to access resources. This provides structured access control and prevents unauthorized actions.

🔹 Example:

  • Admin → Can create, read, update, and delete users.
  • Editor → Can create and edit content but cannot delete.
  • Viewer → Can only read content.

2. Functional & Non-Functional Requirements

Functional Requirements

✅ Users can authenticate and receive an access token.
✅ Users have roles (Admin, Editor, Viewer, etc.).
✅ Roles have permissions (create, read, update, delete).
✅ API endpoints enforce role-based access control.
✅ Admins can manage roles and permissions dynamically.

Non-Functional Requirements

Security – Prevent unauthorized access using proper role validation.
Scalability – Support thousands of users with efficient role checks.
Performance – Optimize role validation with caching (e.g., Redis).
Compliance – Ensure GDPR, HIPAA compliance for sensitive data.
Flexibility – Allow easy addition of new roles and permissions.


3. High-Level Design (HLD)

Architecture Components

  1. User Management Service – Handles authentication & role assignment.
  2. RBAC Middleware – Validates roles & permissions before granting access.
  3. Resource Server – Hosts protected endpoints that require role-based access.
  4. Database – Stores user roles, permissions, and assignments.
  5. Caching Layer (Redis) – Caches role-permission mappings for performance.

RBAC Workflow

  1. User logs in – Receives a JWT token with role information.
  2. Client sends request – Includes JWT in headers (Authorization: Bearer <token>).
  3. RBAC Middleware validates role – Checks if the role has required permissions.
  4. Access granted or denied – If permitted, request proceeds; otherwise, access is denied.

4. Low-Level Design (LLD)

Database Schema

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(255) UNIQUE NOT NULL,
    password_hash TEXT NOT NULL,
    role_id INT REFERENCES roles(id)
);

CREATE TABLE roles ( id SERIAL PRIMARY KEY, name VARCHAR(50) UNIQUE NOT NULL );

CREATE TABLE permissions ( id SERIAL PRIMARY KEY, name VARCHAR(50) UNIQUE NOT NULL );

CREATE TABLE role_permissions ( role_id INT REFERENCES roles(id) ON DELETE CASCADE, permission_id INT REFERENCES permissions(id) ON DELETE CASCADE, PRIMARY KEY (role_id, permission_id) );

API Endpoints

Method Endpoint Description
POST /login Authenticate user and return JWT token
GET /users (Admin) List all users
POST /roles (Admin) Create a new role
POST /permissions (Admin) Define new permissions
POST /assign-role Assign role to a user
GET /dashboard (Editor, Admin) Access dashboard
GET /reports (Viewer, Admin) View reports

6. Diagrams

Here is the RBAC Authorization Flowchart:

RBAC Authorization Flow

View or edit this diagram in Whimsical.


7. Code Implementation (Node.js + Express + JWT + Redis for Caching)

1. Install Dependencies

npm install express bcrypt jsonwebtoken redis dotenv

2. Setup Express Server with RBAC Middleware

require("dotenv").config();
const express = require("express");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const redis = require("redis");

const app = express(); app.use(express.json());

const redisClient = redis.createClient({ url: process.env.REDIS_URL });

// Mock database const users = [ { id: 1, username: "admin", passwordHash: bcrypt.hashSync("password", 10), role: "admin" }, { id: 2, username: "editor", passwordHash: bcrypt.hashSync("password", 10), role: "editor" }, { id: 3, username: "viewer", passwordHash: bcrypt.hashSync("password", 10), role: "viewer" } ];

const permissions = { admin: ["manage_users", "create_content", "view_reports"], editor: ["create_content", "edit_content"], viewer: ["view_reports"] };

// RBAC Middleware const authorize = (requiredPermission) => (req, res, next) => { const token = req.headers.authorization?.split(" ")[1]; if (!token) return res.status(401).json({ message: "Unauthorized" });

try { const { role } = jwt.verify(token, process.env.JWT_SECRET); if (!permissions[role]?.includes(requiredPermission)) { return res.status(403).json({ message: "Access Denied" }); } next(); } catch { return res.status(401).json({ message: "Invalid Token" }); } };

// Login Route app.post("/login", async (req, res) => { const { username, password } = req.body; const user = users.find((u) => u.username === username); if (!user || !(await bcrypt.compare(password, user.passwordHash))) { return res.status(401).json({ message: "Invalid credentials" }); }

const token = jwt.sign({ role: user.role }, process.env.JWT_SECRET); res.json({ message: "Login successful", token }); });

// Protected Routes app.get("/users", authorize("manage_users"), (req, res) => res.json({ message: "User Management" })); app.get("/dashboard", authorize("create_content"), (req, res) => res.json({ message: "Dashboard Access" })); app.get("/reports", authorize("view_reports"), (req, res) => res.json({ message: "Report Viewing" }));

app.listen(3000, () => console.log("RBAC Server running on port 3000"));


RBAC Middleware (Role Validation Logic)

  • Admin → Can manage users, roles, permissions.
  • Editor → Can manage content but not users.
  • Viewer → Can only read content.

Caching Strategy

  • Redis stores role-permission mappings for fast lookup.
  • Cache invalidation occurs when a role or permission changes.

5. Trade-offs & Scalability

Factor Trade-off
Security RBAC is strong, but requires careful role management.
Performance Using caching (e.g., Redis) reduces DB queries for role validation.
Flexibility Adding new roles & permissions is easy but requires schema updates.
Scalability Works well for large-scale systems but may need distributed caching in microservices.

8. Conclusion

RBAC enhances security by ensuring users can only access what they are authorized for. It is efficient, scalable, and widely used in enterprise applications.

⚠️ **GitHub.com Fallback** ⚠️