Open Policy Agent & Checkov with Scalr

Learn how Scalr uses OPA and Chekov for policy as code to enforce guardrails on Terraform workflows—for security, cost control and compliance.

Reviewed for accuracy by Ryan Fee on June 6, 2025.

Policy as Code with Scalr enables organizations to implement robust governance and compliance for their Infrastructure as Code (IaC) workflows, primarily focusing on Terraform and OpenTofu. This capability allows for the codification of organizational standards, security best practices, and cost controls, which are then automatically enforced within the Scalr platform.

Supported Frameworks

Scalr integrates with established open-source policy frameworks to provide flexibility and power:

Open Policy Agent (OPA) with Rego: Scalr has a native integration with OPA, a general-purpose policy engine. Policies are written in Rego, OPA's declarative query language. These policies evaluate Terraform and OpenTofu run data, allowing for fine-grained control over infrastructure provisioning. Scalr expects Rego policies to define a deny set, where each item in the set represents a policy violation message.

Checkov: For static analysis and vulnerability scanning of IaC configurations, Scalr also supports Checkov. This integration allows users to identify and mitigate misconfigurations and security vulnerabilities before infrastructure is provisioned. Checkov scans are typically performed early in the run lifecycle, before Terraform initialization.

OPA

Enforcement Points and Levels

Scalr OPA policies can be enforced at two distinct stages of a Terraform/OpenTofu run, using different data sources:

  • Pre-plan (using tfrun data): Policies at this stage are evaluated before the Terraform plan is generated. The tfrun input data includes information available prior to the plan, such as the run source (VCS details, module versions), workspace configuration, user information, and cost estimation data (if available).
  • Post-plan (using tfplan data): These policies are evaluated after the Terraform plan has been generated. The tfplan input data includes all the tfrun data, plus the full JSON representation of the Terraform plan, allowing policies to inspect proposed changes to resources, their attributes, and dependencies.

Scalr provides three enforcement levels for policies on policies:

Hard Mandatory:

  • Pre-plan: If a Hard Mandatory policy is violated, the run is immediately stopped and marked as errored. No plan is generated.
  • Post-plan: If a Hard Mandatory policy is violated after the plan, the run is stopped and marked as errored. The apply phase cannot proceed.

Soft Mandatory:

  • Pre-plan: If a Soft Mandatory policy is violated, the run is immediately stopped and marked as errored. No plan is generated. (Behaves like Hard Mandatory pre-plan).
  • Post-plan: If a Soft Mandatory policy is violated, the run enters an "approval needed" state. Users with appropriate permissions (policy-checks:override) can review the violation and either approve or deny the run. If approved, the run can proceed to the apply phase.

Advisory:

  • Pre-plan & Post-plan: If an Advisory policy is violated, a warning message is logged in the run output. The run is not halted or sent for approval due to an advisory violation; it proceeds as normal.

Policy Management

Scalr promotes a GitOps model for managing policies, ensuring that policy changes are version-controlled, auditable, and can go through review processes.

  • Policies Managed as Code in Version Control Systems (VCS): OPA Rego policies are stored in Git repositories. This allows teams to manage policy definitions alongside their infrastructure code or in dedicated policy repositories.
  • Environment Enforcement: Administrators in Scalr can enforce the OPA policies across specific environments, ensuring consistent security scanning for all workspaces within those environments.
  • Speculative Runs (Policy Impact Analysis): When changes are proposed to policies in a VCS repository (e.g., via a pull request), Scalr can trigger speculative runs. These runs evaluate the proposed policy changes against recent Terraform plans from linked environments. This "Policy Impact Analysis" allows users to understand the potential effect of policy modifications before they are merged and enforced, preventing unintended blocking of legitimate infrastructure changes.
  • Terraform Provider for Policy Management: Scalr provides a Terraform provider (Scalr/scalr) that can be used to manage scalr_policy_group resources. This allows the configuration of Policy Groups—linking VCS repositories containing policies to Scalr environments—to be managed as code itself. It is important to note that the provider manages the group definition and its linkage, not the individual Rego policies within the VCS repository.
  • Policy Groups: Policy Groups are Scalr entities that collect policies from a VCS repository. A Policy Group is configured by a scalr-policy.hcl file within the linked repository. This HCL file defines which OPA policies from the repository are enabled and their respective enforcement levels (Hard Mandatory, Soft Mandatory, or Advisory) for both pre-plan and post-plan stages. Policy Groups are then linked to one or more Scalr environments, applying the defined governance to all runs within those environments. An example scalr-policy.hcl might look like this:
version = "v1"

policy "terraform_min_version" {
  enabled = true
  enforcement_level = "hard-mandatory"
}

policy "terraform_suggested_version" {
  enabled = true
  enforcement_level = "soft-mandatory"
}

policy "limit_modules" {
    enabled = false
    enforcement_level = "soft-mandatory"
}

policy "workspace_name_convention" {
    enabled = true
    enforcement_level = "advisory"
}

Pre-built Libraries and Templates

To help users get started and codify common best practices, Scalr provides a public GitHub repository: Scalr/sample-tf-opa-policies. This repository contains a collection of example OPA policies covering various use cases, such as:

  • Cost Management: Limiting monthly estimated costs, restricting expensive instance types.
  • Tagging: Enforcing the presence of specific tags (e.g., owner, cost-center, environment).
  • Security: Prohibiting public S3 buckets, restricting IAM policies, enforcing encryption.
  • Naming Conventions: Enforcing resource naming patterns.
  • Resource Restrictions: Limiting the regions where resources can be deployed or the instance types that can be used.

These samples serve as a starting point and can be customized or used as inspiration for developing organization-specific policies.

Policy Examples (Code Snippets)

Below are conceptual examples of OPA Rego policies that can be used with Scalr.

1. Limit Monthly Estimated Cost (Post-plan)

This policy checks the proposed monthly cost estimate provided by input.tfrun.cost_estimate and denies the run if it exceeds a specified threshold.

# Simple check that cost estimate is above threshold.

package terraform

import input.tfrun as tfrun


deny[reason] {
    cost = tfrun.cost_estimate.proposed_monthly_cost
    cost > 100
    reason := sprintf("Plan is too expensive: $%.2f, while up to $100 is allowed", [cost])
}

Note: This policy uses tfrun data which is available in the post_plan input.

2. Enforce S3 Bucket Privacy (Post-plan)

This policy inspects planned S3 bucket resources to ensure they are not configured with a public 'acl'.

# Check S3 bucket is not public

package terraform

import input.tfplan as tfplan

deny[reason] {
	r = tfplan.resource_changes[_]
	r.mode == "managed"
	r.type == "aws_s3_bucket"
	r.change.after.acl == "public"

	reason := sprintf("%-40s :: S3 buckets must not be PUBLIC", 
	                    [r.address])
}

4. Restrict Allowed Instance Types (Post-plan - Multi-Cloud Example)

This policy ensures that only approved instance types are used.

# Multi proivder rule to enforce instance type/size

package terraform

import input.tfplan as tfplan

# Allowed sizes by provider
allowed_types = {
    "aws": ["t2.nano", "t2.micro"],
    "azurerm": ["Standard_A0", "Standard_A1"],
    "google": ["n1-standard-1", "n1-standard-2"]
}

# Attribute name for instance type/size by provider
instance_type_key = {
    "aws": "instance_type",
    "azurerm": "vm_size",
    "google": "machine_type"
}

array_contains(arr, elem) {
  arr[_] = elem
}

get_basename(path) = basename{
    arr := split(path, "/")
    basename:= arr[count(arr)-1]
}

# Extracts the instance type/size
get_instance_type(resource) = instance_type {
    # registry.terraform.io/hashicorp/aws -> aws
    provider_name := get_basename(resource.provider_name)
    instance_type := resource.change.after[instance_type_key[provider_name]]
}

deny[reason] {
    resource := tfplan.resource_changes[_]
    instance_type := get_instance_type(resource)
    # registry.terraform.io/hashicorp/aws -> aws
    provider_name := get_basename(resource.provider_name)
    not array_contains(allowed_types[provider_name], instance_type)

    reason := sprintf(
        "%s: instance type %q is not allowed",
        [resource.address, instance_type]
    )
}

These examples illustrate the flexibility of OPA and Rego in defining policies based on the rich data available in Scalr's tfrun and tfplan inputs.

Checkov

How Scalr Integrates Checkov for Enhanced Security

Scalr seamlessly integrates Checkov into its workflow to provide early and automated security feedback. Here's how it works:

Native Integration: Scalr has native support for Checkov. This means that when you manage your IaC through Scalr, Checkov scans can be automatically incorporated into your deployment pipelines.

Pre-Terraform Init Scans: A key aspect of the Scalr-Checkov integration is that Checkov scans are executed before the terraform init phase. This is crucial because it means potential issues are identified before any Terraform operations begin, saving time and preventing the deployment of vulnerable infrastructure.

Automated Checks and Run Stoppage: When Checkov is enabled within a Scalr environment, Scalr receives your IaC code and triggers a Checkov scan. If Checkov identifies errors or vulnerabilities based on the configured policies (which can be built-in or custom), Scalr can be configured to stop the Terraform run. This proactive approach ensures that only code meeting your security standards proceeds.

Customizable Policies and Parameters: Scalr allows for flexibility in how Checkov is used. You can:

    • Specify the Checkov version you want to use.
    • Pass custom parameters to Checkov, such as skipping certain checks (--skip-check) or defining whether a failed check results in a "hard fail" (stopping the run) or a "soft fail" (allowing the run to continue with warnings).
    • Integrate custom Checkov policies from external repositories, enabling you to enforce organization-specific security and compliance rules beyond Checkov's default set.

Environment Enforcement & Multiple Versions: Administrators in Scalr can enforce Checkov integration across specific environments, ensuring consistent security scanning for all workspaces within those environments. Scalr even supports applying multiple Checkov versions to an environment, facilitating easier testing and upgrading of Checkov versions without disrupting existing workflows.

Summary

Scalr's Policy as Code features provide a comprehensive solution for governing IaC deployments, helping organizations maintain security, compliance, and cost control across their cloud infrastructure.