コンテンツにスキップ

Open Policy Agent (OPA) Cheatsheet

- :material-content-copy: **[Copy to Clipboard](#copy-to-clipboard)** - :material-file-pdf-box: **[Download PDF](#download-pdf)**

Overview

Open Policy Agent (OPA) is an open-source, general-purpose policy engine that enables unified, context-aware policy enforcement across the entire stack. OPA provides a high-level declarative language (Rego) for authoring policies and simple APIs to offload policy decision-making from your software.

Key Features

  • Policy-as-Code: Define policies using the Rego language
  • Unified Policy Engine: Single policy engine for multiple services
  • Context-Aware Decisions: Rich context for policy evaluation
  • High Performance: Fast policy evaluation with caching
  • Cloud-Native Integration: Native Kubernetes and cloud platform support
  • Extensible: Plugin architecture for custom integrations

Installation

Binary Installation

# Download latest release
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
chmod +x opa
sudo mv opa /usr/local/bin/

# Verify installation
opa version

Package Manager Installation

# Homebrew (macOS/Linux)
brew install opa

# Snap (Linux)
sudo snap install opa

# APT (Ubuntu/Debian)
curl -L -o opa_linux_amd64.deb https://github.com/open-policy-agent/opa/releases/latest/download/opa_linux_amd64.deb
sudo dpkg -i opa_linux_amd64.deb

# YUM (RHEL/CentOS/Fedora)
curl -L -o opa_linux_amd64.rpm https://github.com/open-policy-agent/opa/releases/latest/download/opa_linux_amd64.rpm
sudo rpm -i opa_linux_amd64.rpm

Container Installation

# Pull Docker image
docker pull openpolicyagent/opa:latest

# Run as container
docker run -p 8181:8181 openpolicyagent/opa:latest run --server

Go Installation

# Install via Go
go install github.com/open-policy-agent/opa@latest

# Verify installation
opa version

Basic Usage

Running OPA Server

# Start OPA server
opa run --server

# Start with specific address and port
opa run --server --addr localhost:8181

# Start with configuration file
opa run --server --config-file config.yaml

# Start with bundle
opa run --server --bundle bundle.tar.gz

Policy Evaluation

# Evaluate policy with input
opa eval -d policy.rego -i input.json "data.example.allow"

# Evaluate with data
opa eval -d policy.rego -d data.json -i input.json "data.example.allow"

# Format output as JSON
opa eval --format json -d policy.rego -i input.json "data.example.allow"

# Pretty print output
opa eval --format pretty -d policy.rego -i input.json "data.example.allow"

Policy Testing

# Run tests
opa test policy.rego policy_test.rego

# Run tests with coverage
opa test --coverage policy.rego policy_test.rego

# Run tests with verbose output
opa test --verbose policy.rego policy_test.rego

# Generate coverage report
opa test --coverage --format json policy.rego policy_test.rego > coverage.json

Rego Language Basics

Basic Policy Structure

# policy.rego
package example

# Default deny
default allow = false

# Allow rule
allow {
    input.method == "GET"
    input.path[0] == "public"
}

# Allow with conditions
allow {
    input.method == "POST"
    input.path[0] == "api"
    input.user.role == "admin"
}

Data Types and Operations

# Numbers
count := 42
pi := 3.14159

# Strings
message := "Hello, World!"
name := sprintf("User: %s", [input.user.name])

# Booleans
is_admin := input.user.role == "admin"
has_permission := "read" in input.user.permissions

# Arrays
users := ["alice", "bob", "charlie"]
first_user := users[0]

# Objects
user := {
    "name": "alice",
    "role": "admin",
    "permissions": ["read", "write"]
}

# Sets
permissions := {"read", "write", "delete"}

Control Flow

# Conditional logic
allow {
    input.method == "GET"
    input.path[0] == "public"
}

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

# Iteration
user_has_permission {
    some permission
    permission := input.user.permissions[_]
    permission == "admin"
}

# Comprehensions
admin_users := [user | user := data.users[_]; user.role == "admin"]
user_permissions := {permission | permission := input.user.permissions[_]}

Functions and Rules

# Helper functions
is_admin {
    input.user.role == "admin"
}

is_owner {
    input.user.id == input.resource.owner_id
}

# Rules with parameters
has_permission(permission) {
    permission in input.user.permissions
}

# Complex rules
allow {
    is_admin
}

allow {
    is_owner
    has_permission("read")
}

Kubernetes Integration

OPA Gatekeeper Installation

# Install Gatekeeper
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.14/deploy/gatekeeper.yaml

# Verify installation
kubectl get pods -n gatekeeper-system

# Check Gatekeeper status
kubectl get constrainttemplates
kubectl get constraints

Constraint Templates

# constraint-template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        type: object
        properties:
          labels:
            type: array
            items:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        violation[{"msg": msg}] {
          required := input.parameters.labels
          provided := input.review.object.metadata.labels
          missing := required[_]
          not provided[missing]
          msg := sprintf("Missing required label: %v", [missing])
        }

Constraints

# constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: must-have-environment
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["Deployment"]
  parameters:
    labels: ["environment", "team"]

Admission Controller Policies

# admission-policy.rego
package kubernetes.admission

import data.kubernetes.namespaces

# Deny pods without resource limits
deny[msg] {
    input.request.kind.kind == "Pod"
    input.request.object.spec.containers[_]
    container := input.request.object.spec.containers[_]
    not container.resources.limits.memory
    msg := "Container must have memory limits"
}

# Deny privileged containers
deny[msg] {
    input.request.kind.kind == "Pod"
    input.request.object.spec.containers[_].securityContext.privileged
    msg := "Privileged containers are not allowed"
}

# Require specific labels
deny[msg] {
    input.request.kind.kind == "Deployment"
    required_labels := ["environment", "team", "version"]
    provided_labels := input.request.object.metadata.labels
    missing := required_labels[_]
    not provided_labels[missing]
    msg := sprintf("Missing required label: %v", [missing])
}

Advanced Policy Patterns

RBAC Policies

# rbac-policy.rego
package rbac

import data.users
import data.roles

# Default deny
default allow = false

# Allow based on user roles
allow {
    user_has_role(input.user, "admin")
}

allow {
    user_has_role(input.user, "editor")
    input.action == "read"
}

allow {
    user_has_role(input.user, "viewer")
    input.action == "read"
    not input.resource.sensitive
}

# Helper functions
user_has_role(user, role) {
    user.roles[_] == role
}

user_has_permission(user, permission) {
    role := user.roles[_]
    roles[role].permissions[_] == permission
}

Data Filtering Policies

# data-filter-policy.rego
package data.filter

# Filter sensitive data based on user role
filtered_users[user] {
    user := data.users[_]
    input.user.role == "admin"
}

filtered_users[user] {
    user := data.users[_]
    input.user.role == "manager"
    user.department == input.user.department
    filtered_user := object.remove(user, ["ssn", "salary"])
    user := filtered_user
}

filtered_users[user] {
    user := data.users[_]
    input.user.role == "employee"
    user.id == input.user.id
    filtered_user := object.remove(user, ["ssn", "salary", "performance"])
    user := filtered_user
}

Compliance Policies

# compliance-policy.rego
package compliance

# PCI DSS compliance checks
pci_compliant {
    # Check encryption requirements
    input.data.encrypted == true

    # Check access controls
    count(input.data.access_controls) > 0

    # Check audit logging
    input.data.audit_logging == true

    # Check network segmentation
    input.data.network_segmented == true
}

# GDPR compliance checks
gdpr_compliant {
    # Check data minimization
    data_minimized

    # Check consent
    valid_consent

    # Check data retention
    retention_policy_valid
}

data_minimized {
    required_fields := {"name", "email"}
    provided_fields := {field | field := object.keys(input.data)[_]}
    extra_fields := provided_fields - required_fields
    count(extra_fields) == 0
}

valid_consent {
    input.data.consent.given == true
    input.data.consent.timestamp > time.now_ns() - (365 * 24 * 60 * 60 * 1000000000)
}

retention_policy_valid {
    input.data.created_at > time.now_ns() - (input.policy.retention_days * 24 * 60 * 60 * 1000000000)
}

CI/CD Integration

GitHub Actions

# .github/workflows/opa.yml
name: OPA Policy Validation

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  opa-test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Setup OPA
      uses: open-policy-agent/setup-opa@v2
      with:
        version: latest

    - name: Run OPA tests
      run: |
        opa test policies/ --verbose

    - name: Run OPA format check
      run: |
        opa fmt --list policies/
        if [ $? -ne 0 ]; then
          echo "Policy files are not formatted correctly"
          exit 1
        fi

    - name: Validate policies
      run: |
        find policies/ -name "*.rego" -exec opa fmt {} \;
        find policies/ -name "*.rego" -exec opa parse {} \;

    - name: Run policy evaluation tests
      run: |
        # Test allow cases
        opa eval -d policies/ -i test-data/allow-input.json "data.example.allow" | grep -q "true"

        # Test deny cases
        opa eval -d policies/ -i test-data/deny-input.json "data.example.allow" | grep -q "false"

    - name: Generate coverage report
      run: |
        opa test --coverage --format json policies/ > coverage.json

    - name: Upload coverage
      uses: actions/upload-artifact@v3
      with:
        name: opa-coverage
        path: coverage.json

GitLab CI

# .gitlab-ci.yml
stages:
  - validate
  - test

opa-validate:
  stage: validate
  image: openpolicyagent/opa:latest
  script:
    - opa fmt --list policies/
    - find policies/ -name "*.rego" -exec opa parse {} \;
  only:
    - main
    - merge_requests

opa-test:
  stage: test
  image: openpolicyagent/opa:latest
  script:
    - opa test policies/ --verbose --coverage
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml
  only:
    - main
    - merge_requests

Jenkins Pipeline

// Jenkinsfile
pipeline {
    agent any

    stages {
        stage('Setup') {
            steps {
                script {
                    // Install OPA
                    sh '''
                        curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
                        chmod +x opa
                        sudo mv opa /usr/local/bin/
                    '''
                }
            }
        }

        stage('Validate Policies') {
            steps {
                script {
                    // Format check
                    sh 'opa fmt --list policies/'

                    // Parse check
                    sh 'find policies/ -name "*.rego" -exec opa parse {} \\;'
                }
            }
        }

        stage('Test Policies') {
            steps {
                script {
                    // Run tests
                    sh 'opa test policies/ --verbose --coverage --format json > test-results.json'

                    // Parse test results
                    def testResults = readJSON file: 'test-results.json'
                    def passedTests = testResults.findAll { it.result == 'PASS' }.size()
                    def failedTests = testResults.findAll { it.result == 'FAIL' }.size()

                    echo "Tests passed: ${passedTests}"
                    echo "Tests failed: ${failedTests}"

                    if (failedTests > 0) {
                        error("${failedTests} policy tests failed")
                    }
                }
            }
        }

        stage('Deploy Policies') {
            when {
                branch 'main'
            }
            steps {
                script {
                    // Deploy to OPA server
                    sh '''
                        curl -X PUT http://opa-server:8181/v1/policies/example \
                          --data-binary @policies/example.rego
                    '''

                    // Deploy to Kubernetes
                    sh '''
                        kubectl apply -f k8s/constraint-templates/
                        kubectl apply -f k8s/constraints/
                    '''
                }
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: 'test-results.json', fingerprint: true
        }
    }
}

Automation Scripts

Policy Bundle Management

#!/bin/bash
# opa-bundle-manager.sh

set -e

# Configuration
BUNDLE_DIR="policies"
BUNDLE_NAME="policy-bundle"
OPA_SERVER="${OPA_SERVER:-http://localhost:8181}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Function to create bundle
create_bundle() {
    echo "Creating policy bundle..."

    # Create bundle structure
    mkdir -p "bundles/$BUNDLE_NAME"

    # Copy policies
    cp -r "$BUNDLE_DIR"/* "bundles/$BUNDLE_NAME/"

    # Create manifest
    cat > "bundles/$BUNDLE_NAME/.manifest" << EOF
{
  "revision": "$TIMESTAMP",
  "roots": [""]
}
EOF

    # Create bundle tarball
    cd bundles
    tar -czf "$BUNDLE_NAME-$TIMESTAMP.tar.gz" "$BUNDLE_NAME"
    cd ..

    echo "Bundle created: bundles/$BUNDLE_NAME-$TIMESTAMP.tar.gz"
}

# Function to validate policies
validate_policies() {
    echo "Validating policies..."

    # Format check
    opa fmt --list "$BUNDLE_DIR"
    if [ $? -ne 0 ]; then
        echo "❌ Policy formatting issues found"
        exit 1
    fi

    # Parse check
    find "$BUNDLE_DIR" -name "*.rego" -exec opa parse {} \;
    if [ $? -ne 0 ]; then
        echo "❌ Policy parsing errors found"
        exit 1
    fi

    # Run tests
    opa test "$BUNDLE_DIR" --verbose
    if [ $? -ne 0 ]; then
        echo "❌ Policy tests failed"
        exit 1
    fi

    echo "✅ All policies validated successfully"
}

# Function to deploy bundle
deploy_bundle() {
    local bundle_file="$1"

    echo "Deploying bundle to OPA server..."

    # Upload bundle
    curl -X PUT "$OPA_SERVER/v1/policies/bundle" \
        -H "Content-Type: application/gzip" \
        --data-binary "@$bundle_file"

    if [ $? -eq 0 ]; then
        echo "✅ Bundle deployed successfully"
    else
        echo "❌ Bundle deployment failed"
        exit 1
    fi
}

# Function to test deployment
test_deployment() {
    echo "Testing deployed policies..."

    # Test policy evaluation
    curl -X POST "$OPA_SERVER/v1/data/example/allow" \
        -H "Content-Type: application/json" \
        -d '{"input": {"method": "GET", "path": ["public", "data"]}}' \
        | jq -r '.result'

    if [ $? -eq 0 ]; then
        echo "✅ Policy evaluation test passed"
    else
        echo "❌ Policy evaluation test failed"
        exit 1
    fi
}

# Main execution
main() {
    case "${1:-all}" in
        "validate")
            validate_policies
            ;;
        "bundle")
            validate_policies
            create_bundle
            ;;
        "deploy")
            validate_policies
            create_bundle
            deploy_bundle "bundles/$BUNDLE_NAME-$TIMESTAMP.tar.gz"
            test_deployment
            ;;
        "all")
            validate_policies
            create_bundle
            deploy_bundle "bundles/$BUNDLE_NAME-$TIMESTAMP.tar.gz"
            test_deployment
            ;;
        *)
            echo "Usage: $0 {validate|bundle|deploy|all}"
            exit 1
            ;;
    esac
}

main "$@"

Policy Testing Framework

#!/usr/bin/env python3
# opa-test-framework.py

import json
import subprocess
import sys
import os
from pathlib import Path

class OPATestFramework:
    def __init__(self, policy_dir="policies", test_dir="tests"):
        self.policy_dir = Path(policy_dir)
        self.test_dir = Path(test_dir)
        self.opa_binary = "opa"

    def run_opa_command(self, args):
        """Run OPA command and return result"""
        try:
            result = subprocess.run(
                [self.opa_binary] + args,
                capture_output=True,
                text=True,
                check=True
            )
            return result.stdout, result.stderr
        except subprocess.CalledProcessError as e:
            return None, e.stderr

    def validate_policies(self):
        """Validate policy syntax and formatting"""
        print("Validating policies...")

        # Check formatting
        stdout, stderr = self.run_opa_command(["fmt", "--list", str(self.policy_dir)])
        if stderr:
            print(f"❌ Formatting issues: {stderr}")
            return False

        # Check parsing
        for policy_file in self.policy_dir.glob("**/*.rego"):
            stdout, stderr = self.run_opa_command(["parse", str(policy_file)])
            if stderr:
                print(f"❌ Parse error in {policy_file}: {stderr}")
                return False

        print("✅ All policies validated")
        return True

    def run_unit_tests(self):
        """Run OPA unit tests"""
        print("Running unit tests...")

        stdout, stderr = self.run_opa_command([
            "test", str(self.policy_dir), "--verbose", "--format", "json"
        ])

        if stderr:
            print(f"❌ Test execution error: {stderr}")
            return False

        try:
            results = json.loads(stdout)
            passed = sum(1 for r in results if r.get("result") == "PASS")
            failed = sum(1 for r in results if r.get("result") == "FAIL")

            print(f"Tests passed: {passed}")
            print(f"Tests failed: {failed}")

            if failed > 0:
                for result in results:
                    if result.get("result") == "FAIL":
                        print(f"❌ {result.get('package')}.{result.get('name')}: {result.get('error')}")
                return False

            print("✅ All unit tests passed")
            return True

        except json.JSONDecodeError:
            print(f"❌ Failed to parse test results: {stdout}")
            return False

    def run_integration_tests(self):
        """Run integration tests with sample data"""
        print("Running integration tests...")

        test_cases = self.load_test_cases()
        passed = 0
        failed = 0

        for test_case in test_cases:
            result = self.evaluate_policy(test_case)
            if result == test_case["expected"]:
                passed += 1
                print(f"✅ {test_case['name']}")
            else:
                failed += 1
                print(f"❌ {test_case['name']}: expected {test_case['expected']}, got {result}")

        print(f"Integration tests passed: {passed}")
        print(f"Integration tests failed: {failed}")

        return failed == 0

    def load_test_cases(self):
        """Load test cases from JSON files"""
        test_cases = []

        for test_file in self.test_dir.glob("**/*.json"):
            with open(test_file) as f:
                test_data = json.load(f)
                if isinstance(test_data, list):
                    test_cases.extend(test_data)
                else:
                    test_cases.append(test_data)

        return test_cases

    def evaluate_policy(self, test_case):
        """Evaluate policy with test input"""
        input_data = json.dumps(test_case["input"])
        query = test_case.get("query", "data.example.allow")

        stdout, stderr = self.run_opa_command([
            "eval", "-d", str(self.policy_dir), 
            "-i", "-", "--format", "json", query
        ])

        if stderr:
            print(f"❌ Evaluation error: {stderr}")
            return None

        try:
            result = json.loads(stdout)
            return result["result"][0]["expressions"][0]["value"]
        except (json.JSONDecodeError, KeyError, IndexError):
            return None

    def generate_coverage_report(self):
        """Generate test coverage report"""
        print("Generating coverage report...")

        stdout, stderr = self.run_opa_command([
            "test", str(self.policy_dir), "--coverage", "--format", "json"
        ])

        if stderr:
            print(f"❌ Coverage generation error: {stderr}")
            return False

        try:
            coverage_data = json.loads(stdout)

            # Save coverage report
            with open("coverage.json", "w") as f:
                json.dump(coverage_data, f, indent=2)

            # Calculate coverage percentage
            if "coverage" in coverage_data:
                covered = coverage_data["coverage"]["covered"]
                not_covered = coverage_data["coverage"]["not_covered"]
                total = covered + not_covered
                percentage = (covered / total * 100) if total > 0 else 0

                print(f"Coverage: {covered}/{total} ({percentage:.1f}%)")

            print("✅ Coverage report generated: coverage.json")
            return True

        except json.JSONDecodeError:
            print(f"❌ Failed to parse coverage data: {stdout}")
            return False

    def run_all_tests(self):
        """Run complete test suite"""
        print("=== OPA Policy Test Suite ===")

        success = True

        # Validate policies
        if not self.validate_policies():
            success = False

        # Run unit tests
        if not self.run_unit_tests():
            success = False

        # Run integration tests
        if not self.run_integration_tests():
            success = False

        # Generate coverage
        if not self.generate_coverage_report():
            success = False

        if success:
            print("\n✅ All tests passed!")
            return 0
        else:
            print("\n❌ Some tests failed!")
            return 1

def main():
    framework = OPATestFramework()
    exit_code = framework.run_all_tests()
    sys.exit(exit_code)

if __name__ == "__main__":
    main()

Policy Monitoring Script

#!/bin/bash
# opa-monitor.sh

set -e

# Configuration
OPA_SERVER="${OPA_SERVER:-http://localhost:8181}"
METRICS_FILE="opa-metrics.json"
ALERT_THRESHOLD_ERRORS="${ALERT_THRESHOLD_ERRORS:-5}"
ALERT_THRESHOLD_LATENCY="${ALERT_THRESHOLD_LATENCY:-1000}"
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-}"

# Function to collect metrics
collect_metrics() {
    echo "Collecting OPA metrics..."

    # Get server metrics
    curl -s "$OPA_SERVER/metrics" > "$METRICS_FILE"

    # Get health status
    health_status=$(curl -s -o /dev/null -w "%{http_code}" "$OPA_SERVER/health")

    # Get policy status
    policies=$(curl -s "$OPA_SERVER/v1/policies" | jq -r 'keys[]')

    echo "Health status: $health_status"
    echo "Loaded policies: $policies"
}

# Function to analyze metrics
analyze_metrics() {
    echo "Analyzing metrics..."

    # Parse metrics (simplified - would need proper Prometheus parsing)
    error_count=$(grep -o 'http_request_duration_seconds_count{code="[45][0-9][0-9]"' "$METRICS_FILE" | wc -l || echo "0")
    avg_latency=$(grep 'http_request_duration_seconds_sum' "$METRICS_FILE" | awk '{sum+=$2} END {print sum/NR}' || echo "0")

    echo "Error count: $error_count"
    echo "Average latency: $avg_latency ms"

    # Check thresholds
    if [ "$error_count" -gt "$ALERT_THRESHOLD_ERRORS" ]; then
        send_alert "High error rate detected: $error_count errors"
    fi

    if [ "$(echo "$avg_latency > $ALERT_THRESHOLD_LATENCY" | bc -l)" -eq 1 ]; then
        send_alert "High latency detected: ${avg_latency}ms"
    fi
}

# Function to send alerts
send_alert() {
    local message="$1"

    echo "🚨 ALERT: $message"

    if [ -n "$SLACK_WEBHOOK_URL" ]; then
        curl -X POST -H 'Content-type: application/json' \
            --data "{
                \"text\": \"OPA Alert: $message\",
                \"color\": \"danger\"
            }" \
            "$SLACK_WEBHOOK_URL"
    fi
}

# Function to test policy evaluation
test_policy_evaluation() {
    echo "Testing policy evaluation..."

    # Test cases
    test_cases='[
        {
            "name": "Allow GET public",
            "input": {"method": "GET", "path": ["public", "data"]},
            "expected": true
        },
        {
            "name": "Deny POST without auth",
            "input": {"method": "POST", "path": ["api", "data"]},
            "expected": false
        }
    ]'

    echo "$test_cases" | jq -c '.[]' | while read -r test_case; do
        name=$(echo "$test_case" | jq -r '.name')
        input=$(echo "$test_case" | jq '.input')
        expected=$(echo "$test_case" | jq '.expected')

        result=$(curl -s -X POST "$OPA_SERVER/v1/data/example/allow" \
            -H "Content-Type: application/json" \
            -d "{\"input\": $input}" | jq '.result')

        if [ "$result" = "$expected" ]; then
            echo "✅ $name"
        else
            echo "❌ $name: expected $expected, got $result"
            send_alert "Policy evaluation test failed: $name"
        fi
    done
}

# Main monitoring loop
main() {
    while true; do
        echo "=== OPA Monitoring - $(date) ==="

        collect_metrics
        analyze_metrics
        test_policy_evaluation

        echo "Monitoring cycle completed. Sleeping for 60 seconds..."
        sleep 60
    done
}

# Run monitoring
main

Troubleshooting

Common Issues

# Server not starting
opa run --server --log-level debug

# Policy evaluation errors
opa eval --explain full -d policy.rego -i input.json "data.example.allow"

# Bundle loading issues
opa run --server --bundle bundle.tar.gz --log-level debug

# Performance issues
opa run --server --set decision_logs.console=true

# Memory issues
opa run --server --set status.console=true

Debugging Policies

# Trace policy execution
opa eval --explain full -d policy.rego -i input.json "data.example.allow"

# Profile policy performance
opa eval --profile -d policy.rego -i input.json "data.example.allow"

# Validate policy syntax
opa parse policy.rego

# Format policies
opa fmt policy.rego

# Test specific rules
opa eval -d policy.rego "data.example.is_admin"

Performance Optimization

# Enable caching
opa run --server --set caching.inter_query_builtin_cache.max_size_bytes=104857600

# Optimize bundle loading
opa run --server --set bundles.example.persist=true

# Configure decision logging
opa run --server --set decision_logs.console=false

# Tune garbage collection
opa run --server --set runtime.gc_percentage=20

Best Practices

Policy Development

  1. Modular Design: Break policies into reusable modules
  2. Clear Naming: Use descriptive names for rules and variables
  3. Documentation: Document policy intent and usage
  4. Testing: Write comprehensive unit and integration tests
  5. Versioning: Version policies and maintain backwards compatibility

Security Guidelines

  1. Principle of Least Privilege: Default deny, explicit allow
  2. Input Validation: Validate all input data
  3. Secure Defaults: Use secure default configurations
  4. Audit Logging: Enable comprehensive audit logging
  5. Regular Reviews: Regularly review and update policies

Performance Optimization

  1. Efficient Queries: Write efficient Rego queries
  2. Caching: Enable appropriate caching strategies
  3. Bundle Optimization: Optimize bundle size and structure
  4. Monitoring: Monitor policy evaluation performance
  5. Resource Limits: Set appropriate resource limits

This comprehensive OPA cheatsheet provides everything needed for professional policy-as-code implementation, from basic usage to advanced automation and integration scenarios.