Ask OPA before every destructive step.

Evaluate Rego policies on Terraform plans, Kubernetes manifests, IAM changes, and secret rotations as flow tasks. Upload policies from Git with dryRun review. Audit every decision in the execution history. Compile partial evaluations for hot paths. Self-hosted OPA, air-gapped friendly, fully under your control.

Blueprints for OPA orchestration.

Put policy-as-code inline with a workflow engine that listens to releases or schedules, evaluates Rego policies on Terraform plans, Kubernetes manifests, or IAM changes before any write, and chains OPA decisions with Terraform, Kubernetes, and audit reports in one execution. Catch violations before terraform apply lands; SOX/ISO/SOC evidence writes itself.

terraform plan output evaluated by OPA; apply gated on the decision Open blueprint
Pull Rego from Git, run opa test, validate, gate, upload Open blueprint
Pull AWS + K8s + Terraform state, evaluate against compliance policies, report Open blueprint

Around every write, every change, every commit.

OPA evaluates the Rego decisions. Kestra puts those decisions inline in every flow that changes state: before terraform apply, before kubectl.Apply, before IAM key rotation, before opening firewall ports. Policy-as-code stops being a Kubernetes admission webhook only; it becomes a first-class gate in the orchestrator.

policy.Evaluate gates destructive operations

policy.Evaluate calls OPA's Data API at /v1/data/{path} with a JSON input document built from the flow's current context: the Terraform plan output, the Kubernetes manifest, the IAM policy change, the firewall rule mutation. OPA returns a Rego decision; the flow's If task branches on it. Allow continues; deny halts and routes to an errors branch with the violation reasons.

policy.Upload deploys Rego from Git, with dryRun review

policy.Upload PUTs a Rego module to /v1/policies/{id}, overwriting existing content. Chain with git.Clone to fetch the policy repo at flow runtime, opa test for unit tests, then push to OPA on green. A Pause task between validate and push lets a reviewer inspect changes that affect prod policies. The Rego file in Git is the source of truth.

policy.List reconciles loaded modules with Git

policy.List returns every policy module on the OPA server. A weekly reconciliation flow diffs the result against the Rego files in Git. Modules in OPA but not in Git get flagged for removal. Modules in Git but not in OPA fire policy.Upload. The OPA bundle stays in sync with declared intent, with drift surfaced as Slack alerts.

policy.Compile for partial evaluation in hot paths

policy.Compile uses OPA's Compile API to partially evaluate a Rego query, returning residual queries. Use when most of the logic can be pre-computed and only one runtime value changes per evaluation. The hot-path flow evaluates the residual only, cutting latency for high-frequency gating like per-request authorization or per-row data classification.

Decision audit linked to flow execution

Each policy.Evaluate response includes a decision_id when OPA's decision logging is enabled. The Kestra execution history records the decision_id alongside the input document and the result. Auditors can trace a policy decision from the OPA decision log back to the Kestra flow that triggered it, the inputs that produced it, and what ran afterward. SOX, ISO 27001, and SOC 2 evidence written automatically.

Gate writes, not reads

Put policy.Evaluate before every task that creates, updates, or deletes state: terraform apply, kubectl.Apply, aws.iam mutations, NetBox device.Create, Cloudflare dns.records.Upsert. Reads (Get, List, Query) skip the gate. Latency overhead lands only on operations that actually change the world, and every state change is recorded as a policy decision.

How platform and security teams use OPA and Kestra

Patterns engineering teams run in production today. Each one shows the flow end to end, with the real plugin classes in play.

Pre-apply gate

Evaluate the terraform plan against OPA before apply runs

terraform plan runs and captures the JSON output. policy.Evaluate sends the plan as input to OPA's terraform/deny policy. OPA returns the violations array; if empty, the flow proceeds to terraform apply. If not, the flow halts and the errors branch posts the violation reasons to Slack with the plan attached. Compliance enforcement happens before the infrastructure changes land, not after.

Plan never sees prod if it violates policy

The apply task is gated by an If on the policy decision. A bad plan halts the flow before terraform touches state.

Violations route to the right channel

OPA's violation array names the offending resource. The Slack message includes the resource and the rule that fired, with a link to the policy in the repo.

Decision ID linked to the execution

The OPA decision_id is recorded in the Kestra output. Auditors trace from decision log to plan to flow to reviewer.

Reusable across environments

Same flow pattern for dev / staging / prod. The policy path or input shape differs per environment, the gate logic stays identical.

release trigger
manual or schedule
terraform plan
JSON output
evaluate policy
OPA terraform/deny
decision branch
If violations
apply or halt
with decision_id logged
audit slack
violation details if any
K8s gate

Validate Kubernetes manifests with OPA before kubectl apply

Before kubectl.Apply, policy.Evaluate runs the manifest through OPA's kubernetes/admission policy. OPA returns allow plus a violations list. If allowed, the flow applies. If denied, the flow stops and the errors branch opens a GitHub issue with the violation reasons attached. Pattern works for clusters where you cannot install an admission webhook (managed K8s, customer tenant clusters, multi-cloud), using the same Rego you would use server-side.

Works without an admission webhook

For clusters where you cannot install OPA Gatekeeper or a Validating Admission Webhook, run the same Rego policy in the flow.

Reuses your existing Rego

The same kubernetes/admission policy that would run server-side runs here. No policy fork, no duplicate logic.

Failure produces a structured GitHub issue

The errors branch opens an issue with the violations array, the manifest excerpt, and the execution URL.

release trigger
manual or webhook
load manifest
from Git or input
OPA admission
policy.Evaluate
branch on allow
If allow
kubectl apply
if allow
open issue
if deny
Policy lifecycle

Pull Rego from Git, unit-test, dryRun gate, push to OPA

Weekly policy sync flow. git.Clone pulls the policy repo at the main branch. A Shell task runs opa test for unit tests. policy.Compile validates each policy parses cleanly. A Pause task gates on the diff between current OPA state (policy.List) and the Git state. After approval, policy.Upload deploys the updated modules. Failed unit tests stop the flow before any change reaches OPA.

Tests gate every deploy

opa test runs the Rego unit tests. Failures halt the flow before policy.Upload fires.

Compile catches parse errors early

policy.Compile validates each module parses cleanly. Syntax errors never reach the live OPA server.

Human gate before prod-policy changes

The Pause task surfaces the diff between current OPA state and the Git source. A reviewer approves before changes apply.

weekly schedule
cron
clone policy repo
Git source of truth
opa test
unit tests
validate parse
policy.Compile
list current
policy.List
diff review
Pause for approval
upload to OPA
policy.Upload
notify
Slack with modules
Audit

Cross-stack daily compliance audit

A scheduled audit flow pulls current state from each stack: aws.cloudformation.Get for stack outputs, kubectl.Get for K8s resources, terraform state list outputs, NetBox device.List for the inventory. For each, policy.Evaluate runs the compliance rules. Violations are aggregated into a Slack-friendly daily report. The report links to OPA decision IDs and to the affected resources. Compliance posture becomes a continuous signal, not a quarterly audit drill.

Same policies, multiple sources

The Rego policy library covers AWS, Kubernetes, Terraform state, and NetBox inventory. One policy set, many evaluations.

Daily signal, not quarterly audit

Violations land in Slack within 24 hours. Auditors see a continuous compliance posture, not a frozen point-in-time snapshot.

Decision IDs link to OPA decision log

Every violation in the report includes the OPA decision_id, so investigators trace from the report row to the policy, to the input, to the flow.

daily schedule
off-hours
pull aws state
cloudformation, IAM
pull k8s state
kubectl.Get
pull terraform
state list
evaluate per stack
policy.Evaluate
aggregate report
violations rolled up
post to slack
with decision IDs

Kestra vs OPA orchestration alternatives

Capability
OPA admission webhook (K8s only)
conftest in CI scripts
Custom OPA HTTP client in CI
Evaluate before terraform apply, kubectl, IAM changes
policy.Evaluate as a flow task before any write
K8s only, not Terraform or IAMRun in CI, no runtime gateCustom code per gate
Upload Rego from Git with dryRun review
git.Clone + policy.Compile + Pause + policy.Upload
Helm or ConfigMap mounts, manual reviewNot in scopeCustom upload logic
Reconcile loaded modules with declared Git state
policy.List + diff + Upload/Delete
ManualNot in scopeCustom reconcile loop
Partial evaluation for hot paths
policy.Compile returns residual queries
Not exposedNot in scopeCustom HTTP client
Decision audit linked to flow execution
decisionId recorded with execution outputs
OPA decision log only, no flow correlationCI run log onlyCustom correlation
Same policies gate Terraform, K8s, IAM, NetBox
One policy library, many evaluations
K8s admission onlyCI checks per repoCustom per integration
Cross-stack daily compliance audit
One flow pulls state from each stack, evaluates, reports
Not in scope (admission, not audit)Not in scope (CI, not runtime)Custom orchestration
Self-hosted, air-gapped
Self-hosted Kestra calls self-hosted OPA
Self-hostedSelf-hostedSelf-hosted

OPA & Kestra: common questions

Find answers to your questions right here, and don't hesitate to Contact Us if you couldn't find what you're looking for.

See How

Ready to ask OPA before every destructive step?

Gate Terraform applies, kubectl applies, IAM changes, and Cloudflare mutations on Rego policy decisions. Deploy policies from Git with dryRun review. Audit every decision in execution history. Cross-stack compliance as a continuous signal. Open source, self-hosted Kestra calls self-hosted OPA.