Skip to content

Conftest & OPA Integration

Combining Conftest and OPA for Security

In modern DevOps workflows, ensuring security and compliance across infrastructure as code (IaC) and application configurations requires a layered approach. Conftest and Open Policy Agent (OPA) can be combined to create a unified framework that enforces security policies during development and runtime. This section explores advanced use cases where these tools integrate to enforce compliance, detect misconfigurations, and adapt to dynamic environments.


Policy Enforcement in CI/CD Pipelines

Integrating Conftest and OPA into CI/CD pipelines ensures that infrastructure and application configurations meet security standards before deployment. Conftest validates Kubernetes manifests, Helm charts, or Terraform files against policies, while OPA can enforce policies dynamically based on contextual data (e.g., environment, user roles).

Example: Enforcing secrets in Kubernetes manifests

# conftest policy to check for secrets in ConfigMaps
# policy.rego
package k8s.secrets

deny[msg] {
    input.configmap.data["secret_key"]
    msg := "ConfigMap contains sensitive data"
}

# Run conftest in a CI pipeline
conftest test --policy policy.rego manifests/

Example: OPA evaluating environment-specific rules

# OPA policy to block secrets in production environments
# policy.rego
package k8s.secrets

deny[msg] {
    input.review.object.kind == "ConfigMap"
    input.review.object.metadata.namespace == "production"
    input.review.object.data["secret_key"]
    msg := "Secrets not allowed in production ConfigMaps"
}

# Integrate OPA with a Kubernetes admission controller or API server
opa eval --input configmap.yaml --policy policy.rego


Dynamic Policy Evaluation with OPA

OPA’s policy-as-code model allows for real-time, context-aware enforcement. When combined with Conftest, it enables scenarios where policies adapt to runtime conditions, such as environment variables, user roles, or resource constraints.

Example: Enforcing resource limits based on environment

# OPA policy to restrict CPU limits in staging environments
package k8s.resource_limits

deny[msg] {
    input.review.object.kind == "Pod"
    input.review.object.metadata.namespace == "staging"
    input.review.object.spec.containers[_].resources.limits.cpu > "2"
    msg := "CPU limits exceed staging environment constraints"
}

Example: Conftest validating OPA policy syntax

# Conftest policy to ensure OPA policies are syntactically valid
# policy.rego
package opa.syntax

deny[msg] {
    input.policy != ""
    msg := "OPA policy is empty or invalid"
}


Centralized Policy Management with OPA and Conftest

By centralizing policies in OPA, teams can manage security rules across multiple tools and environments. Conftest can act as a gatekeeper, ensuring that IaC files align with OPA’s centralized policies.

Example: Shared policy repository

# Conftest policy to enforce OPA policy compliance
# policy.rego
package opa.compliance

deny[msg] {
    input.config != ""
    not input.config == "allowed_policy"
    msg := "Configuration does not match allowed policies"
}

Example: OPA as a single source of truth

# OPA policy to enforce cross-cutting rules (e.g., no root volumes)
# policy.rego
package k8s.security

deny[msg] {
    input.review.object.kind == "PersistentVolumeClaim"
    input.review.object.spec.volumeClaimTemplates[_].spec.accessModes == ["RootSquash"]
    msg := "RootSquash not allowed in PersistentVolumeClaims"
}


Key takeaways

  • Conftest and OPA complement each other: Conftest validates static configurations, while OPA enforces dynamic, context-aware policies.
  • CI/CD integration: Use Conftest to catch misconfigurations early and OPA to enforce rules at runtime.
  • Centralized governance: OPA’s policy-as-code model enables consistent enforcement across diverse systems, with Conftest ensuring alignment with these policies.
  • Dynamic adaptability: Combine both tools to enforce rules that vary by environment, user, or resource type.