CoreValue Technologies – Tech Solution Partner

Open Policy Agent (OPA) for Policy Authorization

1st Jan 2025

Introduction

In the world of microservices and cloud-native applications, managing authorization policies can quickly become complex. Open Policy Agent (OPA) is a general-purpose policy engine that provides a unified way to define and enforce fine-grained policies across your entire stack. This blog will walk you through using OPA for policy-based authorization, integrating it with your backend, and defining policies using the Rego language.

OPA decouples policy decision-making from application logic, enabling flexibility and centralization of policy enforcement. Let’s dive into how OPA can be used for role-based access control (RBAC) in a microservice architecture.

What is OPA?

OPA is an open-source, declarative policy engine that allows you to define policies in a high-level, declarative language called Rego. These policies are evaluated against incoming requests, and based on the outcome, OPA will return an "allow" or "deny" decision. This decouples the policy logic from the application, making your codebase cleaner and more manageable.

OPA is well-suited for enforcing policies in different layers of your system, including API authorization, Kubernetes admission control, and more.


Setting Up OPA for Policy Authorization

For this tutorial, we’ll build a basic OPA policy service that integrates with a backend application. OPA will determine whether a user is authorized to access certain resources based on roles stored in a database.

Step 1: Install OPA

To get started, you can install OPA using Docker, which is the easiest method. Run the following command:

    docker run -p 8181:8181 openpolicyagent/opa run --server
 

This command starts OPA on port 8181 in server mode, allowing us to interact with it using HTTP.

Step 2: Define an Example Policy

We’ll define a simple RBAC policy where only users with the role of admin or user can access certain resources. Policies are written in Rego and saved as .regofiles.

Here’s a basic Rego policy that checks the user’s role:

        package authz

default allow = false

allow {
    input.user.role == "admin"
}

allow {
    input.user.role == "user"
}


      

This policy checks the input.user.role field to see if it matches admin or user. If so, the allow rule evaluates to true, and OPA will return an "allow" decision.

Step 3: Test the Policy

You can test the policy using a curl command. Save the Rego policy as authz.rego and run the following command to load and evaluate it:

        curl -X POST http://localhost:8181/v1/data/authz/allow -d '{
    "input": {
        "user": {
            "role": "admin"
        }
    }
}'

      

OPA will respond with a true or false decision based on the role provided in the input.

Response
        {
            "result": true
        }
      

OPA returns true because the user role is admin, which is allowed according to the policy.

Comparison with other policy authorization frameworks

Here’s a comparison table that evaluates Open Policy Agent (OPA) against other popular policy authorization frameworks like AWS IAM, Google Cloud IAM, Kubernetes RBAC, and Spring Security.

Feature/Aspect Open Policy Agent (OPA) AWS IAM Google Cloud IAM Kubernetes RBAC Spring Security Keycloak Custom Authorization
Policy Language Rego (declarative, flexible, highly granular) JSON (policy documents) YAML/JSON (policy documents) YAML (Role & RoleBinding definitions) Java/Annotations (method-level, config-based) JSON, XML (using policies and roles) Any (flexible, defined by custom implementation)
Policy Granularity Highly granular, supports RBAC, ABAC, and custom Fine-grained but limited to AWS resources Fine-grained for Google resources Role-based, focused on Kubernetes resources Fine-grained, flexible for app resources Fine-grained, supports RBAC, ABAC, custom policies Fully flexible, defined by your design
Policy Location Policies stored externally (files, APIs, DB) Integrated within AWS resources Integrated within Google Cloud resources Integrated within Kubernetes cluster Integrated within Spring Boot app Stored within Keycloak, centrally managed Fully flexible, defined by your system
Decoupled from Application Yes, completely decoupled from application logic Part of AWS resource configuration Part of Google Cloud resource configuration Part of Kubernetes cluster Partially decoupled (through annotations or configuration) Yes, can be decoupled or integrated with apps Fully flexible, defined by your system
Support for Multiple Systems Yes, supports any system via APIs or integrations No, tied to AWS ecosystem No, tied to Google Cloud ecosystem No, tied to Kubernetes No, tied to Spring Boot applications Yes, supports multiple applications and protocols Yes, fully customizable for any systems
Dynamic Policy Updates Yes, can pull policies dynamically via APIs or DB Policies are tied to AWS resources, updated via console or CLI Policies updated via console or CLI Yes, but limited to cluster scope Yes, but manual update of configurations Yes, policies can be updated dynamically Depends on implementation (can be manual or automated)
Policy Evaluation Point Can be deployed anywhere (sidecar, middleware, etc.) Managed by AWS at the service level Managed by Google at the service level Evaluated within Kubernetes API Evaluated within the application Managed by Keycloak centrally Fully flexible, can be evaluated in code, middleware, or an external service
Centralized Policy Management Yes, centralized for multiple services or microservices Centralized only for AWS services Centralized only for Google services Centralized only for Kubernetes resources Centralized within Spring applications Yes, centralized management for multiple apps Depends on implementation (can be centralized or distributed)
Policy Decision Model External decision-making engine (pull model) Inline policy enforcement at AWS service level Inline policy enforcement at Google service level Inline policy enforcement at the Kubernetes API level Inline policy enforcement (within app) External decision-making, evaluated within Keycloak Fully flexible (defined by implementation)
Extensibility Highly extensible, supports custom rules, complex logic Limited to AWS resources Limited to Google Cloud resources Focused on Kubernetes API resources Extensible with custom logic in code Extensible, supports custom rules, roles, and policies Fully extensible, defined by your system
Support for Non-Cloud Systems Yes, supports cloud and non-cloud environments No, tied to AWS No, tied to Google Cloud No, tied to Kubernetes Yes, applicable to any Spring-based system Yes, supports both cloud and on-prem systems Yes, fully flexible
Performance Overhead Minimal when deployed locally or as a sidecar Minimal but depends on AWS network latency Minimal, depends on Google network latency Minimal within the Kubernetes cluster Minimal, evaluated within the application Minimal, depends on external Keycloak latency Depends on implementation (could be minimal to significant)
Community and Ecosystem Strong open-source community, growing ecosystem Large AWS-specific ecosystem Large Google-specific ecosystem Kubernetes-focused ecosystem Large Spring Java ecosystem Large open-source and enterprise ecosystem Depends on the technology stack you choose
Compliance Support Supports fine-grained compliance checks Built-in AWS compliance features Built-in Google Cloud compliance features Built-in Kubernetes compliance Requires manual implementation of compliance policies Built-in compliance and identity features Depends on implementation (requires manual compliance checks)

Conclusion

OPA makes policy-based authorization easy to implement and scale in modern microservices architectures. By separating the policy logic from application code, you gain flexibility and maintainability. Whether you're enforcing RBAC, ABAC (Attribute-Based Access Control), or custom policies, OPA provides a powerful and flexible solution.

With OPA integrated into your stack, you can manage policies in one place, scale them easily, and keep your application logic simple and clean.