Conf42 DevSecOps 2024 - Online

- premiere 5PM GMT

A Policy-as-Code Approach to RBAC Authorization

Video size:

Abstract

The cloud-native landscape brings advantages but also new security challenges. Manual policy management risks breaches. Policy-as-Code uses code to define and manage policies, preventing violations. Learn to implement PaC with Rönd and Open Policy Agent to secure your APIs with RBAC authorization.

Summary

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Hello everyone and welcome to my session. Today we will talk about Polisys code and how to use this approach to build RBAC and OpenPolicyAgent. Let me introduce myself. My name is Graziano Casto and I'm a Developer Relations Engineer at MIA Platform, an Italian company that, among other things, is the creator of the tool we will be discussing today. Feel free to check out my website and follow me on LinkedIn. Before diving in, let's start with the basics and understand what we mean by policies. When we think about policies, we often immediately associate them with roles and users. And this is correct. A rule that governs a specific role access to a particular resource is in fact a policy. However, even an instruction that defines the behavior of a system based on the value of a certain property can also be considered a policy. And applying this to real life, even rules like the age limit for purchasing alcohol can, in a way, be considered a policy. In general, a policy is simple. simply a set of rules that govern the behavior of a system by describing the invariance that must hold will in it. Policies are not necessarily limited to the world of authorization. Authorization policies are just a subset of a broader category and they specify which users or machine of course are allowed to perform certain actions or on specific resource within a system. The first thing we need to think about when considering API authorization is which strategy to use. There are different strategies to define the access control on our system. Let's take a look at a couple of them. Let's take the example of an internal developer platform. In this context, we may have senior developers who are allowed to access project configurations, commit changes and deploy them. Then we have a group of junior developers who are allowed to access the project configurations and commit changes, but not deploy them. And finally, we have the platform administrator with full permissions. They can do everything senior developers can do, but in addition, they can also create new projects. In this situation, even if we used a simple example, scaling by directly assigning each user the specific set of actions they are allowed to do becomes really complex. One way to simplify this process is by categorizing users into roles. This way, we only We will only assign the user to a role and the permission will be inherited directly from the role. This means that whenever we need to add a new user to the platform, for example, we just need to identify its role. And if we need to add the new features that require new permissions, the only thing we need is to assign this permission to the roles that require it. In this way, all the users associated with that role will inherit the permission. This strategy is known as Role Based Access Control, RBAC, and it is useful for abstracting out the complexity of assigning permission to users by using an intermediate level of assignment. Another popular strategy is called Attribute Based Access Control, ABAC, which focuses on the use of attributes instead of roles. In this access management strategy, each user is directly assigned to attributes, which are used to determine whether the specific user's methods certain conditions for accessing a resource or performing an action. Both strategies have their pros and cons. On one hand, the airbag strategy is certainly simple, but compared to an ABAC approach, it lacks of granularity. On the other hand, using attributes allow for more granular definition of access points. specific access, but implementing such a strategies requires more time and expertise to define correctly the attributes you need. The ideal solution could be to use a hybrid approach, using roles for a high level access control and then using attributes for more granular management of access to specific access. Let's look at some example of this hybrid strategy. Suppose our users have roles and corresponding permissions as described in the previous example. And we have also assigned them attributes like the environments, which describe the environments they are allowed to work on, and the project, which is the list of projects they work on. In this case, a senior developer having the permission to deploy as part of their role will be able to deploy to any environment for the project they are assigned to. On the other hand, the same senior developer will not be able to deploy anything to projects they are not assigned to. In other words, even If they inherit the deploy permission from their role, if they don't have the project attribute associated, they will not be able to deploy any changes to that project. Now let's analyze the case of a junior developer. They don't have the permission to deploy, so it doesn't matter which projects they are assigned to. They will not be able to deploy any changes to those projects. In this case, if we want to give a specific junior developer the ability to deploy changes, but only to the dev environment, for example, for the project they are assigned to, a poorly error back approach wouldn't allow us to do that. However, with this hybrid approach, we can assign the environment attribute to the user. Even if the junior developer doesn't have the deploy permission in their role, by assigning them the development environment attribute, we can make an exception that allows them to deploy only the development environment for the projects they are assigned to. This provides a more flexible and granular way to manage access to specific, specific assets like the environment and the projects now that we know the strategies available to us and all that's left to figure out how to implement them. The old approach of keeping everything inside the code base works well and that's why it is always being used. This approach involves having the code responsible for enforcing the authorization policy co exist within the same code base and the same code base as the business logic. Handling authorization this way has its pros and cons. On one hand, it's convenient because it is the simplest and quickest solution to start with. Start developing our system. On the other end, it exposes to several problems such as the repetition, for example, if the same policies need to be used in other services, especially in a distributed application, it has to be repeated and this lead to difficult code maintainability in the larger scale application. A better way to manage our policies is to decouple them from the code base that contain the business logic of our services. The way to do this is by adopting a policies code approach. this is involved, this involves, extracting the policies definition code into a separate repository from our application code and using an agent that sits between our APIs and the users to handle the enforcement of these policies. The tool that allow us to do this is Open Policy Agent, OPA, an open source tool graduated by the Cloud Native Computing Foundation, the CNCF, and it provides an high level language called RIGO for defining policies and an agent for the enforcement. What you are seeing on the screen right now is a snippet of a simple regopolicy that only authorizes post requests on the slash order route, where the value of the store property inside the body matches the store assigned to the user making the request. Returning to the previous example and implementing it to using Rigo for policies definition, what we would have is that all the code in our code base responsible for enforcing policies is managed through Rigo code, outside our code base, okay? This way the policy enforcement logic is decoupled from the business logic of our services and managed independently, making the system easier to maintain and more flexible. By analyzing the Rego policy code, we have these two allows blocks, which are the actual entry point for the authorization logic. With each request, if one of these two blocks returns true, then the request is authorized. These blocks use functions defined above to evaluate, for example, the role of the user making the request. To retrieve the user's role, the JWT token is decoded. Which is retrieved from the editor of the request itself. This approach does indeed add a first level of decoupling of decoupling, of the policies from our code base, of our code base. However, the problem is that hope can be deployed as arrest service, which means that our application with. We still need to communicate with the services, with the service, and therefore a minimal level of coupling remains in our application doing so. So we want more, we want to do better, to do it better. And to further the couple, the policy from our code base, what we can do is using R Round is an open source project, is a lightweight side car container for API protection that used OPA and Rigo for authorization policy validation. natively allows building airbag solutions by defining the concept like roles, permissions, user groups as binding blocks inside the project. For its configuration, ROND uses open policy, open API compliant files. Therefore, to add RON to our project, all we need to do is modify these files to add the XRON property to the routes that we want to protect. Inside this property, we will declare the name of the regopolicies that we intend to use to protect the specific route. We just need to do In addition to protecting routes with authentication rules, ROND offers two other powerful features. The first one is query generation, which allows us to filter the results. response of our APIs before returning it to the client. In this case, we can define a policy that will be executed before returning the result to the client, allowing us to filter the response dataset we will return to the client itself. The second feature is the ability to define a policy that modify the structure, the response schema before returning it to the client. In this case, let's suppose, I don't know, we have the response payload for our request to fetch the customers of our application. Using the same endpoint, for example, the get slash users, we can use run to ensure that, Power users, so the user with more privileges, can access the full payload, while users with fewer privileges receive just a filtered payload, without, for example, sensitive information. Now, we get to the point. Let's start, let's talk about why ROND was created and how it is used at large scales. At MIA Platform, we created ROND to manage the entire authorization flow of our EDP. And it is also provided as an authorization mechanism for the workloads managed by our platform. From our clients. For the ADP alone, ROND is currently running on more than 30 microservices, managing over 5, 000 policies across more than 300, 300 routes. ROND is a project designed to be integrated into existing distributed application without the need to modify the existing services thanks to the use of the sidecar pattern and the open ABI specification compliant configurations. This design make it easy to integrate into existing system by design. ROND also exposes various metrics to track the usage of policies, such as the number of time each policy is used and the average evaluation time from them. additionally it provides metrics to monitor the resource usage of the sidecar container, including resource utilization at the container level. We have reached the end of the presentation and thank you for following me this far and I invite you to connect with me on LinkedIn and start using Roam. Thank you all and see you next time.
...

Graziano Casto

Developer Relations Engineer @ Mia-Platform

Graziano Casto's LinkedIn account



Join the community!

Learn for free, join the best tech learning community for a price of a pumpkin latte.

Annual
Monthly
Newsletter
$ 0 /mo

Event notifications, weekly newsletter

Delayed access to all content

Immediate access to Keynotes & Panels

Community
$ 8.34 /mo

Immediate access to all content

Courses, quizes & certificates

Community chats

Join the community (7 day free trial)