Security meets Usability: Crafting Dynamic and Granular Access Control Solutions

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

As applications scale in complexity, managing user permissions becomes a growing challenge. Without a structured approach, permissions quickly become a tangled mess of if-else statements, leading to poor maintainability and scalability. While Role-Based Access Control (RBAC) provides a strong starting point for managing user access, it may not offer the level of granularity needed as your app evolves. To gain finer control over who can perform what actions, on which objects, and under what conditions, the Attribute-Based Access Control (ABAC) model, recommended by OWASP, becomes invaluable.


In this session, we’ll explore two practical approaches to building a scalable permissions system in React. First, I'll introduce CASL, a popular ABAC library that simplifies fine-grained access control. Then, I'll walk you through creating a custom permissions system from scratch, offering insight into designing a solution that fits your app’s needs.


Throughout the session, I'll conduct detailed code walkthroughs for both approaches, covering key concepts like optimized state management, custom hooks, and caching/conditional queries using Redux Toolkit. You’ll learn how to implement these strategies to create a clean, efficient, and maintainable permissions framework.


By the end of the session, you’ll have a solid understanding of how to implement scalable permission systems in React, whether you choose a pre-built solution like CASL or build your own.

This talk has been presented at React Summit 2025, check out the latest edition of this React Conference.

FAQ

Samhita is a full-stack engineer at BlackRock.

RBAC grants access based on user roles, while ABAC uses user attributes, resource attributes, and environmental attributes, making it more effective for dynamic access needs and the principle of least privilege.

The four core components of ABAC are user attributes, resource attributes, environmental attributes, and access control policies.

CASL is an open-source JavaScript library that allows you to define permissions in a declarative manner, focusing on what the user can or cannot do rather than how to check for permissions.

Building your own solution offers complete control over security logic, avoiding potential vulnerabilities and issues with documentation in third-party libraries, which is crucial for applications dealing with sensitive data.

'Policy as code' involves using code or configuration files like JSON or YAML to define and manage policies, allowing for version control and easier scalability.

Policies can be managed using a policy management service and evaluated using evaluators like Google's common expression language, ensuring consistent and scalable access control.

Challenges include ensuring policy consistency across multiple front-ends and back-ends, handling dynamic access needs, and maintaining a scalable and efficient solution without duplicating rules across layers.

Access control is crucial because it ensures that sensitive data is accessed only by those who truly need it. OWASP lists broken access control as the number one security risk in web applications.

Access control should be enforced both on the front-end and back-end. The front-end provides instant feedback to the user, while the back-end ensures security as front-end controls can be bypassed.

Samhitha Rama Prasad
Samhitha Rama Prasad
21 min
17 Jun, 2025

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Samhita emphasizes the importance of access control in web applications and the shift towards attribute-based access control for enhanced security. Attribute-based access control considers user attributes, resource attributes, and environmental factors for access granting. Implementation challenges include the need for both front-end and back-end enforcement to prevent bypassing. Permission definition in CASL involves assigning abilities based on user roles using keywords and operators. Policy implementation involves defining policies for UI and server compatibility, grouping policies by resource, and using CEL for conditions evaluation. Access control evaluation requires handling dynamic business logic, enforcing permissions with CASL components, and implementing protected routes based on user permissions.

1. Introduction to Access Control

Short description:

Samhita, a full-stack engineer at BlackRock, discusses the importance of access control in web applications and the shift towards attribute-based access control for enhanced security.

Hey, everyone. I'm Samhita. I'm a full-stack engineer at BlackRock. And here's a little something about me. Now, if we were doing this session in person, we would have played a quick icebreaker game. I would have bragged about my benching abilities and showed you a lot of memes. But unfortunately, I couldn't join you in Amsterdam this year. So, we'll have to skip all of this and dive right in. Let's get started.

Imagine you're building access control into your web application. So, first question you'd probably ask yourself is, what strategies should I use to make sure that sensitive data is accessed by only those who truly need it? Then you might start thinking. Should I implement it at the component level or the API layer? Or is it safe for the back end to handle it all? Then you might consider another layer of complexity. How do I integrate all of these permissions with business logic checks and feature flags so that certain features are only available to specific users?

By now, I hope you understand that access control is not a single decision and you'd have to think through multiple layers in your architecture in order to get it right. So, in today's session, we'll be going over all of this and explore two ways to implement access control that's granular, dynamic, and scalable. Why should you care about this? OASP has listed broken access control as the number one security risk in web applications. They also recommend attribute-based access control over the traditional role-based access control, which grants access to users only based on the user's roles.

2. Implementation of Attribute-Based Access Control

Short description:

Attribute-based access control ensures robust security by considering user attributes, resource attributes, and environmental factors in granting access. Enforcement on the front end provides instant feedback to users but must be complemented by back-end enforcement to prevent bypassing. Implementing access control solely on the front end poses scalability challenges and requires policy consistency across layers, necessitating a centralized back-end approach for defining permissions.

Why? Because attribute-based access control is more effective in implementing the principle of least privilege, and it also handles dynamic access needs. Let's see how. Consider Sam, who is a publisher for a blogging application. When she joined, she was assigned categories within which she can take actions. The access control rule is that publishers can publish approved posts in their assigned categories but only during business hours. Whenever a blog post is created, it is given a category. It is initially unreviewed but gets eventually approved by the editor. Now, if Sam wants to publish this post, access is granted not just based on her role, which is the case with role-based access control, but also based on her attributes, the attributes of the resource, which is the post, and environmental attributes like time and location. These three, along with the access control policies themselves, are the four core components that make up ABAC. If any of her attributes change, like she moves to the membership department or is assigned to fashion, her access is automatically revoked. And because all these attributes are incorporated into the decision-making process, your application's security is much more robust.

Where should you enforce it? You would enforce access control on the front end so that users have instant feedback. They immediately know what they can or cannot do, and this makes for a very intuitive UI. This is a crude example of what it might look like. Apart from the fact that it's an FL-stangle and the solution is not scalable, the problem here is that front-end access control is only the first line of defense. It's like hanging a do not enter sign on your door and not actually locking it. So it's very crucial that you also enforce access control in the back end because front-end access control can be easily bypassed with the right tools. So you might replicate the same rules on the back end. That's a lot of duplication and it's difficult to ensure policy consistency across both the layers, which is why even though your policy enforcement needs to happen on both the front-end and the back-end, the definition of the rules or your permissions themselves need to be on the back-end as a single source of truth. So you may offload your entire access control logic to the back end and have the front end make an API call to the back end and get the access control decision.

This solution is secure, but it introduces trade-offs in terms of usability and performance, especially in ABAC because we saw how it depends on dynamic factors like user, resource, and environmental attributes. And every time these attributes change, your UI needs to trigger an API call to the back end to get the updated access control decision, which causes latency and a laggy user experience. And not to mention, if there are any policy updates or policy additions, your code needs to be rewritten. Also, how would you handle feature flags like premium users or exclusive resources? And what about when there are multiple front ends and multiple back-end services? How would you ensure policy definition consistency across these layers? And more importantly, how do you create a scalable solution that satisfies all the design criteria that we discussed so far? Like I said in the beginning, we'll be going over two solutions. The first one is CASL. It's an open-source JavaScript library which allows you to define permissions in a declarative manner, like what the user can or cannot do instead of worrying about how to check for permissions. Consider these examples from our blogging application. An admin can manage everything. An author can create and edit their own posts within assigned categories, but cannot delete published posts. These are called abilities in CASL.

3. Implementation of Permission Definition in CASL

Short description:

Define functions to assign abilities based on user roles. Use keywords like manage and all in CASL for specifying permissions. Utilize operators like in for defining conditions. Combine rules with logical operators for a unified permission system.

Let's convert this into code. Let's begin by defining a function called defineAbilityFor, which takes in the user as an input and returns the user's abilities. If the user is an admin, the user can manage all. Manage and all are keywords in CASL where manage means any action and all means any subject. If the user is an author, the user can create a post but cannot delete a post. You can also type check these abilities by defining a type for the actions and subjects and creating an ability object which conforms to the defined types.

Note here that createMongoAbility does not mean that your application has to use MongoDB. It only means that we'll be using certain operators from the MongoDB query language. One such operator is the in operator, which is used to specify conditions on these abilities. For example, the user can create a post in a tech and lifestyle or the user can update only the title and description fields of their own posts which are in draft state. If the description object is nested, you can use a wildcard to state that you only want to grant access to the top-level fields. Finally, you can use cannot to describe what the user cannot do, like deleting published posts.

Behind the scenes in Kazzle, these can rules are combined using logical or and inverted rules, like cannot and all the conditions are going to be combined using logical and, which are the pink boxes that you see. Okay, so remember this, we have the definability for function which returns all the abilities for the user. Because the permission definition needs to be a single source of truth, this is going to be a shared library between the UI and the server. Once the user is authenticated, you would invoke this definability for function and get the user's abilities. To validate an action on the server side, you would do ability.can and pass the action and the subject. The same ability.can function can be used on the front-end to perform programmatic checks and it returns a boolean true or false.

4. Considerations for Security Logic Control

Short description:

Create a context for application-wide access to abilities. Understand the distinction in permission checks. Consider the implications of third-party libraries for security logic control.

Better yet, create a context and pass the ability instance to the application so that all the components in the app have access to it. Bazel also provides an option to create a contextual can component, which is like a wrapper component around other components that you can use for conditional rendering.

Can I delete a post? Do you see how readable the permission check is? It means that you are asking if you have the permission to delete at least one post. But on the other hand, if you ask, can I delete this post, it means that you are asking if you have the permission to delete that particular instance of the post because post here is the type of the subject. It can be a tad confusing, which brings me to my next point.

Should you be using a third-party library? While they offer a lot of convenience, there are some concerns about using them in enterprise applications, especially for access control and especially in applications that deal with sensitive data. Because the documents could be unclear, outdated or inaccurate. But most importantly, there may be vulnerabilities in the library itself. To have complete control over your security logic, you may want to build your own solution.

5. Policy Implementation and Business Logic Handling

Short description:

Define policies for UI and server compatibility. Utilize policy as code with JSON or YAML. Group policies by resource for efficient management. Use CEL for fast, secure conditions evaluation. Manage user details and policies for accurate evaluation alongside dynamic business logic.

How do we write the policies such that it can be used by both the UI and the server? Or that can be used by multiple UIs and multiple servers? To solve this issue when the backend tech stack is not JavaScript-based, policy as code is utilized. This approach involves using code or configuration files like JSON or YAML to define and manage policies. By structuring policies in YAML with conditions for evaluation, you can ensure effective policy management.

Improving the structure of policies involves grouping them by resource and action for better navigation and scalability. The use of Google's common expression language for writing conditions ensures fast and secure policy evaluation. Evaluating conditions is done using CEL evaluators, such as the cell javascript evaluator for front-end applications, to produce Boolean results based on user, resource, and environment data. Storing user details in the global state and fetching policies from a management service are essential for policy evaluation.

Handling contextual business logic alongside permissions is crucial for accurate access control. Dynamic business logic, dependent on the application state, can further restrict actions despite having required permissions. Examples include preventing post approval during editing, disabling actions based on content presence, and enforcing unique constraints like post category names. Balancing dynamic business rules with permission-based access is vital for robust access control implementation.

6. Access Control Evaluation and Dynamic Handling

Short description:

Evaluate conditions with CEL evaluators. Use cell JS evaluator for front-end. Store user details for evaluation and fetch policies conditionally. Contextual business logic restricts actions dynamically. Encapsulate validation logic for use in multiple components.

And even with growing policies, the lookup time is going to remain constant. Now that we have the policies in place, evaluation of conditions is crucial. CEL evaluators are available for different languages, with the cell javascript evaluator used for the front-end. The validator resides in the web app and receives resource and environment attributes from the invoking component.

User details like role and department are stored in the global state for evaluation. Policies are fetched from a management service conditionally using Redux Toolkit or Tanstack Query. Contextual business logic often restricts actions despite having necessary permissions, depending on dynamic application states. Examples include preventing post approval during editing or disabling actions based on content presence.

Contextual business rules are vital for accurate access control alongside permissions. Encapsulating validation logic in a use permission hook allows its use in various components. Changing application states trigger re-computation of validation outputs and re-rendering of components using the hook. Fetching policies conditionally after a valid user ID is present and validating contextual actions are key parts of this process.

7. Dynamic Business Logic Handling

Short description:

Avoid unnecessary network requests. Cache policies automatically. Handle dynamic business logic. Encapsulate validation logic for reusability. Use selector hook selectively.

You know, so as to avoid unnecessary network requests. And if you're using RTK or Tanstack Query for this, the policies are going to be automatically cached in the store. We will be reading from the store for the purposes of this example, but please be very mindful of storing sensitive user and policy data in the store.

More often than not, even if you have the required permission to perform an action, you may still not be allowed to do so because of contextual business logic. And this business logic may depend on the state of the application and may need to be handled dynamically. Examples would be to prevent the approval of a post if it's currently being edited, to disable the comment button if there's no content typed in the comment box, and to prevent the creation of a post category if the name already exists.

So if a contextual action rule is present, it's going to be evaluated alongside the contextual policy validator. Encapsulate all of this validation logic inside a use permission hook so that it can be used by any component that needs to check for permissions. With changing application state and changing attributes, the hook would recompute the validation output and trigger a re-render in all the components that use it. At a high level, this is what simplified code for that looks like. This is where I'm fetching the policies conditionally after a valid user ID is present. And then here is the validation logic for cell JSC evaluation and contextual action validation. But there is one thing in this code that needs to be rewritten. You see how here I'm using the use selector hook to subscribe to the entire application state. Which means that any state change is going to trigger a re-render in all the components that use the use permission hook. Which is why that's a bad practice and you're supposed to be using your use selector hook to subscribe to only what's necessary. Make it as granular as possible.

8. Enforcement of Access Control Policies

Short description:

Enforce permissions with CASL-inspired components. Implement protected routes based on user permissions. Summary: scalable solutions for dynamic attribute-based access control.

Which is why that's a bad practice and you're supposed to be using your use selector hook to subscribe to only what's necessary. Make it as granular as possible.

Okay. Moving on to the last bit, we looked into the definition of permissions using the custom solution. Now let's look into how to enforce these permissions. You can create a can wrapper component inspired by CASL to hide or show a component in this case. To disable a component and then to create a protected route. If the user has permissions, you would show the outlet. If not, navigate to the login page. And finally, to skip an API call if the user doesn't have any permissions.

That was all for today. That wraps up our session. But before I let you go, let's summarize. We learned two ways to enforce fine-grained attribute-based access control. First one using CASL and second one using a custom solution. Both the solutions are scalable in the sense that adding a new policy means updating a single file without any code rewrites. They are dynamic because they work seamlessly with changing application state. They're readable like, can I read a post? Can I delete a post? And finally, they are clean because there's separation of concerns. Hopefully you remember everything from this session. But because it was a lot and if you had to remember just one thing, it would be to consider using OWASP recommended attribute-based access control because it's more effective in implementing the principle of least privilege.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
The talk discusses the importance of supply chain security in the open source ecosystem, highlighting the risks of relying on open source code without proper code review. It explores the trend of supply chain attacks and the need for a new approach to detect and block malicious dependencies. The talk also introduces Socket, a tool that assesses the security of packages and provides automation and analysis to protect against malware and supply chain attacks. It emphasizes the need to prioritize security in software development and offers insights into potential solutions such as realms and Deno's command line flags.
The State of Passwordless Auth on the Web
JSNation 2023JSNation 2023
30 min
The State of Passwordless Auth on the Web
Passwords are terrible and easily hacked, with most people not using password managers. The credential management API and autocomplete attribute can improve user experience and security. Two-factor authentication enhances security but regresses user experience. Passkeys offer a seamless and secure login experience, but browser support may be limited. Recommendations include detecting Passkey support and offering fallbacks to passwords and two-factor authentication.
5 Ways You Could Have Hacked Node.js
JSNation 2023JSNation 2023
22 min
5 Ways You Could Have Hacked Node.js
Top Content
The Node.js security team is responsible for addressing vulnerabilities and receives reports through HackerOne. The Talk discusses various hacking techniques, including DLL injections and DNS rebinding attacks. It also highlights Node.js security vulnerabilities such as HTTP request smuggling and certification validation. The importance of using HTTP proxy tunneling and the experimental permission model in Node.js 20 is emphasized. NearForm, a company specializing in Node.js, offers services for scaling and improving security.
Content Security Policy with Next.js: Leveling Up your Website's Security
React Summit US 2023React Summit US 2023
9 min
Content Security Policy with Next.js: Leveling Up your Website's Security
Top Content
Watch video: Content Security Policy with Next.js: Leveling Up your Website's Security
Lucas Estevão, a Principal UI Engineer and Technical Manager at Avenue Code, discusses how to implement Content Security Policy (CSP) with Next.js to enhance website security. He explains that CSP is a security layer that protects against cross-site scripting and data injection attacks by restricting browser functionality. The talk covers adding CSP to an XJS application using meta tags or headers, and demonstrates the use of the 'nonce' attribute for allowing inline scripts securely. Estevão also highlights the importance of using content security reports to identify and improve application security.
How React Applications Get Hacked in the Real-World
React Summit 2022React Summit 2022
7 min
How React Applications Get Hacked in the Real-World
Top Content
How to hack a RealWorld live React application in seven minutes. Tips, best practices, and pitfalls when writing React code. XSS and cross-site scripting in React. React's secure by default, but not always. The first thing to discover: adding a link to a React application. React code vulnerability: cross-site scripting with Twitter link. React doesn't sanitize or output H ref attributes. Fix attempts: detect JavaScript, use dummy hashtag, transition to lowercase. Control corrector exploit. Best practices: avoid denialist approach, sanitize user inputs. React's lack of sanitization and output encoding for user inputs. Exploring XSS vulnerabilities and the need to pretty print JSON. The React JSON pretty package and its potential XSS risks. The importance of context encoding and secure coding practices.
Let Me Show You How React Applications Get Hacked in the Real-World
React Advanced 2021React Advanced 2021
22 min
Let Me Show You How React Applications Get Hacked in the Real-World
Top Content
React's default security against XSS vulnerabilities, exploring and fixing XSS vulnerabilities in React, exploring control characters and security issues, exploring an alternative solution for JSON parsing, and exploring JSON input and third-party dependencies.

Workshops on related topic

Hands-On Workshop: Introduction to Pentesting for Web Apps / Web APIs
JSNation US 2024JSNation US 2024
148 min
Hands-On Workshop: Introduction to Pentesting for Web Apps / Web APIs
Featured Workshop
Gregor Biswanger
Gregor Biswanger
In this hands-on workshop, you will be equipped with the tools to effectively test the security of web applications. This course is designed for beginners as well as those already familiar with web application security testing who wish to expand their knowledge. In a world where websites play an increasingly central role, ensuring the security of these technologies is crucial. Understanding the attacker's perspective and knowing the appropriate defense mechanisms have become essential skills for IT professionals.This workshop, led by the renowned trainer Gregor Biswanger, will guide you through the use of industry-standard pentesting tools such as Burp Suite, OWASP ZAP, and the professional pentesting framework Metasploit. You will learn how to identify and exploit common vulnerabilities in web applications. Through practical exercises and challenges, you will be able to put your theoretical knowledge into practice and expand it. In this course, you will acquire the fundamental skills necessary to protect your websites from attacks and enhance the security of your systems.
0 to Auth in an hour with ReactJS
React Summit 2023React Summit 2023
56 min
0 to Auth in an hour with ReactJS
WorkshopFree
Kevin Gao
Kevin Gao
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool. There are multiple alternatives that are much better than passwords to identify and authenticate your users - including SSO, SAML, OAuth, Magic Links, One-Time Passwords, and Authenticator Apps.
While addressing security aspects and avoiding common pitfalls, we will enhance a full-stack JS application (Node.js backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session securely for subsequent client requests, validating / refreshing sessions- Basic Authorization - extracting and validating claims from the session token JWT and handling authorization in backend flows
At the end of the workshop, we will also touch other approaches of authentication implementation with Descope - using frontend or backend SDKs.
OWASP Top Ten Security Vulnerabilities in Node.js
JSNation 2024JSNation 2024
97 min
OWASP Top Ten Security Vulnerabilities in Node.js
Workshop
Marco Ippolito
Marco Ippolito
In this workshop, we'll cover the top 10 most common vulnerabilities and critical security risks identified by OWASP, which is a trusted authority in Web Application Security.During the workshop, you will learn how to prevent these vulnerabilities and develop the ability to recognize them in web applications.The workshop includes 10 code challenges that represent each of the OWASP's most common vulnerabilities. There will be given hints to help solve the vulnerabilities and pass the tests.The trainer will also provide detailed explanations, slides, and real-life examples in Node.js to help understand the problems better. Additionally, you'll gain insights from a Node.js Maintainer who will share how they manage security within a large project.It's suitable for Node.js Developers of all skill levels, from beginners to experts, it requires a general knowledge of web application and JavaScript.
Table of contents:- Broken Access Control- Cryptographic Failures- Injection- Insecure Design- Security Misconfiguration- Vulnerable and Outdated Components- Identification and Authentication Failures- Software and Data Integrity Failures- Security Logging and Monitoring Failures- Server-Side Request Forgery
How to Build Front-End Access Control with NFTs
JSNation 2024JSNation 2024
88 min
How to Build Front-End Access Control with NFTs
WorkshopFree
Solange Gueiros
Solange Gueiros
Understand the fundamentals of NFT technology and its application in bolstering web security. Through practical demonstrations and hands-on exercises, attendees will learn how to seamlessly integrate NFT-based access control mechanisms into their front-end development projects.
Finding, Hacking and fixing your NodeJS Vulnerabilities with Snyk
JSNation 2022JSNation 2022
99 min
Finding, Hacking and fixing your NodeJS Vulnerabilities with Snyk
Workshop
Matthew Salmon
Matthew Salmon
npm and security, how much do you know about your dependencies?Hack-along, live hacking of a vulnerable Node app https://github.com/snyk-labs/nodejs-goof, Vulnerabilities from both Open source and written code. Encouraged to download the application and hack along with us.Fixing the issues and an introduction to Snyk with a demo.Open questions.
Bring Code Quality and Security to your CI/CD pipeline
DevOps.js Conf 2022DevOps.js Conf 2022
76 min
Bring Code Quality and Security to your CI/CD pipeline
Workshop
Elena Vilchik
Elena Vilchik
In this workshop we will go through all the aspects and stages when integrating your project into Code Quality and Security Ecosystem. We will take a simple web-application as a starting point and create a CI pipeline triggering code quality monitoring for it. We will do a full development cycle starting from coding in the IDE and opening a Pull Request and I will show you how you can control the quality at those stages. At the end of the workshop you will be ready to enable such integration for your own projects.