Using Open Policy Agent for Cloud-Native App Authorization
How companies like Netflix, Pinterest, Yelp, Chef, and Atlassian use OPA for ‘who-and what-can-do-what’ application policy.
In the cloud-native space, microservice architectures and containers are reshaping the way that enterprises build and deploy applications. They function, in a word, differently than traditional monolithic applications.
Microservices are far more distributed and dynamic than their traditional counterparts. A single application might have tens or hundreds of microservices, leading potentially to thousands of separate OS-level processes, each with its own API, deployed across multiple data centers all over the world, and spun up and down dynamically. These architectural differences from monolithic applications cause challenges for developers, operations, and security alike.
Among the biggest security challenges is authorization: controlling what users and machines can and can’t do within the application. In the pre-cloud era, authorization was solved at the gateway level—at the point at which end-users interacted with the application’s API—and often the downstream requests were assumed to be authorized.
For a microservice application running in the cloud, gateway-level authorization is far less secure. If an attacker compromises a single microservice component, they can run the APIs of all the microservices that make up that application, which gives them complete control over it and all of the data it protects. So while internal APIs and microservice architecture enable better time-to-market for the application, they also pose a substantial security risk and need to be protected by deploying authentication and authorization, just like for public APIs.
Changing development strategy
Not only are the architectural changes brought about by microservices substantial, but the way people develop microservice-based applications is changing radically too. Traditionally, companies had a few highly coordinated development teams who built the application in tandem, and who released software only after intense scrutiny. Today, numerous dev teams work independently on discrete, individual application components, and they release code whenever they see fit. No team is responsible for “the whole app.” The benefit of having numerous teams is that they can all work independently, and therefore deliver software more efficiently overall.
However, having numerous teams also means that every team needs to maintain and enforce authorization policies for each of the services they are responsible for. The real challenge is that security, compliance and operational teams also need to understand these authorization policies; they’re responsible for them. And if you ask 10 teams to implement authorization for their service, you’ll end up with 10 different hardcoded implementations in different programming languages, with different enforcement guarantees and different ways of logging unauthorized access attempts.
All of this wreaks havoc on the outside teams that need to modify, or even just review, these authorization policies and understand how they are being enforced.
Unifying authorization for the application
A growing number of organizations (e.g. Netflix, Pinterest, Yelp, Chef, Atlassian) are implementing authorization by providing a unified authorization framework for all development teams. That framework provides a single language or GUI for writing policy, a single way of distributing those policies to the services that need them, a single architecture for enforcing those policies, and a single system for logging decisions.
A unified framework for authorization often means faster time-to-market, since developers have less code to write. More importantly, a unified framework guarantees that policies are decoupled from the software systems they govern. There are numerous benefits to this fact: Security and compliance teams can review the policies separately from their implementation; policies enforced in multiple places only need to be written once; policies are enforced consistently across services; decisions are logged consistently, enabling easier SIEM analysis; and policies can be updated dynamically to respond to security events.
In the end, because authorization is a topic under the purview of security, operations, compliance, and developers, a unified framework provides a natural point at which all of those different teams can collaborate.
Using OPA for application authorization
For many developers, operations, security, and compliance teams, Open Policy Agent (OPA) has become a primary tool for implementing consistent, secure and scalable authorization across an organization and across the cloud-native ecosystem. OPA is a domain-agnostic, general-purpose policy engine —a building block for creating and implementing consistent and flexible policies. Developers can plug OPA into different layers of the stack for numerous rules-based use cases, from safeguarding Kubernetes, to managing policy consistently across CICD pipelines and public clouds, to implementing in-app authorization.
For this latter use case (today’s topic), OPA is growing quickly in popularity, because it lets companies write policies that are understandable across many different dev teams and translatable across each of a company’s applications and their components. While there are numerous aspects of authorization where OPA applies, here we will focus on three of the most popular: service-level authorization, end user authorization and policy-suite authorization.
OPA for service-level authorization
One popular OPA use case is service-level authorization, or the “what-can-do-what” policies that determine what applications and their components can do and how they talk to each other — if microservice A can talk to microservice B, for instance. When you have dozens or hundreds of microservices components, it’s essential that you have clear, consistent and scalable rules about which services can call which APIs. From a security perspective, it’s also critical to have policies that limit the ability of attackers to laterally traverse those APIs.
In fact, this was an early OPA use case for Netflix, which provides a textbook example. From an operational perspective, security engineers at Netflix needed to ensure that developers could tightly control which applications and services, from the vast back-end Netflix ecosystem, could call the REST API endpoint on their own service. Without such rules, Netflix services might not scale correctly to maintain high availability, as traffic pathways could become heavily congested.
Because speed was a critical requirement of the overall system, service-level authorization decisions needed to happen at a sub-millisecond timescale. Netflix also needed to ensure that a potential attacker couldn’t compromise one service and traverse to others, and they needed a way to hot patch every authorization policy across microservices to stop an attack in its tracks.
Because OPA provides a consistent policy framework and decouples authorization decisions from the app itself, it provided Netflix with a way to not only let dev teams control service-level authorization for their own apps, but also to update and federate policies across their environment in real time.
OPA for end-user authorization
Another way that app developers use OPA is for end-user authorization. These policies make sure that users (living, breathing human beings) have the right levels of access in the application and can take only certain actions depending on the user’s permissions and dynamic context. For some applications the end-user is a customer, and for others the end-user is an employee. Sometimes the policies are extensions of the service-level authorization policies described earlier, but allow developers or operators to run microservice APIs if they are on-call. This style of policy makes decisions based on the user’s identity, the corporate groups the user is a member of, and possibly other information loaded dynamically into OPA.
Other times OPA is used to implement authorization for the application itself. For example, in a banking application, the policy might stop someone from withdrawing $100 from an account they don’t own. In this case, OPA is a building block for developers who must either build this functionality themselves or use a policy that already exists.
Using OPA lets developers future-proof their authorization implementation. While in the early days, authorization requirements were often limited, they usually changed over time. OPA’s flexibility ensures you can start with a simple (say role-based) model and grow to a more sophisticated (say attribute-based) model as the requirements evolve.
OPA for product-suite authorization
A third popular way to use OPA is to unify authorization across a suite of different products, sometimes known as entitlements services in sectors like banking. Enterprises often have numerous products deployed across the organization, and they need a unified way of implementing authorization across this product suite. Typically, this need comes from one of two places. Either the company is moving their legacy products into the cloud and the on-premises authorization system can’t come with, or the organization wants to improve the user experience across the product suite.
In the latter case, when different products owned by the same organization have different ways of performing authentication and authorization, the user experience can be poor, because it gives the impression that many companies are delivering these products, or that the organization lacks cohesion and organization. In both of these cases, OPA provides companies with a unified way to implement authorization or entitlements across all of their cloud-native products.
Regardless of how or where enterprises are building applications in cloud-native environments, there are numerous authorization problems they must overcome—from end-user authorization, to managing microservices APIs, to deploying consistent authorization policies across the organization. OPA, as an open-source tool, is emerging as a clear standard for helping organizations solve these problems — helping to reduce complexity and development time while increasing the scalability and security of development.
Learn how to operationalize OPA at scale.
This article first appeared in Infoworld on November 4, 2020.