Policy-as-Code with Open Policy Agent
Overview
This skill enables policy-as-code enforcement using Open Policy Agent (OPA) for compliance validation, security policy enforcement, and configuration auditing. OPA provides a unified framework for policy evaluation across cloud-native environments, Kubernetes, CI/CD pipelines, and infrastructure-as-code.
Use OPA to codify security requirements, compliance controls, and organizational standards as executable policies written in Rego. Automatically validate configurations, prevent misconfigurations, and maintain continuous compliance.
Quick Start
Install OPA
# macOS
brew install opa
# Linux
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
chmod +x opa
# Verify installation
opa version
Basic Policy Evaluation
# Evaluate a policy against input data
opa eval --data policy.rego --input input.json 'data.example.allow'
# Test policies with unit tests
opa test policy.rego policy_test.rego --verbose
# Run OPA server for live policy evaluation
opa run --server --addr localhost:8181
Core Workflow
Step 1: Define Policy Requirements
Identify compliance requirements and security controls to enforce:
- Compliance frameworks (SOC2, PCI-DSS, GDPR, HIPAA, NIST)
- Kubernetes security policies (pod security, RBAC, network policies)
- Infrastructure-as-code policies (Terraform, CloudFormation)
- Application security policies (API authorization, data access)
- Organizational security standards
Step 2: Write OPA Rego Policies
Create policy files in Rego language. Use the provided templates in assets/ for common patterns:
Example: Kubernetes Pod Security Policy
package kubernetes.admission
import future.keywords.contains
import future.keywords.if
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
container.securityContext.privileged == true
msg := sprintf("Privileged containers are not allowed: %v", [container.name])
}
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf("Container must run as non-root: %v", [container.name])
}
Example: Compliance Control Validation (SOC2)
package compliance.soc2
import future.keywords.if
# CC6.1: Logical and physical access controls
deny[msg] {
input.kind == "Deployment"
not input.spec.template.metadata.labels["data-classification"]
msg := "SOC2 CC6.1: All deployments must have data-classification label"
}
# CC6.6: Encryption in transit
deny[msg] {
input.kind == "Service"
input.spec.type == "LoadBalancer"
not input.metadata.annotations["service.beta.kubernetes.io/aws-load-balancer-ssl-cert"]
msg := "SOC2 CC6.6: LoadBalancer services must use SSL/TLS encryption"
}
Step 3: Test Policies with Unit Tests
Write comprehensive tests for policy validation:
package kubernetes.admission_test
import data.kubernetes.admission
test_deny_privileged_container {
input := {
"request": {
"kind": {"kind": "Pod"},
"object": {
"spec": {
"containers": [{
"name": "nginx",
"securityContext": {"privileged": true}
}]
}
}
}
}
count(admission.deny) > 0
}
test_allow_unprivileged_container {
input := {
"request": {
"kind": {"kind": "Pod"},
"object": {
"spec": {
"containers": [{
"name": "nginx",
"securityContext": {"privileged": false, "runAsNonRoot": true}
}]
}
}
}
}
count(admission.deny) == 0
}
Run tests:
opa test . --verbose
Step 4: Evaluate Policies Against Configuration
Use the bundled evaluation script for policy validation:
# Evaluate single file
./scripts/evaluate_policy.py --policy policies/ --input config.yaml
# Evaluate directory of configurations
./scripts/evaluate_policy.py --policy policies/ --input configs/ --recursive
# Output results in JSON format for CI/CD integration
./scripts/evaluate_policy.py --policy policies/ --input config.yaml --format json
Or use OPA directly:
# Evaluate with formatted output
opa eval --data policies/ --input config.yaml --format pretty 'data.compliance.violations'
# Bundle evaluation for complex policies
opa eval --bundle policies.tar.gz --input config.yaml 'data'
Step 5: Integrate with CI/CD Pipelines
Add policy validation to your CI/CD workflow:
GitHub Actions Example:
- name: Validate Policies
uses: open-policy-agent/setup-opa@v2
with:
version: latest
- name: Run Policy Tests
run: opa test policies/ --verbose
- name: Evaluate Configuration
run: |
opa eval --data policies/ --input deployments/ \
--format pretty 'data.compliance.violations' > violations.json
if [ $(jq 'length' violations.json) -gt 0 ]; then
echo "Policy violations detected!"
cat violations.json
exit 1
fi
GitLab CI Example:
policy-validation:
image: openpolicyagent/opa:latest
script:
- opa test policies/ --verbose
- opa eval --data policies/ --input configs/ --format pretty 'data.compliance.violations'
artifacts:
reports:
junit: test-results.xml
Step 6: Deploy as Kubernetes Admission Controller
Enforce policies at cluster level using OPA Gatekeeper:
# Install OPA Gatekeeper
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml
# Apply constraint template
kubectl apply -f assets/k8s-constraint-template.yaml
# Apply constraint
kubectl apply -f assets/k8s-constraint.yaml
# Test admission control
kubectl apply -f test-pod.yaml # Should be denied if violates policy
Step 7: Monitor Policy Compliance
Generate compliance reports using the bundled reporting script:
# Generate compliance report
./scripts/generate_report.py --policy policies/ --audit-logs audit.json --output compliance-report.html
# Export violations for SIEM integration
./scripts/generate_report.py --policy policies/ --audit-logs audit.json --format json --output violations.json
Security Considerations
- Policy Versioning: Store policies in version control with change tracking and approval workflows
- Least Privilege: Grant minimal permissions for policy evaluation - OPA should run with read-only access to configurations
- Sensitive Data: Avoid embedding secrets in policies - use external data sources or encrypted configs
- Audit Logging: Log all policy evaluations, violations, and exceptions for compliance auditing
- Policy Testing: Maintain comprehensive test coverage (>80%) for all policy rules
- Separation of Duties: Separate policy authors from policy enforcers; require peer review for policy changes
- Compliance Mapping: Map policies to specific compliance controls (SOC2 CC6.1, PCI-DSS 8.2.1) for audit traceability
Bundled Resources
Scripts (scripts/)
evaluate_policy.py- Evaluate OPA policies against configuration files with formatted outputgenerate_report.py- Generate compliance reports from policy evaluation resultstest_policies.sh- Run OPA policy unit tests with coverage reporting
References (references/)
rego-patterns.md- Common Rego patterns for security and compliance policiescompliance-frameworks.md- Policy templates mapped to SOC2, PCI-DSS, GDPR, HIPAA controlskubernetes-security.md- Kubernetes security policies and admission control patternsiac-policies.md- Infrastructure-as-code policy validation for Terraform, CloudFormation
Assets (assets/)
- `k8s-pod-securi