Eliminate Critical Risks in Your Cloud Environment

Secure your cloud with thousands of built-in policies, or create your own with Wiz and OPA

What is Open Policy Agent (OPA)? Best Practices + Applications

Open Policy Agent (OPA) is an open-source, versatile policy engine that facilitates unified and context-aware policy enforcement across various cloud environments.

6 minutes read

Open Policy Agent (OPA) explained

Open Policy Agent (OPA) is an open-source, versatile policy engine that facilitates unified and context-aware policy enforcement across various cloud environments. As a developer or systems architect, you might have encountered challenges when managing policies across multiple platforms and services. OPA addresses these challenges head-on by providing versatile and high-level policy languages designed to express policy rules efficiently and effectively.

Why is OPA important?

The need for robust policy management has grown significantly as organizations increasingly adopt cloud-native technologies. Traditional methods of embedding policy logic directly into software services are no longer feasible due to their complexity and lack of scalability. With OPA, you can decouple policy enforcement from these services, gaining greater control and flexibility.

One of OPA's standout features is its ability to integrate seamlessly with a variety of native environments. Whether Kubernetes, microservices architectures, or CI/CD pipelines, OPA's flexible design allows it to fit into different operational models.

Pro tip

Open policy agent's integration capability is essential for organizations looking to implement a unified policy enforcement strategy across their entire infrastructure.

In the subsequent sections, we'll delve deeper into the benefits and applications of OPA and see how this general-purpose policy engine can transform the way you approach policy enforcement in your cloud-native architecture.

Benefits and applications of OPA

Leveraging Open Policy Agent offers significant advantages that make it an essential tool for managing policies in cloud-native environments:

Security and compliance

One of the primary drivers for adopting Open Policy Agent is its ability to enhance security and ensure compliance in cloud-native environments. By implementing policy as code, organizations can codify security and compliance requirements into policies that are automatically enforced across all systems. This approach minimizes human error and ensures that policies are applied consistently.

For instance, consider a scenario where an organization needs to make sure that all container images are scanned for vulnerabilities before deployment. With OPA, a policy can be written to enforce this requirement, preventing any unscanned images from being deployed.

Flexibility and scalability

Another significant advantage of OPA is its flexibility. Because OPA allows policies to be applied across various platforms and services, it’s a versatile tool for modern infrastructure. Whether it's Kubernetes, microservices, or traditional applications, OPA can enforce policies uniformly, providing a cohesive policy management framework.

For example, a large enterprise might use OPA to manage policies across hundreds of Kubernetes clusters. By centralizing policy definitions in a policy library, the organization can ensure consistent policy enforcement regardless of the scale of its operations. This approach simplifies policy updates and ensures that new policies are rolled out seamlessly across all environments.

Decoupling policy from code

Traditionally, policy enforcement mechanisms are embedded within software services, leading to tightly coupled systems that are difficult to update and manage. OPA addresses this issue by separating policy logic from these services, allowing policies to be defined and managed independently. Teams can review, test, and audit policies using the same workflows they use for code, creating high standards of quality and compliance.

Pro tip

Separating policy and code has several benefits for development and operations teams. Developers can focus on writing application logic without worrying about policy enforcement details. Meanwhile, operations teams can manage and update policies without modifying application code. Dividing these responsibilities improves collaboration and accelerates the development and deployment processes.

How does OPA work?

OPA evaluates policies and makes decisions based on predefined rules. When a policy decision is required, OPA receives policy input in the form of a JSON document. (This input contains all the necessary information for OPA to evaluate the policy.) OPA then uses the policies defined in Rego (OPA’s policy language) to process this input and return a decision:

Figure 1: OPA overview (Source: OPA Docs)
Figure 1: OPA overview (Source: OPA Docs)

For example, in a Kubernetes environment, policies can be evaluated in two key stages: at the infrastructure-as-code (IaC) level and at runtime. Before a pod is deployed, OPA can be used to evaluate an IaC manifest to ensure that configurations adhere to organizational policies.

Once the pod reaches the Kubernetes API, GateKeeper—an admission controller that works with OPA—can enforce policies related to security, misconfiguration, and compliance before the pod is created. This layered approach ensures that all resources in the cluster comply with organizational policies both before and during deployment:

Figure 2: Admission control flow with OPA (Source: OPA Docs)

Understanding Rego

OPA's policy language, Rego, is a high-level declarative language that simplifies the process of writing and managing policies. Rego enables you to define policies that are both expressive and easy to understand, which makes it easier for teams to collaborate on policy development and maintenance. Fundamental principles and design goals of Rego include:

  • Expressiveness: Rego is designed to express a wide range of policies, from simple access control rules to complex compliance requirements.

  • Declarative syntax: Policies in Rego are written declaratively, allowing you to state what the policy should enforce.

  • Flexibility: Rego supports various data types and operations, making it suitable for a broad range of policy enforcement scenarios.

The policies written in Rego can be stored in a policy library, allowing for reuse and version control, much like how code is managed in a code repository. The ability to maintain a centralized policy library means that policy changes can be propagated consistently across all systems that rely on OPA for policy enforcement. As a result, any updates or new policies are applied uniformly, reducing the risk of policy drift and compliance issues.

Best practices

Implementing policies with OPA requires adhering to best practices to ensure clarity, modularity, performance, and maintainability:

1. Define clear policy goals

Ensure each policy has a specific, measurable goal to simplify evaluation and maintenance. The following example policy denies the creation of any pod in which containers lack defined resource limits:

package kubernetes.admission

deny[{"msg": msg}] {
    input.request.kind.kind == "Pod"
    container := input.request.object.spec.containers[_]
    not container.resources.limits
    msg := "All containers must have resource limits set"
}

2. Use modular policy design

Enhance manageability by decomposing complex policies into smaller, reusable modules. The following policy verifies if the container image originates from an approved registry by importing and utilizing a separate module:

package kubernetes.admission

import data.image_policy

deny[{"msg": msg}] {
    input.request.kind.kind == "Pod"
    container := input.request.object.spec.containers[_]
    not image_policy.allowed_registry(container.image)
    msg := "Container image must be from an allowed registry"
}

# image_policy.rego
package image_policy

allowed_registry(image) {
    startswith(image, "myregistry.com/")
}

3. Optimize for performance

Write efficient policies to minimize evaluation time, especially in high-throughput environments. The following policy precomputes a set of allowed namespaces to quickly check if the pod's namespace is permitted:

package kubernetes.admission

# Precompute allowed namespaces
allowed_ns := { "default", "kube-system", "production" }

deny[{"msg": msg}] {
    input.request.kind.kind == "Pod"
    not input.request.object.metadata.namespace in allowed_ns
    msg := "Pod namespace is not allowed"
}

4. Implement logging and monitoring

Incorporate logging within policies to facilitate auditing and troubleshooting. The following policy logs each denied request, helping administrators to audit policy-enforcement activities:

package kubernetes.admission

# A deny rule that prevents pod creation if containers don't have resource limits
deny[{"msg": msg}] {
    input.request.kind.kind == "Pod"
    container := input.request.object.spec.containers[_]
    not container.resources.limits
    msg := "All containers must have resource limits set"
    
    # Log the denied request message for external logging purposes
    logging_msg := sprintf("Denied request for Pod: %v, reason: %v", [input.request.object.metadata.name, msg])
    log_violation(logging_msg)
    
    # Increment monitoring counter for tracking policy violations
    record_violation()
}

# This function simulates logging the violation (in practice, external tools will log these messages)
log_violation(logging_msg) {
    # External system would capture this log
    print(logging_msg)
}

5. Regularly review and update policies

Policies should evolve with the application and the threat landscape to remain effective. The following policy shows how to incrementally add new rules to reflect new compliance requirements:

package kubernetes.admission

deny[{"msg": msg}] {
    input.request.kind.kind == "Pod"
    container := input.request.object.spec.containers[_]
    not container.resources.limits
    msg := "All containers must have resource limits set"
}

# New policy addition for compliance
deny[{"msg": msg}] {
    input.request.kind.kind == "Pod"
    container := input.request.object.spec.containers[_]
    not container.securityContext.runAsUser == 1000
    msg := "Containers must run as non-root user"
}

OPA and Wiz

As we’ve seen, OPA offers numerous benefits for cloud security and policy management, including unified policy enforcement, flexibility, and scalability. Additionally, OPA facilitates the separation of policy logic from application code for better manageability and enhances security and compliance by automating the enforcement of related policies.

To see how these benefits can be seamlessly integrated into your cloud security strategy, consider adopting Wiz. Wiz’s benefits include:

  • Automated policy enforcement: Wiz leverages OPA to automatically enforce security policies consistently across the entire development lifecycle, from code to runtime. By unifying policy enforcement from development through to production, Wiz reduces the risk of human error and ensures security controls are applied at every stage.

  • Centralized policy management: With Wiz, policies can be managed centrally and are applied consistently across all cloud resources. 

  • Real-time compliance monitoring: By integrating OPA, Wiz ensures that all resources adhere to security standards by providing continuous monitoring and enforcement of compliance policies.

To learn more about Open Policy Agent (OPA) and how it can improve your cloud security, check out our detailed blog post in collaboration with Styra: Getting started with Open Policy Agent (OPA) to improve your cloud security.

Bolster your cloud security with OPA and Wiz

We have thousands of built-in policies to protect you from potential cloud security risks, or you can leverage Rego to tune Wiz for your needs.

Get a demo

Continue reading

Vulnerability Prioritization in the Cloud: Strategies + Steps

Vulnerability prioritization is the practice of assessing and ranking identified security vulnerabilities based on critical factors such as severity, potential impact, exploitability, and business context. This ranking helps security experts and executives avoid alert fatigue to focus remediation efforts on the most critical vulnerabilities.