DEV Community

Alex Spinov
Alex Spinov

Posted on

OPA Has a Free API: Unified Policy Engine for Cloud-Native Environments

Open Policy Agent (OPA) is a general-purpose policy engine that enables unified policy enforcement across your entire stack — Kubernetes admission control, API authorization, Terraform plans, and more.

What Is OPA?

OPA is a CNCF graduated project that decouples policy decision-making from your application. You write policies in Rego (a declarative language), and OPA evaluates them against any JSON data to make allow/deny decisions.

Key Features:

  • General-purpose policy engine
  • Rego policy language
  • REST API for policy evaluation
  • Kubernetes admission control (Gatekeeper)
  • Partial evaluation for optimization
  • Bundle API for policy distribution
  • Decision logging
  • WebAssembly compilation

Quick Start

# Install OPA
brew install opa

# Start OPA server
opa run --server --addr :8181

# Or Docker
docker run -d -p 8181:8181 openpolicyagent/opa:latest run --server
Enter fullscreen mode Exit fullscreen mode

Write Policies in Rego

# policy.rego
package authz

import rego.v1

default allow := false

# Allow admins to do anything
allow if {
    input.user.role == "admin"
}

# Allow users to read their own data
allow if {
    input.method == "GET"
    input.path[0] == "users"
    input.path[1] == input.user.id
}

# Allow managers to read team members
allow if {
    input.method == "GET"
    input.path[0] == "users"
    input.user.role == "manager"
    input.path[1] in input.user.team_members
}
Enter fullscreen mode Exit fullscreen mode

OPA REST API

import requests

OPA = "http://localhost:8181/v1"

# Upload policy
policy = open("policy.rego").read()
requests.put(f"{OPA}/policies/authz", data=policy,
    headers={"Content-Type": "text/plain"})

# Evaluate policy
result = requests.post(f"{OPA}/data/authz/allow", json={
    "input": {
        "user": {"id": "user-42", "role": "admin"},
        "method": "DELETE",
        "path": ["users", "user-99"]
    }
}).json()
print(f"Allowed: {result['result']}")  # True (admin)

# Check non-admin
result = requests.post(f"{OPA}/data/authz/allow", json={
    "input": {
        "user": {"id": "user-42", "role": "user"},
        "method": "GET",
        "path": ["users", "user-42"]
    }
}).json()
print(f"Allowed: {result['result']}")  # True (own data)

result = requests.post(f"{OPA}/data/authz/allow", json={
    "input": {
        "user": {"id": "user-42", "role": "user"},
        "method": "GET",
        "path": ["users", "user-99"]
    }
}).json()
print(f"Allowed: {result['result']}")  # False
Enter fullscreen mode Exit fullscreen mode

Kubernetes with Gatekeeper

# Require all pods to have resource limits
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlimits
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLimits
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlimits
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits.cpu
          msg := sprintf("Container %v has no CPU limit", [container.name])
        }
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits.memory
          msg := sprintf("Container %v has no memory limit", [container.name])
        }
Enter fullscreen mode Exit fullscreen mode

OPA with Python Middleware

from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

def check_authz(user, method, path):
    result = requests.post("http://opa:8181/v1/data/authz/allow", json={
        "input": {"user": user, "method": method, "path": path.split("/")[1:]}
    }).json()
    return result.get("result", False)

@app.before_request
def authorize():
    user = get_current_user()  # From JWT/session
    if not check_authz(user, request.method, request.path):
        return jsonify({"error": "Forbidden"}), 403
Enter fullscreen mode Exit fullscreen mode

Resources


Need to scrape web data for your policy engine? Check out my web scraping tools on Apify — production-ready actors for Reddit, Google Maps, and more. Questions? Email me at spinov001@gmail.com

Top comments (0)