The Problem with Traditional Security Policy

Most organizations manage security policies the same way they did in 2005: Word documents in SharePoint, PDF checklists emailed between teams, and manual reviews that happen weeks after code is written. The result is predictable—policies are outdated before they’re published, enforcement is inconsistent, and the gap between what’s documented and what’s deployed grows wider every sprint.

In a world where infrastructure is provisioned in seconds and code deploys dozens of times per day, document-based security policy is a liability.

Policy as Code is the DevSecOps principle that solves this by treating security policies the same way we treat application code: written in a declarative language, version-controlled in Git, automatically tested, and continuously enforced.

What is Policy as Code?

Policy as Code means expressing security rules, compliance requirements, and organizational standards as machine-readable, executable code rather than human-readable documents.

Instead of a policy document that says:

“All S3 buckets must have encryption enabled and public access blocked.”

You write:

deny[msg] {
    input.resource_type == "aws_s3_bucket"
    not input.config.server_side_encryption_configuration
    msg = "S3 bucket must have server-side encryption enabled"
}

deny[msg] {
    input.resource_type == "aws_s3_bucket"
    input.config.acl == "public-read"
    msg = "S3 bucket must not allow public read access"
}

This policy is testable, versionable, and automatically enforced in your CI/CD pipeline. No human review required. No exceptions forgotten. No drift between intent and reality.

Why Policy as Code Matters

1. Enforcement Becomes Automatic

Manual policy enforcement relies on humans remembering rules and catching violations. Policy as Code shifts enforcement to automated gates in your pipeline. A misconfigured resource never reaches production because the policy engine rejects it at build time.

This is the shift-left principle in its purest form—security violations are caught when they’re cheapest to fix: before deployment.

2. Policies Become Testable

When policies are code, you can write unit tests for them. You can verify that a policy correctly blocks a public S3 bucket while allowing a properly encrypted private one. You can test edge cases. You can catch policy regressions before they create vulnerabilities.

3. Audit Becomes Trivial

Every policy change goes through a pull request. Every approval is recorded. Every version is preserved in Git history. When an auditor asks “when was this policy last updated and who approved it?”—you have a complete, tamper-evident answer.

For organizations subject to FedRAMP, SOC 2, HIPAA, or CMMC, this transforms compliance from a quarterly fire drill into a continuous, automated process.

4. Policies Scale with Your Organization

A document-based policy requires every team to read, interpret, and manually implement it. Policy as Code is enforced identically across every team, every project, and every environment—whether you have 5 developers or 5,000.

5. Policies Evolve with Your Infrastructure

When a new cloud service is adopted or a new threat emerges, you update the policy code, test it, and deploy it. Every team gets the updated enforcement immediately through the shared pipeline, without needing to read a new memo.

Implementing Policy as Code

The Tool Landscape

Several mature tools support Policy as Code:

  • Open Policy Agent (OPA) — General-purpose policy engine using the Rego language. Works with Kubernetes, Terraform, CI/CD pipelines, and API gateways
  • HashiCorp Sentinel — Policy framework integrated with Terraform Enterprise/Cloud, Vault, and Consul
  • Checkov — Static analysis for infrastructure-as-code (Terraform, CloudFormation, Kubernetes, Helm)
  • Kyverno — Kubernetes-native policy engine using YAML instead of a custom language
  • AWS Config Rules / Azure Policy — Cloud-native policy enforcement for their respective platforms

Where to Enforce

Policy as Code should operate at multiple layers:

1. Pre-commit (Developer Workstation)

Run lightweight policy checks before code is even committed. Catch obvious violations instantly.

# Example: pre-commit hook running Checkov
checkov -d . --framework terraform --quiet

2. CI Pipeline (Pull Request)

The primary enforcement point. Every pull request is evaluated against the full policy set. Violations block the merge.

3. Admission Control (Runtime)

For Kubernetes environments, OPA Gatekeeper or Kyverno acts as an admission controller, rejecting resources that violate policies even if they somehow bypass the CI pipeline.

4. Continuous Monitoring (Post-Deployment)

Detect drift and violations that emerge after deployment. Tools like AWS Config or OPA can continuously evaluate running infrastructure against declared policies.

Starting Small

You don’t need to codify every policy on day one. Start with the highest-impact rules:

  1. No public cloud storage — Block publicly accessible S3 buckets, Azure Blob containers, GCS buckets
  2. Encryption everywhere — Require encryption at rest and in transit for all data stores
  3. No hardcoded secrets — Scan for API keys, passwords, and tokens in code and configuration
  4. Container image provenance — Only allow images from trusted registries with verified signatures
  5. Network segmentation — Enforce that production workloads cannot communicate with development environments

Each of these can be implemented in a single policy file and added to your pipeline in hours, not weeks.

Policy as Code in Practice: A Real Pipeline

Here’s what a mature Policy as Code pipeline looks like:

Developer writes Terraform code
        │
        ▼
Pre-commit: Checkov scans locally
        │
        ▼
Pull Request opened
        │
        ▼
CI Pipeline runs:
  ├── terraform plan
  ├── OPA evaluates plan against policies
  ├── Checkov scans IaC files
  ├── tfsec scans for misconfigurations
  └── Secret scanner checks for credentials
        │
        ▼
All checks pass → PR can be merged
        │
        ▼
terraform apply (via GitOps)
        │
        ▼
Kubernetes admission controller
validates deployed resources
        │
        ▼
Continuous monitoring detects drift

Every layer reinforces the others. A violation caught at any stage is logged, reported, and blocked.

The Cultural Shift

Policy as Code isn’t just a technical change—it’s a cultural one. It requires:

  • Security teams to learn to express policies in code rather than documents
  • Development teams to accept automated policy gates as part of their workflow
  • Leadership to invest in shared policy infrastructure rather than manual review processes

The payoff is significant: security becomes a continuous, automated property of your system rather than a periodic, manual audit. Teams move faster because they get immediate feedback on violations instead of waiting weeks for a security review.

The Connection to GitOps

If you’ve read my previous post on GitOps, Policy as Code is a natural extension. GitOps makes Git the source of truth for infrastructure state. Policy as Code makes Git the source of truth for security rules. Together, they create a system where:

  • Every infrastructure change is declared in Git
  • Every security policy is declared in Git
  • Every change is automatically validated against every policy
  • Every deployment is auditable and reproducible

This is the foundation of true continuous compliance.

The Bottom Line

Policy as Code is the DevSecOps principle that turns security from a gate into a guardrail. Instead of blocking teams at the end of a development cycle with manual reviews, it provides immediate, automated feedback at every stage.

The organizations that adopt this principle will ship faster, comply more easily, and suffer fewer security incidents. Those that don’t will continue fighting the losing battle of enforcing document-based policies in an automated world.

Start small. Pick five critical policies. Write them in code. Add them to your pipeline. The hardest part is the first policy—after that, the pattern is established and momentum takes over.


Is your organization still managing security policies in documents? What’s holding you back from codifying them? Share your experience in the comments.