30 August 2026

8 Policy as Code Examples for Secure Delivery

Reza Khosravi
No items found.

Table of Contents

8 Policy as Code Examples for Secure Delivery

Policy as code is already a production practice, not a speculative cloud trend. In a May 2023 U.S. survey of 285 developers and technical decision-makers, 87% said their organizations used policy as code in production, while only 30% used it at significant capacity across most or all systems (Styra's 2023 State of Policy as Code report). The useful question, then, isn't whether to encode policy. It's where each rule should make a delivery decision.

Policy works best when it turns security intent into an observable result inside an existing workflow, not when it creates another detached compliance document. The eight policy as code examples below map controls to pull requests, infrastructure plans, clusters, GitOps reconciliation, code analysis, dependency management, and continuous cloud monitoring. Each example separates preventive blocking from detective feedback, identifies the policy boundary, and shows how to start in audit mode before enforcing high-impact controls.

1. OPA and Rego

Open Policy Agent, or OPA, is a strong fit when one policy engine needs to evaluate different kinds of decisions. Teams can keep authorization, infrastructure, Kubernetes, and delivery rules separate from application code, then version, test, review, and reuse those rules through normal engineering workflows.

OPA's history helps explain why it remains one of the most practical policy as code examples. The Cloud Native Computing Foundation accepted OPA on March 29, 2018, moved it to Incubating on April 2, 2019, and graduated it on January 29, 2021, according to the CNCF milestone history summarized by InfoQ. That cloud-native maturity makes OPA useful across Kubernetes admission, Terraform plans, API gateways, and CI pipelines.

Define the boundary before writing Rego

A policy should answer one decision clearly. For example, “a production workload must use an approved image registry” belongs at the deployment or admission boundary. “A service may access a particular customer record” belongs at an authorization boundary. Combining both into one opaque rule makes ownership and troubleshooting harder.

A practical OPA rollout looks like this:

  • Start with high-impact controls: Prioritize image provenance, network egress, sensitive data residency, or encryption requirements rather than encoding every preference at once.
  • Test known outcomes: Use OPA's test framework with both acceptable and unacceptable inputs, so a policy change can reveal unintended behavior before release.
  • Use decision logs: Preserve the input, result, and policy version needed to explain why a request was allowed or rejected.
  • Begin in audit mode: Observe violations in pull requests or staging, refine the rule, then switch to enforcement when the signal is reliable.

Practical rule: A blocked deployment should identify the violated requirement and the evidence that triggered it. “Policy failed” isn't remediation guidance.

OPA becomes especially valuable when design context matters. A generic rule can reject an unencrypted database, but a context-aware control can distinguish a production system handling regulated data from a disposable local environment. Teams can connect OPA evaluations to repository changes and approved architecture decisions through policy as code tooling guidance, keeping enforcement closer to the reason the policy exists.

A comparison chart showing the benefits of using Policy as Code with OPA versus manual approaches.

2. Terraform Sentinel

Terraform Sentinel belongs at the infrastructure plan boundary. It evaluates the proposed resources before Terraform provisions them, which makes it a preventive control for encryption, regions, network exposure, tagging, and approved platform usage.

The distinction from a post-deployment scanner is important. A CSPM tool can discover a public storage bucket after creation. Sentinel can stop the plan that would create it, provided the resource is represented in the Terraform workflow and the policy evaluates the relevant plan data.

Make plan review more than a security veto

A useful Sentinel rule has three parts: the condition, the reason, and the exception path. “Databases must use encryption at rest” is clearer when the policy also identifies the architectural or regulatory requirement behind it. A team may permit a narrowly defined exception for a test fixture, but that exception should be visible in the plan review rather than hidden in an informal message.

Common controls include:

  • Approved regions: Reject resources that would store regulated information outside authorized locations.
  • Encryption settings: Block databases, storage, or transport configurations that don't meet the service requirement.
  • Public exposure: Prevent public buckets, open security groups, or unrestricted network paths where the design doesn't permit them.
  • Ownership metadata: Require tags or labels that support accountability, operations, and cost allocation.

Use Sentinel's soft-mandatory approach during rollout to collect violations without immediately stopping every plan. That period gives platform and application teams time to identify legitimate patterns, correct modules, and improve error messages. Once the policy reflects actual architecture, hard enforcement can begin for the controls with clear risk and low ambiguity.

A policy that blocks a valid migration without explaining the approved path will push engineers toward workarounds instead of safer infrastructure.

Run policy tests in the same CI workflow that validates Terraform formatting and plans. Review violations by module and service, not only as a security backlog. Repeated findings often indicate a flawed shared module or missing secure default, not individual developer carelessness.

A hand-drawn illustration showing cloud infrastructure security, policy enforcement, and compliance approval processes for modern IT systems.

3. GitHub Branch Protection Rules

Branch protection turns repository governance into a merge decision. Instead of asking a reviewer to remember whether security checks ran, the repository can require successful status checks, designated approvals, and controlled deployment paths before a protected branch accepts a change.

This is one of the most direct policy as code examples because the policy boundary is the pull request itself. GitHub branch protection can require automated checks, while GitHub Actions can run custom logic for SAST, dependency scanning, signed artifacts, change classification, or design-review alignment.

Keep merge gates understandable

A large collection of required checks creates friction when nobody knows which check failed or why it matters. Group related results into a clearly named workflow where appropriate, then make the failure message actionable. A pull request should show whether the issue concerns a hardcoded secret, an unreviewed production change, a missing approval, or a policy exception.

Effective repository controls include:

  • Required security checks: Require the relevant SAST, DAST, secret detection, and dependency workflows before merge.
  • Protected production branches: Restrict direct pushes and require the review path defined by the team's release model.
  • Signed change controls: Use signed commits or equivalent verification where provenance is part of the repository's security requirement.
  • Synchronized governance: Manage rules through the GitHub API when many repositories must follow a common baseline.

The important trade-off is central consistency versus local context. A financial service repository may need a stricter production approval rule than a documentation repository. Apply a shared baseline, but allow the policy to inspect repository classification, deployment target, data sensitivity, and approved architectural decisions before blocking.

Review branch rules regularly. A required check that no longer runs, produces noisy findings, or duplicates another control becomes a ritual rather than protection. Store the policy rationale in contributing guidance and security policy files so developers can understand the contract without opening a separate ticket.

4. Kubernetes Network Policies and Pod Security Standards

Kubernetes network policies and Pod Security Standards protect the cluster boundary, where workloads become runtime actors. NetworkPolicy controls which pods may communicate and which traffic paths are permitted. Pod security controls constrain risky runtime behavior, such as privileged containers or unsafe security contexts.

The preventive point is admission for workload configuration, followed by network enforcement during runtime. A manifest can pass a source review and still create an unintended connection. Conversely, a network rule can't fix a pod that was admitted with excessive privileges. These controls work together because they address different parts of the attack surface.

Start with explicit communication

A deny-by-default posture can reduce accidental reachability, but it requires a reliable inventory of legitimate traffic. Apply it first in development or staging, observe blocked flows, and add narrowly scoped allowances. Namespace labels, pod selectors, and clearly named services are easier to reason about than broad CIDR ranges or unrestricted namespace access.

Consider these scenarios:

  • Payment workloads: Permit only the service paths required for payment processing, rather than allowing broad namespace connectivity.
  • Patient data services: Separate sensitive data pods from public-facing APIs and make the permitted intermediary path explicit.
  • Media platforms: Restrict outbound connections where a workload has no business reason to contact external destinations.
  • Shared clusters: Block privileged execution and require safer alternatives for debugging or host-level operations.

Network policy visibility matters because a technically correct rule can still break an undocumented dependency. Tools such as Cilium and Calico can help teams inspect and visualize traffic, while logs reveal which denied connections represent real application behavior.

“Deny all” is a starting posture, not a finished policy. The allow rules must reflect the approved service design.

Combine native Pod Security Standards with OPA or another admission policy engine when the organization needs custom requirements, such as approved image registries, required labels, or environment-specific exceptions. Keep the rule close to the workload boundary, and connect exceptions to an owner and an explicit expiration or review process.

5. Cloud Security Posture Management Policy Frameworks

CSPM policy frameworks are detective controls with a continuous view of cloud accounts. Tools such as Prisma Cloud, Wiz, and CloudSploit can evaluate cloud resources against customizable security and compliance rules, identify drift, and route findings for remediation.

CSPM becomes most useful when the control surface extends beyond infrastructure repositories. A console change, a manually created resource, or an inherited cloud configuration may bypass Terraform and GitHub protection. Continuous evaluation can discover that state, even though it can't replace preventive checks at the point of change.

Separate discovery from enforcement

Use CSPM to find exposure and to verify that preventive controls are working. For example, Terraform Sentinel may block a public bucket in the normal provisioning path, while CSPM detects a bucket made through a separate administrative route. The two controls answer different questions, so removing one because the other exists leaves a gap.

Prioritize findings by risk and actionability:

  • High-impact exposure: Focus first on public access, missing encryption, excessive permissions, and sensitive data exposure.
  • Automated low-risk repair: Consider automatic remediation for repeatable settings such as logging enablement, but preserve approval for changes that can affect availability or access.
  • Policy tuning: Review false positives and legitimate exceptions regularly, then update the rule or the resource classification.
  • Operational ownership: Route each finding to the team that can change the resource, not only to a central security queue.

CSPM findings should appear in engineering dashboards and delivery workflows where possible. A finding that arrives only as a periodic report encourages backlog accumulation. A finding linked to the resource owner, recent change, relevant design decision, and remediation path creates a more useful feedback loop.

Teams that need to connect posture findings with broader application security context can evaluate application security posture practices. The key is to treat CSPM as one layer in a defense-in-depth system, not as permission to skip plan-time and merge-time enforcement.

6. GitOps and Policy-Driven Deployment

GitOps makes the repository the declared source of production state, while ArgoCD or Flux continuously reconciles that desired state with the cluster. This model creates a strong audit boundary because a deployment should correspond to a reviewed Git change, not an untracked command executed directly against production.

The policy decision can happen before merge, during admission, and during reconciliation. Pull request checks catch errors early. OPA, Kyverno, or another admission layer provides a final guard against non-compliant resources. ArgoCD or Flux then applies only the approved desired state and reports when the live environment diverges.

Protect the source of truth

GitOps security depends on repository controls. Strong role-based access control, protected branches, review requirements, and separate ownership for application manifests and platform policies reduce the chance that one change can weaken the environment.

A practical arrangement might include:

  • Policy repositories: Store shared guardrails with restricted write access and dedicated review ownership.
  • Application repositories: Let service teams propose workload changes while automated checks evaluate the policy boundary.
  • Environment overlays: Keep production-specific requirements visible in Kustomize overlays or Helm values instead of embedding them in undocumented pipeline logic.
  • Admission verification: Recheck image signatures, required labels, network settings, and security contexts immediately before acceptance.
  • Change notifications: Alert platform and security teams when reconciliation fails or a policy violation appears.

The trade-off is speed versus central control. A single global policy repository can simplify governance but may slow local changes. Separate repositories can improve ownership and review clarity, but they require dependable versioning and compatibility testing.

Run policy tests before merging changes into the GitOps source. If a workload needs an exception, encode the reason and approval in the change record. That makes the deployment decision reproducible rather than dependent on a private conversation.

7. SAST Policies in CI/CD

SAST policies evaluate source code before it becomes a merged artifact. They can detect hardcoded secrets, unsafe input handling, weak cryptography, and other patterns, then decide whether to provide feedback, require review, or block the pull request.

The most effective SAST enforcement doesn't treat every finding as equally urgent. A high-confidence secret detection rule deserves a different response from a complex data-flow warning that may require application context. Blocking everything immediately trains developers to suppress findings or bypass the scanner.

Build a signal-based merge policy

Start with rules that are easy to understand and remediate. A pull request comment should identify the file, the relevant code path, the risk, and the accepted fix. IDE integrations can surface the same issue before a developer opens a pull request, while CI remains the authoritative gate.

Useful policy distinctions include:

  • Immediate blocking: Use for high-confidence secrets and severe findings with a clear remediation path.
  • Review required: Escalate ambiguous or context-dependent findings to a security owner rather than stopping every merge automatically.
  • Audit feedback: Record lower-confidence patterns and use recurring results to improve coding guidance.
  • Suppression governance: Require a reason and ownership for suppressed findings, then review suppressions for patterns.

SAST also benefits from design context. A rule against direct handling of sensitive data may be appropriate for one service and unnecessary for another, depending on its approved architecture. If the policy understands data flows, trust boundaries, and required logging, it can avoid treating every use of a sensitive field as an identical violation.

For teams working primarily in JavaScript and TypeScript, JavaScript static analysis guidance can complement scanner configuration. The objective isn't to maximize finding volume. It's to prevent unsafe code from crossing the merge boundary while giving developers feedback early enough to act.

8. SCA and Dependency Policies

Software composition analysis applies policy to the components an application imports, including direct and transitive dependencies. SCA tools such as Snyk, Dependabot, and Black Duck can evaluate known vulnerabilities, dependency age, and license constraints in pull requests and CI pipelines.

Dependency policy has two separate boundaries. License compatibility belongs to the organization's legal and distribution model. Vulnerability handling belongs to security risk and exploitability. A single rule that blocks every outdated package or every unfamiliar license will create noise and encourage exceptions without improving decisions.

Set thresholds that match the release context

Critical or high-severity vulnerabilities may justify blocking when the affected component is reachable and the fix is available. Lower-severity findings may produce feedback while the team schedules remediation. The policy should also account for whether the dependency runs in production, handles sensitive data, or sits behind a compensating control.

A workable dependency policy can include:

  • Vulnerability severity: Block findings that meet the organization's defined risk threshold, with an explicit exception process.
  • Reachability and exposure: Give more weight to components used by exposed services than to development-only packages.
  • Transitive dependencies: Inspect the full dependency tree, since indirect components can introduce risk without appearing in the manifest.
  • License compatibility: Match permitted licenses to the company's distribution and commercial requirements.
  • Update behavior: Prioritize security fixes and review automated update pull requests for breaking changes.

The best enforcement point is the pull request, where the dependency change is visible and reversible. Keep the finding attached to the exact package version and lockfile change, then show the upgrade path or approved mitigation. Continuous rescanning still matters because a previously acceptable dependency can later receive a vulnerability disclosure.

Avoid using age alone as a blocking criterion. Old code isn't automatically unsafe, and a recent version can still create operational or compatibility risk. Combine package metadata with application context, exposure, and the approved security design so dependency policy supports delivery decisions instead of producing an undifferentiated queue.

Policy-as-Code: 8-Example Comparison

Tool🔄 Implementation complexity⚡ Resource requirements📊 Expected outcomes💡 Ideal use cases⭐ Key advantages
OPA/Rego (Open Policy Agent)High, learn Rego; author & test declarative rulesModerate–High, OPA service, integrations, maintainersCentralized, fine-grained enforcement; audit-ready decision logsCross-domain policy enforcement; admission-time blocking; compliance automationFlexible policy-as-code; strong auditability and CI validation
Terraform SentinelMedium, Sentinel language + Terraform Cloud setupRequires Terraform Cloud/Enterprise; policy maintenancePrevent non-compliant infra at plan stage; clear audit trailsTerraform-centric infra policy checks and pre-provision controlsPlan-time enforcement; soft/hard modes; integrates with Terraform workflow
GitHub Branch Protection RulesLow–Medium, native settings; Actions for custom logicMinimal–Moderate, GitHub features; optional Enterprise for advancedImmediate PR feedback; merge-time blocking; visible audit logsRepo-level CI checks, code-review enforcement, developer-facing policiesNative to developer workflow; fast adoption; integrates with Actions
Kubernetes Network Policies & Pod Security StandardsMedium–High, requires Kubernetes networking and security knowledgeCluster-native; may need advanced CNI (Calico/Cilium) for visibilityRuntime isolation; reduced lateral movement; cluster-level enforcementKubernetes workloads needing network segmentation and pod hardeningNative, manifest-driven policies; GitOps-friendly; no extra platform required
CSPM Policy Frameworks (Prisma/Wiz/etc.)Low–Medium, pre-built rules; customization advisedHigh, SaaS licenses, multi-cloud scanning, remediation workflowsContinuous detection of misconfigs; compliance reporting; risk scoringMulti-cloud environments and compliance-driven organizationsPre-built benchmarks; scalable continuous monitoring; automated remediation
GitOps & Policy-Driven Deployment (ArgoCD, Flux)Medium, Git workflows, operators, and policy integrationModerate, GitOps platform, repo management, operatorsDeclarative, versioned deployments; automated reconciliation and rollbackMulti-cluster consistency, auditability, and policy-as-code workflowsSingle source of truth; version-controlled policies; automated reconciliation
SAST Policies in CI/CDLow–Medium, integrate scanners and tune rulesVariable, tool licenses, CI compute, rule maintenanceEarly detection of code vulnerabilities; shift-left remediation; audit logsApp teams needing code-level security checks and compliance evidenceDeveloper feedback in PRs; blocks risky code; tailored rule sets
SCA & Dependency Policies (Snyk/Dependabot/etc.)Low–Medium, integrate scanners; set thresholdsVariable, tooling, PR/merge workflow handlingReduced supply-chain risk; automated updates; license complianceLarge dependency surfaces; supply-chain and license risk managementContinuous CVE detection; transitive scanning; automated dependency PRs

Turn Examples Into an Enforcement Strategy

These policy as code examples work because each rule has a recognizable decision point. OPA can evaluate a shared policy across systems. Sentinel can stop an unsafe infrastructure plan. Branch protection can prevent an unverified pull request from merging. Kubernetes admission and network controls protect the cluster boundary. CSPM can detect drift and out-of-band changes. GitOps keeps desired state reviewable. SAST and SCA bring code and supply chain decisions into the same pull request workflow.

Adoption doesn't require turning every rule into a hard gate on the first day. Start with controls that are version-controlled, high-confidence, and tied to a real security or architectural requirement. Run them in audit or soft-mandatory mode, inspect representative violations, and fix the shared defaults that generate repeated findings. A secure module, repository template, or deployment overlay often removes more friction than asking every developer to repair the same issue.

Before enforcement, define four things for every policy:

  • Owner: The team responsible for maintaining the rule and handling exceptions.
  • Boundary: The exact object being evaluated, such as a pull request, Terraform plan, admission request, or live cloud resource.
  • Blocking condition: The risk signal that justifies stopping delivery.
  • Evidence trail: The policy version, decision, input, approval, and remediation guidance needed for review or audit.

Measure the system, not only the number of violations. Track false positives, overrides, review latency, recurring violations, policy evaluation failures, and the time teams need to remediate a blocked change. A policy that catches a serious issue but causes developers to wait through unclear reviews may need better context, not weaker security. A policy that never blocks may be correctly designed as detective feedback, or it may be disconnected from the workflow where decisions happen.

The central maintenance challenge is drift. Architecture changes, repositories evolve, dependencies move, and tickets acquire new requirements. The policy can remain syntactically valid while no longer representing the approved design. Connect rules to current threat models, design decisions, service metadata, and pull requests so reviewers can see why a control applies to this change.

A platform such as DevArmor can fit for teams that need more than isolated rules. DevArmor provides continuous threat modeling from project artifacts, security design reviews in tools such as GitHub, Jira, Google Docs, VS Code, Cursor, and MCP, and Policy-as-Code enforcement on pull requests with optional merge blocking. Its review outcomes can be tied to approved design decisions or threat models, making the relationship between architectural intent and implementation visible.

Teams assessing a broader operating model can also review these use cases for ops teams. Start with one delivery boundary, prove that the rule is understandable and maintainable, then expand only when the next control has a clear owner, signal, and enforcement point.


DevArmor connects continuous threat modeling, security design reviews, and Policy-as-Code enforcement to the workflows where teams plan, code, review, and deploy. It can turn approved design decisions into traceable pull request checks with optional blocking and remediation context. Visit DevArmor to see how those controls can fit your software delivery process.

Table of Contents

Subscribe