Policy as Code

Styra OPA Alternative for Infrastructure Security and Compliance Policies

In case you haven’t heard yet, the creators of Open Policy Agent (along with many team members from Styra) are leaving to join Apple. Styra’s Enterprise OPA customers have received news that their subscriptions will be ending. The news sent a shockwave through the OPA and Rego communities. It’s uncertain what this means for the future of OPA; will the code still be maintained, will it remain available as open source in the long run, will the license be changed? In this blog we'll share our perspective and take a look at alternatives for Policy as Code use cases.

At the heart of this discussion are two Styra open-source projects that are tightly linked together: The Open Policy Agent (OPA), an engine for executing policies, and Rego, a declarative language for writing policies. These projects are well-known in the Kubernetes community and offer policy executions for other use-cases as well.

What is Styra OPA?

Styra OPA is an open-source policy engine that enables fine-grained control and authorization across various systems using a declarative policy language called Rego. OPA is used for:

  1. Application authorization: OPA allows developers to define authorization policies in a declarative way, which simplifies development, improves maintainability, and enhances security by centralizing policy management. For example OPA can be used to determine whether a user is authorized to view a specific document based on their role and the document's attributes. 
  2. Infrastructure guardrails: OPA enforces configuration policies on infrastructure deployments like Kubernetes, microservices, and CI/CD pipelines, ensuring that resources are provisioned according to predefined rules and best practices. For example, OPA can be used to ensure that all Kubernetes deployments are deployed to approved regions, require specific security settings, or use approved container images. 

From the ground up, the OPA/Rego framework was designed to solve a very specific problem: Authorization. This area is one of the most daunting fields for developers to maintain and is riddled with complexities. OPA offered a better solution that helped many developers (including ourselves) tackle authorization use cases in a maintainable way. It is great for programmers that have to deal with authorization use cases, especially in APIs and Kubernetes scenarios.

Today, there are many paths for tackling authorization use cases. For an alternative approach to authorization, you can take a look at OpenFGA, which is based on the paper "Zanzibar: Google’s Consistent, Global Authorization System." There is also AWS Cedar and Google Zanzibar itself. 

New frontier: OPA for infrastructure security and compliance

Over the years, the coverage of OPA and Rego gradually expanded to new use cases, such as conftest. These were more focused on infrastructure components, like writing policies to verify IaC code (e.g. Terraform), filtering alerts in CI/CD pipelines, and validating compliance requirements before these configurations are applied to production. 

As OPA usage continued expanding, new users like security analysts started using it and new requirements were also introduced. However, these new users were getting frustrated with the framework, because it was complicated, hard to debug, and difficult to expand. OPA/Rego was now being used by an entirely new group of users, who weren't developers anymore. Even with the rise of GenAI, which made it easier to generate Rego code, these problems persisted and became worse as users struggled to maintain and test their policies.

Maslow's hammer is very fitting here: "If all you have is a hammer, it's tempting to treat everything like a nail." OPA and Rego were trying to solve problems that they weren't designed to solve well. That's why we encountered many teams in some of the largest tech companies in the world who tried and failed to implement OPA/Rego for infrastructure security and compliance.

Mondoo Policy as Code

Mondoo offers an intuitive approach centered on YAML policies and lightweight Mondoo Query Language (MQL) scripts to enforce policies across the entire IT environment (including cloud, on-prem, endpoints, and SaaS). MQL can be used to create policies in cnspec, Mondoo’s open source, cloud-native tool that assesses the security, compliance, and cost control of your entire infrastructure. MQL was purpose-built for security teams, making it the easiest policy as code solution to use and understand.

Mondoo includes a rich library of pre-built policies for common security standards and compliance frameworks, and makes it easy to write YAML policies in MQL, even for non-developers. In addition, Mondoo includes an AI policy generator, pre-trained on Mondoo MQL policies, that can generate or update policies. All coded policies can be viewed in the Mondoo UI, making them accessible for security and compliance teams.

Due to this design, Mondoo is far better suited than OPA/Rego to tackle infrastructure security and compliance that is used by both security and platform engineering teams. 

Mondoo Policy as Code is perfect for:

  1. Security posture analysis of cloud environments: with built-in support for AWS, Azure, Google Cloud, OCI, and more.
  2. Security posture of operating systems and containers: covering the vast majority of OSs for servers and endpoints, images, as well as containers and container images.
  3. Infrastructure as Code (IaC):  including Terraform, Ansible, and CloudFormation. Policies can even be written for IaC and runtime use cases at the same time. For example, a rule can check if your Terraform HCL is configured correctly, while also testing the deployed service in your cloud.
  4. Kubernetes: including manifest security and Kubernetes objects. The Mondoo Operator for Kubernetes supports analyzing entire clusters.
  5. Cost controls: to avoid costly infrastructure from spinning up without guardrails. Cost control policies can prevent unnecessary spend and help manage exceptions.
  6. Best practices: policies that focus on operational requirements and best practices that you want your platform teams to follow.  
  7. Compliance: particularly for regulatory compliance across different countries. These compliance frameworks help automate the evidence gathering and prevent changes from breaking compliance policies. 
  8. Inventory: MQL was not only written with policy assertions in mind, but was also built on the premise of creating a rich inventory of your infrastructure. You can use the inventory to explore, search, or feed it into your favorite AI tool to quickly get accurate answers about which assets you have, and what’s running on them.

While switching to a different solution always takes some effort, we believe that for those who are using  OPA/Rego for infrastructure security and compliance the additional effort is worth it - especially now, with the uncertain future of OPA.

Find and fix the security risks that pose the biggest threat to your business.

Mondoo Policy as Code: Define Once, Enforce Everywhere

Comparing Mondoo MQL with OPA Rego

Below we provide a few comparisons between Mondoo's MQL and OPA's Rego. The examples for Rego are taken from https://github.com/open-policy-agent/conftest/tree/master/examples. In these examples you can see how much shorter and more concise the MQL code is. It is considerably easier to read, understand, and to maintain long-term. 

#1. Dockerfile

FROM openjdk:8-jdk-alpine

VOLUME /tmp

ARG DEPENDENCY=target/dependency

COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app

RUN apk add --no-cache python3 python3-dev build-base && pip3 install awscli==1.18.1

ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

Example: Ensure the openjdk image is not used

Rego:

package main
import rego.v1

denylist := ["openjdk"]

deny contains msg if {
    some i
    input[i].Cmd == "from"
    val := input[i].Value
    contains(val[i], denylist[_])

    msg = sprintf("unallowed image found %s", [val])
}

MQL:

docker.file.stages.none(from.image == "openjdk")

Example: Ensure that apk, apt, pip, curl, wget commands are not used

Rego:

package commands
import rego.v1

denylist := [
    "apk",
    "apt",
    "pip",
    "curl",
    "wget",
]

deny contains msg if {
    some i
    input[i].Cmd == "run"
    val := input[i].Value
    contains(val[_], denylist[_])

    msg := sprintf("unallowed commands found %s", [val])
}

MQL:

denylist = ["apk", "apt","pip", "curl", "wget"]
docker.file.stages.all(
    run.all(
        script.split(" ").containsNone(denylist)
    )
)

#2. Terraform/HCL

Example: Ensure that google_iam and google_container resources are not used

Full example is available here https://github.com/open-policy-agent/conftest/blob/master/examples/hcl1/gke.tf.

provider "google" {
  version = "2.5.0"
  project = "instrumenta"
  region = "europe-west2"
}

resource "google_container_cluster" "primary" {
  name     = "my-gke-cluster"
  location = "us-central1"
  .. 
}

resource "google_container_node_pool" "primary_preemptible_nodes" {
  name       = "my-node-pool"
  ...
}

Rego:

package main
import rego.v1

denylist := [
    "google_iam",
    "google_container",
]

deny contains msg if {
    check_resources(input.resource_changes, denylist)
    banned := concat(", ", denylist)
    msg := sprintf("Terraform plan will change prohibited resources in the following namespaces: %v", [banned])
}

# Checks whether the plan will cause resources with certain prefixes to change
check_resources(resources, disallowed_prefixes) if {
    startswith(resources[_].type, disallowed_prefixes[_])
}

MQL:

denyList=["google_iam", "google_container"]
denyList.all(entry: terraform.resources.none(nameLabel.contains(entry)))

#3. Kubernetes

Example: Kubernetes Deployment file

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
    app.kubernetes.io/managed-by: helm
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes
  template:
    metadata:
      labels:
        app: hello-kubernetes
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.5
        ports:
        - containerPort: 8080

Rego:

package kubernetes
import rego.v1

is_deployment if {
    input.kind = "Deployment"
}

package main
import rego.v1

import data.kubernetes

name := input.metadata.name

deny contains msg if {
    kubernetes.is_deployment
    not input.spec.template.spec.securityContext.runAsNonRoot

    msg = sprintf("Containers must not run as root in Deployment %s", [name])
}

MQL:

 k8s.deployments.all( podSpec.securityContext.runAsNonRoot == empty)

Deciding between OPA and Mondoo MQL

So how do you decide which solution is best for your purposes? Below we have listed the pros and cons of both solutions as well as a decision matrix, to help you make the best decision.

Pros and Cons of OPA Rego

Pro Con
Data agnostic - Works with any JSON/YAML data from any source Steep learning curve - Logic programming paradigm is unfamiliar to most
Real-time enforcement - Perfect for admission controllers Requires external data collection - Need separate systems to gather config data
Mature ecosystem - Extensive tooling, IDE support Generic data model - No built-in understanding of specific resource types
Kubernetes native - Deep integration with K8s via Gatekeeper Limited security expertise - Requires building security knowledge from scratch
Rich query language - Supports complex joins, aggregations, set operations No built-in risk scoring - Manual effort to implement impact assessment
Verbose syntax - Can become complex for simple checks
Debugging challenges - Logic programming can be hard to troubleshoot
No asset management - Lacks inventory and tracking capabilities

Pros and Cons of Mondoo MQL

Pro Con
Security-focused design - Built specifically for security and compliance Limited real-time enforcement - Primarily assessment-focused
Easy to learn - GraphQL-like syntax familiar to most security users Provider dependency - Limited to supported platforms and services, providers are extensible similar to terraform.
Automated data collection - Built-in scanners for 25+ platforms Less general-purpose - Not suitable for non-security policy use cases like authorization
Rich resource models - Deep understanding of AWS, Azure, K8s, OS configs Emerging ecosystem - Fewer third-party integrations and community tools
Pre-built policies - Extensive library of CIS, SOC 2, PCI DSS policies
Risk scoring built-in - Automatic impact assessment
Asset inventory - Comprehensive tracking and management
Unified platform - Single tool for cloud, OS, containers, SaaS
Professional support - Commercial backing with enterprise features
Compliance reporting - Rich dashboards and audit reports

OPA vs Mondoo Decision Matrix

Choose OPA/Rego if you need: Choose Mondoo if you need:
Real-time authorization enforcement Security & compliance assessment
Kubernetes admission control Out-of-the-box security policies like CIS, STIG, and Mondoo benchmarks
Custom authorization logic Enforce custom business requirements like cost controls, security, and compliance
Multi-cloud configuration scanning incl. coverage of IaC to cloud policy coverage
IaC and runtime assessment for tool consolidation
Comprehensive vulnerability detection and remediation
Risk-based prioritization to prioritize business-critical systems and toxic combinations
Asset inventory
Professional support

Conclusion

Mondoo Policy as Code is focused on providing ease of use and provides a more comprehensive, unified solution for policy as code, particularly catering to security and compliance needs across the entire IT infrastructure, including traditional and modern components.

Mondoo's MQL framework supports countless use cases out of the box, is easier to succeed, and works well in combination with LLMs. Mondoo’s open-source projects are also highly extensible to support any technology you want to tackle. Take it for a spin and join our community! Or, if you’d like to discuss your Policy as Code needs, please contact us.

Dominik Richter

Dom is a founder, coder, and hacker and one of the creators of Mondoo. He helped shape the DevOps and security space with projects like InSpec and Dev-Sec.io. Dom worked in security and automation at companies like Google, Chef, and Deutsche Telekom. Beyond his work, he loves to dive deep into hacker and nerd culture, science and the mind, and making colorful pasta from scratch.

You might also like

Microsoft
Microsoft Patch Tuesday August 2025: How to Prioritize Vulnerabilities for Patching
Vulnerabilities
Introducing Agentic Vulnerability Patching Using Ansible
Insights from DEF CON 33: From LLM Hacking to Supply Chain Remediation