Scalable Access Control for Your Web App: The Handbook

Access control is crucial for preventing unauthorized access and ensuring that only the right people can access sensitive data in your application. As your app grows in complexity, so does the challenge of enforcing permissions in a clean and efficie...

Feb 5, 2025 - 03:10
 0
Scalable Access Control for Your Web App: The Handbook

Access control is crucial for preventing unauthorized access and ensuring that only the right people can access sensitive data in your application. As your app grows in complexity, so does the challenge of enforcing permissions in a clean and efficient way.

In this handbook, we’ll explore various access control mechanisms and walk through two approaches for building a scalable Attribute-Based Access Control solution in React.

First, we'll examine CASL, a popular open-source authorization library. Then, we’ll build a custom solution from scratch to deepen your understanding of how to design a flexible permissions validation system.

This guide includes detailed code walkthroughs for both approaches, covering key concepts such as state management, custom hooks, and caching/conditional queries using Redux Toolkit.

If you plan to implement the code, you should have a basic understanding of how a web app using state management works. But even if you're not coding along, you’ll still gain valuable insights into the design patterns and best practices behind creating a robust permissions validation system.

Let’s dive in!

Table of Contents

What is Access Control? How is it Different from AuthZ, AuthN, and Permissions?

Let me break down these terms using the example of an airport.

When you arrive at the check-in counter, you present your passport to verify your identity. Authentication (Who are you?) is the process of confirming that you are who you say you are.

Once your identity is confirmed, the airline checks if you are authorized to board the flight by verifying your ticket, or if you are authorized to access the lounge by reviewing your membership status, class of travel, or loyalty program tier. Authorization (What are you allowed to do?) is about determining what specific resources you are permitted to access.

Permissions (What specific actions can you take?) are the granular details of what you're allowed to do within the scope of your authorization. If you’re authorized to board the flight and access the lounge, your permissions might include: sitting at the boarding gate, relaxing in the lounge, shopping in duty-free, or if you’re staff, accessing restricted areas.

Access control refers to the measures in place to enforce authorization policies. These are the rules the airport follows to validate boarding passes or lounge access, and to guide you to the correct gate.

Multi-layered Access Control

To ensure comprehensive protection, access control should be enforced at multiple layers, depending on your application architecture.

To understand this, here’s a little something for my fellow Potter-heads:

Hogwarts in Harmony: A Unified Defense

At the very edge of Hogwarts, you’ve got your Perimeter—the outer defenses that keep dark forces at bay. Think of these as the high, enchanted stone walls that surround the castle—acting like a firewall, with winged boar statues perched on the parapets, keeping watch. Only those with proper clearance are allowed through the gates, ensuring that no unwanted guests, like dark wizards, can enter.

When students arrive at Hogwarts, they come by boats or Thestral-pulled carriages, which are the only trusted means of transport. This is like Endpoint Detection and Response (EDR), ensuring that only the right devices (or carriages) are allowed entry.

If a student tries to use a non-compliant device (like a cursed broomstick or Apparition), they won’t be allowed inside. Mobile Device Management (MDM) acts like the magical inspection process—only devices that meet Hogwarts' standards can pass through the gate and connect to the school’s systems.

At Hogwarts, owls are the trusted messengers that carry messages between the school and the outside world. These owls, like API keys and JWTs, carry the seal of approval and only deliver messages to the right recipients. Dark creatures like Dementors are forbidden from delivering messages, ensuring that only the right communications make it through.

The Acceptance Letter from Hogwarts is like an OAuth token. It proves you belong to the magical world and grants you access to the school without needing to show your face or reveal your blood status.

Inside the castle, access to different areas is controlled by who you are and your role at Hogwarts. For example, Role-Based Access Control (RBAC) ensures that only Gryffindors can access their common room, while Slytherins have their own. Prefects get additional privileges, like access to the Prefect's bathroom or other special rooms. These roles define where you can go and what you can do within the castle.

But things get more nuanced with Attribute-Based Access Control (ABAC). For instance, only students enrolled in Care of Magical Creatures have access to the Forbidden Forest, but they’re only allowed in during daylight hours, when it's safer. The forest is too dangerous at night, and only those with the right attributes (like a specific timetable) can enter at the right time.

Within Hogwarts is the Philosopher’s Stone, hidden away in a vault guarded by powerful enchantments. This is your Data Layer – the most precious resources, secured by powerful protections. Just like database permissions, the vault is protected by Fluffy, the three-headed dog, a series of enchantments, and traps. Similarly, row-level and column-level security ensure that only Harry Potter can retrieve the Stone because he is the only one worthy (you can only access what’s meant for you).

To summarize,

  1. Network Layer (Infrastructure-level): Firewalls and virtual private networks (VPNs) to control incoming and outgoing network traffic.

  2. Endpoint Layer (Device-level): Endpoint Detection and Response (EDR) and Mobile Device Management (MDM) to ensure only compliant device can access your application.

  3. API Layer (Service-level): API keys, JSON Web Tokens (JWTs), and API gateways to authenticate and authorize the caller and enforce policies such as rate limiting, IP whitelisting, and so on.

  4. Application Layer: Where the core business logic for authorization typically resides (which this guide is all about).

  5. Data Layer (Database-level): Database permissions, row/column-level security.

Access Control Models

At the application layer, three primary models of access control are commonly used in software engineering: Role-Based Access Control (RBAC), Attribute-Based Access Control (ABAC), and the more recent Relationship-Based Access Control (ReBAC).

RBAC (Role-Based Access Control) is a model where access is granted or denied based on the roles assigned to a user.

A role is a collection of permissions or privileges that define what actions a user can perform within a system. Roles simplify access control by assigning users to predefined roles, rather than managing individual permissions for each user.

When a user is assigned a role, they automatically inherit all the permissions associated with that role. Each permission also has a scope, which defines the boundaries or contexts within which the role's permissions apply. Scopes are typically used to restrict access to specific resources or data.

Let me illustrate this (and all concepts throughout this guide) using a blogging application as an example. This app allows users to create, manage, and publish blog posts in multiple categories. It supports a variety of user roles, each with different levels of access to the content and functionality within the platform.

  • Admin: Can view, edit, delete, and manage all blog posts and user roles. (Scope: All posts and users)

  • Editor: Can edit and approve posts within their assigned categories (for example, Tech, Lifestyle). (Scope: Assigned categories)

  • Author: Can create and edit only their own blog posts. (Scope: Own posts)

  • Guest User: Can view public, published blog posts but cannot access private posts. (Scope: Public published posts only)

The relationship between users and roles is often many-to-many, and roles may also be hierarchical, allowing for complex permission structures.

Role-based Access Control diagram

ABAC (Attribute-Based Access Control) is a model where access decisions are made based on the attributes of the subject (user), object (resource), and the environment. It dynamically evaluates whether a subject can perform an action on an object based on these attributes and policies that govern them.

ReBAC (Relationship-Based Access Control) is an emerging model that grants access based on the relationships between users and resources. For example, it might allow only the user who created a post to edit it. This model is particularly useful in social networking applications, where access depends on user relationships (such as friends, followers, or content ownership).

Why ABAC?

RBAC provides several benefits, including ease of implementation, reduced administrative overhead by enabling quick onboarding of new users, and simplified auditing, as it makes it easy to review which roles have access to sensitive data.

But, as the platform grows, you introduce more nuanced requirements for access control. These new requirements lead to the creation of new roles to meet specific access needs:

  1. Publisher: Can view, edit, approve, publish, and delete posts across all categories, but cannot manage user roles or settings.

  2. Junior Author: Can create and edit their own posts within assigned categories.

  3. Senior Author: Can create and edit their own posts in any category.

  4. User (Subscriber): Can view and comment on private posts in addition to public posts.

  5. Premium Subscriber: Has all the permissions of a regular subscriber and access to exclusive posts.

Before long, you may find yourself managing an ever-growing list of roles such as Senior Publisher, Publishing Supervisor, Guest User, Subscriber, Premium Subscriber, Graphic Designer, UX Designer, Photographer, Social Media Manager, US Marketing Specialist, UK Marketing Specialist, Web Developer, Data Analyst, Membership Manager, Ad Manager, Legal Advisor, and Sponsor Manager.

Introducing additional requirements—such as blog category, seniority, and jurisdiction—can quickly lead to role explosion. Just imagine how this would scale in data-intensive enterprise applications like finance or healthcare.

While scopes work well when boundaries are clear and static (for example, department, blog types), they require custom checks for more granular attributes such as seniority, length of service, blog creation time, or publication status. Scopes also struggle to account for attributes that change over time, like the location or timing of access.

Because RBAC relies on roles and fixed scopes to make access decisions, it becomes limited in handling complex and dynamic access needs. That is why, OWASP (Open Worldwide Application Security Project) recommends using ABAC or ReBAC over RBAC, as they are more effective in implementing the principle of least privilege.

Attribute-Based Access Control In Depth

Core Components

The core components of ABAC are:

Attributes: Attributes are key-value pairs used to define the access context. Examples include:

  • User attributes: These describe the characteristics of the person requesting access, like role, department, age, clearance level, and so on.