Agent skill
policy-runner
Run policy-as-code checks (e.g., OPA/Conftest) based on the policy_plan. Use in Flow 2 and Flow 4.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/policy-runner
SKILL.md
Policy Runner Skill
Run policy-as-code checks against plan artifacts, code, and configurations. This skill executes OPA/Conftest/Rego policies and produces structured evidence for compliance verification.
Purpose
Policy-as-code transforms governance rules from documentation into executable checks. Instead of "the security team reviews PRs," you get "the policy runner verifies authentication requirements are met."
What this skill does:
- Execute policy checks defined in
policy_plan.md - Run OPA/Conftest against target files
- Produce structured pass/fail evidence
- Generate summaries for downstream agents (policy-analyst)
What this skill does not do:
- Grant waivers or exceptions
- Modify policy files
- Make compliance judgments (that's policy-analyst's job)
- Post to GitHub
When to Use
| Flow | Purpose |
|---|---|
| Flow 2 (Plan) | Validate contracts/ADR against architectural policies |
| Flow 4 (Review) | Re-check policies after implementation changes |
| Flow 5 (Gate) | Final policy verification before merge decision |
The skill is typically invoked by:
policy-analystagent (for compliance mapping)- Flow orchestrators (as a verification step)
Policy-as-Code Concepts
OPA (Open Policy Agent)
OPA is a general-purpose policy engine. Policies are written in Rego, a declarative query language.
# example: require auth on all endpoints
package api.security
default allow = false
allow {
input.endpoint.auth_required == true
}
deny[msg] {
not input.endpoint.auth_required
msg := sprintf("Endpoint %v requires authentication", [input.endpoint.path])
}
Conftest
Conftest is a tool for testing structured data (YAML, JSON, HCL) against OPA policies. It's commonly used for:
- Kubernetes manifests
- Terraform plans
- CI/CD configurations
- API contracts
# Run conftest against API contracts
conftest test api_contracts.yaml -p policies/api/
Rego
The policy language for OPA. Key concepts:
- Rules define what's allowed/denied
- Input is the data being evaluated (e.g., your YAML files)
- Packages organize rules by domain
- Deny rules produce violations with messages
Invocation
Always invoke via the shim when available:
bash .claude/scripts/demoswarm.sh policy <command> [options]
If the shim doesn't support policy commands, fall back to direct tool invocation:
conftest test <path> -p <policy-dir> --output json
opa eval --data <policy.rego> --input <target.json> "data.policy.deny"
Operating Invariants
Repo root only
- Assume working directory is repo root.
- All paths are repo-root-relative.
Read-only execution
- Do not modify policy files or targets.
- Do not grant waivers.
Evidence capture
- Save raw output to
policy_runner_output.log. - Write structured summary to
policy_runner_summary.md.
Null over guess
- If policies aren't configured: report "no policies wired"
- If tool errors: capture the error, don't fabricate results
Configuration
Policy Plan (policy_plan.md)
The policy_plan.md file defines which policies to run. Located at:
.runs/<run-id>/plan/policy_plan.md(run-specific)policies/policy_plan.md(repo default)
Format:
# Policy Plan
## Active Policies
| Policy | Target | Command | Required |
| ------------------ | ------------------ | ------------------------------------------ | -------- |
| api-security | api_contracts.yaml | conftest test {target} -p policies/api/ | yes |
| data-retention | schema.md | opa eval -d policies/data/retention.rego | no |
| naming-conventions | \*.yaml | conftest test {target} -p policies/naming/ | yes |
## Policy Roots
- policies/
- .policies/
Policy Directory Structure
policies/
api/
security.rego # Auth requirements
versioning.rego # API versioning rules
data/
retention.rego # Data retention rules
pii.rego # PII handling rules
naming/
conventions.rego # Naming standards
conftest.toml # Conftest configuration
Conftest Configuration (conftest.toml)
# policies/conftest.toml
policy = ["policies/"]
output = "json"
Commands
Run All Configured Policies
# If policy_plan.md exists, run all configured checks
bash .claude/scripts/demoswarm.sh policy run \
--plan ".runs/feat-auth/plan/policy_plan.md" \
--output ".runs/feat-auth/plan/policy_runner_output.log"
Run Specific Policy
# Run a single named policy
conftest test .runs/feat-auth/plan/api_contracts.yaml \
-p policies/api/ \
--output json
Check Policy Setup
# Verify policies are configured
bash .claude/scripts/demoswarm.sh policy check-setup
# stdout: CONFIGURED | NOT_CONFIGURED | PARTIAL
Example Commands
API Contract Validation
# Validate API contracts against security policies
conftest test .runs/feat-auth/plan/api_contracts.yaml \
-p policies/api/security.rego \
--output json
# Example output (pass):
# []
# Example output (fail):
# [
# {
# "filename": "api_contracts.yaml",
# "failures": [
# {"msg": "Endpoint /users requires authentication"}
# ]
# }
# ]
Schema Validation
# Validate data models against retention policies
opa eval \
--data policies/data/retention.rego \
--input .runs/feat-auth/plan/schema.json \
"data.retention.deny" \
--format pretty
# Example output (pass):
# []
# Example output (fail):
# [
# "Field 'email' in User model must have retention period defined"
# ]
Kubernetes Manifest Check
# Validate k8s manifests (if applicable)
conftest test k8s/*.yaml \
-p policies/k8s/ \
--output json
ADR Decision Validation
# Check ADR against architectural policies
conftest test .runs/feat-auth/plan/adr.md \
-p policies/architecture/ \
--parser yaml \
--output json
Behavior
-
Read
policy_plan.md(if it exists) to discover which policies and paths to evaluate. -
For each configured policy entry:
- If an explicit command is listed (e.g.,
conftest test <path>oropa eval ...), run it. - Otherwise, if a policy file/rego path is provided, return a message that this policy is planned but not auto-executed.
- If an explicit command is listed (e.g.,
-
Capture output:
- Save raw runner output to
policy_runner_output.log. - Write
policy_runner_summary.mdsummarizing checks run, passed, failed, and planned-only policies.
- Save raw runner output to
-
Do not modify policy files or code.
Output Artifacts
policy_runner_output.log
Raw output from all policy executions:
=== Policy: api-security ===
Command: conftest test api_contracts.yaml -p policies/api/
Exit code: 0
Output:
[]
=== Policy: data-retention ===
Command: opa eval -d policies/data/retention.rego ...
Exit code: 1
Output:
["Field 'email' in User model must have retention period defined"]
policy_runner_summary.md
# Policy Runner Summary
## Execution Context
- Run ID: feat-auth
- Timestamp: 2025-12-12T10:30:00Z
- Policy Plan: .runs/feat-auth/plan/policy_plan.md
## Results
| Policy | Target | Status | Violations |
| ------------------ | ------------------ | ------ | ---------- |
| api-security | api_contracts.yaml | PASS | 0 |
| data-retention | schema.md | FAIL | 1 |
| naming-conventions | \*.yaml | PASS | 0 |
## Violations Detail
### data-retention (FAIL)
- Target: schema.md
- Violation: Field 'email' in User model must have retention period defined
- Policy file: policies/data/retention.rego:L42
## Planned Only (Not Executed)
- pii-classification: No auto-execute command configured
## Summary
- Total policies: 4
- Executed: 3
- Passed: 2
- Failed: 1
- Planned only: 1
Common Failure Modes
No Policies Configured
Symptom: "No policy checks wired for this change"
Resolution:
- Create
policies/directory with Rego files - Create
policy_plan.mdwith policy-to-target mappings - Or: acknowledge no policy-as-code is configured (valid state)
Tool Not Installed
Symptom: conftest: command not found or opa: command not found
Resolution:
# Install conftest
brew install conftest # macOS
# or download from: https://github.com/open-policy-agent/conftest/releases
# Install OPA
brew install opa # macOS
# or download from: https://www.openpolicyagent.org/docs/latest/#running-opa
Policy Parse Error
Symptom: Rego syntax errors in output
Resolution:
- Check Rego syntax in the failing policy file
- Run
opa check policies/*.regoto validate syntax - Fix syntax errors before re-running
Target File Not Found
Symptom: error: file not found: api_contracts.yaml
Resolution:
- Verify the target file exists at the specified path
- Check if
policy_plan.mdreferences the correct location - Ensure upstream agents (interface-designer) have run
Policy Logic Error
Symptom: Unexpected failures or passes
Resolution:
- Test policy in isolation:
opa eval --data policy.rego --input test.json "data.policy.deny" - Add trace output:
opa eval ... --explain full - Review Rego logic for edge cases
Integration with policy-analyst
The policy-analyst agent uses policy-runner output to:
- Map policy requirements to evidence
- Classify violations by severity
- Determine compliance status
- Recommend routing (fix vs waive vs proceed)
Flow:
policy-runner (execute)
|
v
policy_runner_summary.md
|
v
policy-analyst (interpret)
|
v
policy_analysis.md (compliance register)
The skill executes; the agent interprets. Keep these concerns separate.
Example Policy Rules
Require Authentication
# policies/api/security.rego
package api.security
deny[msg] {
endpoint := input.paths[path][method]
not endpoint.security
msg := sprintf("Endpoint %v %v must have security defined", [upper(method), path])
}
Require Versioning
# policies/api/versioning.rego
package api.versioning
deny[msg] {
not input.info.version
msg := "API must have version defined in info block"
}
deny[msg] {
path := input.paths[p]
not startswith(p, "/v")
msg := sprintf("Path %v must be versioned (e.g., /v1/...)", [p])
}
PII Field Encryption
# policies/data/pii.rego
package data.pii
pii_fields := ["email", "phone", "ssn", "address"]
deny[msg] {
field := input.models[model].fields[f]
field.name == pii_fields[_]
not field.encrypted
msg := sprintf("PII field %v.%v must be encrypted", [model, field.name])
}
Naming Conventions
# policies/naming/conventions.rego
package naming
deny[msg] {
endpoint := input.paths[path]
not regex.match(`^/[a-z][a-z0-9-]*(/[a-z][a-z0-9-]*)*$`, path)
msg := sprintf("Path %v must use kebab-case", [path])
}
Troubleshooting
Debug Mode
# Run with verbose output
conftest test target.yaml -p policies/ --trace
# OPA with full explanation
opa eval --data policy.rego --input target.json "data.policy.deny" --explain full
Test Policy in Isolation
# Create test input
echo '{"endpoint": {"path": "/users", "auth_required": false}}' > test_input.json
# Run policy against test input
opa eval --data policies/api/security.rego --input test_input.json "data.api.security.deny"
Validate Rego Syntax
# Check all policies for syntax errors
opa check policies/**/*.rego
# Format Rego files
opa fmt -w policies/
For Agent Authors
When using policy-runner in agents:
- Check for policy_plan.md first — If missing, report "no policies configured" and proceed
- Capture all output — Save to
policy_runner_output.logfor audit trail - Don't fabricate results — If tools fail, report the failure
- Let policy-analyst interpret — The skill runs checks; the agent decides meaning
- Trust exit codes —
0= pass, non-zero = fail or error
Example pattern in agent code:
# Check if policies are configured
if [[ -f ".runs/${RUN_ID}/plan/policy_plan.md" ]]; then
# Run policies
conftest test .runs/${RUN_ID}/plan/api_contracts.yaml \
-p policies/api/ \
--output json > .runs/${RUN_ID}/plan/policy_runner_output.log 2>&1
EXIT_CODE=$?
if [[ $EXIT_CODE -eq 0 ]]; then
echo "PASS"
else
echo "FAIL"
fi
else
echo "No policies configured for this run"
fi
Installation
Conftest
# macOS
brew install conftest
# Linux
wget https://github.com/open-policy-agent/conftest/releases/download/v0.48.0/conftest_0.48.0_Linux_x86_64.tar.gz
tar xzf conftest_0.48.0_Linux_x86_64.tar.gz
sudo mv conftest /usr/local/bin/
# Windows (scoop)
scoop install conftest
OPA
# macOS
brew install opa
# Linux
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
chmod +x opa
sudo mv opa /usr/local/bin/
# Windows (scoop)
scoop install opa
Verify Installation
conftest --version
opa version
See Also
- policy-analyst.md — Agent that interprets policy results
- flow-2-plan.md — Flow where policies are first checked
- verification-stack.md — Where policy fits in verification
- customize-pack.md — How to configure policies for your repo
Didn't find tool you were looking for?