- Best Practices
5 steps to building NSA-level access control for your app
Access Control is a main concern when developing web applications - and the NSA has a lot to say about it, especially the biggest pitfall developers make.
Access Control has become a main concern when it comes to developing secure web applications, and the NSA has a lot to say about it. Especially when it comes to the biggest access management pitfall developers make.
In 2021 OWASP listed ‘Broken Access Control’ as their A01 item on the list of Top 10 Web Application Security Risks. The 2020 Verizon Data Breach Investigations Report states that “At least two-thirds of cyberattacks are now focused on impersonating trusted users and systems to access vital data or critical systems.”
To help address these concerns, the United States National Security Agency (NSA) has issued a cybersecurity information sheet (CSI) titled “Advancing Zero Trust Maturity Throughout the User Pillar”.
The goal of the CSI is to provide recommendations for strengthening Identity, Credential, and Access Management (ICAM) capabilities to mitigate such cyberattacks effectively. It further discusses how these capabilities can be integrated into a comprehensive Zero Trust framework.
These battle-tested best practices are a goldmine of knowledge for every developer.
Developing secure systems is a challenge for every developer, especially for those dealing with matters of national security. These developers handle the most sophisticated cyber threats on a daily basis. To truly excel as developers, we must learn from them, and strive to enhance our knowledge and skills. Only then can we ensure that the systems we build are robust, resilient, and reliable.
In this blog, we will focus and elaborate on the best practices offered by the NSA for building secure access management, and how they can be implemented at the application level. To boil it down, these are the five most important steps:
Adopt a Zero-Trust mindset and design
The User Pillar focus
Event Driven ABAC
Accessible Access Control
Introduction: Zero-Trust, the User Pillar, and Access Management
Let’s start with some context - The CSI provides recommendations for strengthening the identity, credential, and access management capabilities of your organization, and how these can be integrated into a Zero Trust network. The CSI explains Zero Trust architecture as being made up of seven pillars, one of them being the User Pillar. We're not going to dive into the depth of each of those concepts, but we’ll do a quick overview of them.
What is Zero Trust?
The Zero Trust security model is an approach to cybersecurity that requires strict identity verification for every person and device trying to access a network, application, or data. The model assumes that all users, devices, and networks are potential security risks and, therefore, limits access to only the necessary resources and data for each user.
The NSA encourages the implementation of a Zero-Trust model to reduce the risk of data breaches, insider threats, and cyber attacks by limiting access to sensitive information and resources to only users who have the proper authentication and authorization, and constantly monitoring and verifying their identities and behavior.
Some common techniques used in zero-trust security models include multi-factor authentication, granular access controls, network segmentation, and continuous monitoring of user activity.
In a zero-trust model, access control decisions are based on a number of factors, including the user's identity, the device being used, the user's location, and the sensitivity of the data or resource being accessed. These factors are evaluated in real-time, and access is only granted if all of the criteria are met. We will dive deeper into this in a moment.
The Seven Pillars of Zero Trust
The implementation of a zero-trust model requires integrating every system with the controls defined for each of the Seven Pillars of Zero Trust:
User: Continuously authenticate and authorize resource access.
Device: Be aware of device health and status, and maintain real-time inspection, assessment, and patching.
Data: Data transparency and visibility are enabled and secured by enterprise infrastructure, applications, standards, robust end-to-end encryption, and data tagging.
Application/Workload: Secure everything from applications to hypervisors, including containers and virtual machines.
Network/Environment: Segment, isolate, and control (physically and logically) the network environment with granular policy and access controls.
Visibility & Analytics: Analyze events, activities, and behaviors to achieve a model that improves detection and reaction time when making access decisions.
Automation & Orchestration - Automate security responses based on defined processes and security policies.
The CSI goes on to elaborate on each of the seven pillars of zero trust. In this blog, we will focus on the User Pillar, which deals with managing user access in a dynamic risk environment.
Adopting a Zero Trust mindset
Zero Trust isn’t a patch you can simply apply to an existing solution - it's a security-by-design principle. In Permit, for instance, we had to achieve a zero trust model to provide our SaaS authorization solution.
We designed our architecture to be split into two parts - the control plane and the data plane. The control plane through which our clients manage their authorization is hosted in our cloud solution, yet our client’s data is never exposed to us and remains hosted on their side.
This way, our clients can fully utilize our SaaS service without exposing any data, security, or performance factors to it.
The User Pillar
The user pillar is an expansion of the FICAM framework, which consists of several parts:
Identity Management: Creation, maintenance, and verification of digital identities.
Credential management: Issuing, revoking, and managing digital credentials that verify an individual's identity, such as smart cards, tokens, and digital certificates.
Access Management: Authorizing and controlling access to resources based on a user's identity and permissions, enforcing policies and controls to manage access to those resources.
Federation: Sharing identity and access information between different organizations or systems to enable cross-organizational collaboration and resource sharing.
Governance: Establishing policies, procedures, and controls to ensure compliance with laws, regulations, and industry standards.
You can learn more about the seven pillars of zero trust and their aspects in the full CSI available here. In this blog, we’ll focus on Access Management.
Access Management is all about making sure that only the right people (authenticated users or entities) can perform the right actions on the right resources.
Access control frameworks provide access decisions at various levels of granularity, with more advanced systems being able to support a higher level of granularity.
The Biggest Access Management Pitfall
There are many ways of implementing these access controls. Many implementations use single sign-on (SSO) solutions that validate a user’s credentials, assign them with specific properties (Like roles), and then manage access based on the privileges of those properties.
These solutions tend to use broad, static, role-based access (RBAC) rules governing access to all resources on a system. But that’s not enough.
Access control mechanisms should consider granularity, reliability, availability, and potential risks to the resource. A solution based on authentication and simple RBAC (or even worse - an Admin / Non-Admin system) lacks crucial flexibility and granularity to properly handle not only sensitive data but also the requirements of almost any modern application.
In the context of the NSA, granting access to resources based on roles given to users (even if they are authenticated) is out of the question. Attributes such as classification, clearance, geolocation, time of access, and many others are crucial for their systems to remain secure. The need for attributes is not limited to highly sensitive government organizations:
Consider this access policy example -
Only authenticated users who have an active paid subscription and are located in the EU can access a specific part of your application.
That’s a type of policy you probably encounter every day in almost every modern app. Not only it requires multiple attributes for both the users and resources, but also the ability to be updated instantaneously in real-time.
The solution? Battle-tested Best Practices
The NSA CSI offers a few best practices when it comes to creating a granular, reliable, and flexible access control layer. The best practices emphasize, first and foremost, the use of an Attribute-based access control (ABAC) model, which provides the required flexibility to meet our access management goals.
- Implement an ABAC-based model
ABAC is an authorization model that determines access based on conditional attributes. This model allows for highly granular policy creation, with the ability to factor in a great number of variables for deciding on a user’s range of access. According to the CSI, it is one of the most basic prerequisites to building secure access management.
- Where to start? Map your application's access control
One of the first and most basic steps in enhancing your access control is mapping out your application’s requirements to determine what user and resource attributes it requires. A “Comprehensive inventory and characterization of users, resources, and the users’ ability to protect the data” is the first step required to know how exactly your application’s access control should be designed.
- Should I move to ABAC completely?
Implementing ABAC doesn’t mean we have to shift from using RBAC completely - RBAC and ABAC can be used together hierarchically, with broad access enforced by RBAC protocols and more complex access managed by ABAC.
- Build a flexible system
Implementing and maintaining authorization can in itself be quite challenging. Creating a structure that allows you to switch from one model to another or use them together is even more complicated. The best solution is to use an authorization solution that allows for this flexibility.
- Create a separate microservice for authorization
It is highly recommended to create a “centralized management interface for assigning fine-grained privileges”. Each service in your application will have to be configured with its own set of policies manually. This can be quite a time-consuming, and, more importantly - unsafe process. As the number of policies, users, and services grows, updating the policies in each relevant service will become tedious, time-consuming, and a huge source of potential error. On the same topic -
- Don’t mix application code with authorization logic
Mixing the code of the authorization layer into the application code is a bad idea for several reasons. Each upgrade or added capability would require us to refactor large areas of code that only drift further from one another.
A solution that allows you to both create a separate microservice for authorization and decouple policy and code is Open Policy Agent (OPA), which you can use to manage authorization in a separate service.
- Utilize event-driven authorization
In addition to granular access rules, keeping your authorization layer up to date in real-time is a must for every modern application. OPAL (Open Policy Administration Layer), for example, is an open-source project that makes OPA event-driven. This allows you to respond to policy and data changes instantly as they happen, push live updates to your agents, and bring open policy up to the speed needed by live applications.
Don't stop there - Make access control accessible
“Attribute-based models require an authoritative source for attributes and processes for users to be provisioned with attributes”. While tools like OPA and OPAL allow us to unify all policies in one server, take on the role of policy decision-making and enforcement from the service, and manage policy as code, they lack one major capability:
Creating, managing, and enforcing ABAC policies in a way anyone in your organization can use.
Normally, creating and managing your application’s authorization layer only be done through complex R&D work and steep learning curves. This creates a situation where developers become bottlenecks in your app’s permission management, while other stakeholders are locked out of the conversation, and your customers are left without the flexibility they require. This results in an unending flow of feature requests.
The answer is to provide human-oriented low-code interfaces that all relevant stakeholders, including end users, can use. This empowers developers to delegate some of the work without them becoming bottlenecks.
At Permit.io, we took on the accessibility challenge head-on, while being adamant about keeping the full power of policy-as-code.
Permit’s policy editor implements and manages your RBAC and ABAC policies with a simple no-code UI which makes permission management accessible to other stakeholders.
Permit provides developers with a permission management solution that makes policy-as-code as easy as checking a checkbox - generating the needed code for you, and wrapping it nicely into Git, and API / UI interfaces.
Never stop learning
“Adoption of ZT principles is not accomplished overnight. Implementation is achieved through careful and deliberate planning and continuous incremental improvements”.
Want to learn more about Authorization and access control? Join Permit’s Slack Community, where world-class authorization specialists and hundreds of devs are discussing, building, and implementing authorization together.