Secure OpenTofu Code with cnspec
Scan OpenTofu configurations, plans, and state files for security misconfigurations with cnspec. No OpenTofu CLI required.
Catch insecure infrastructure before tofu apply provisions it. cnspec has a dedicated OpenTofu connector that evaluates HCL configurations, plan files, and state files against security policies on a developer workstation, as a CI/CD gate, or as a post-provisioning check.
This page is part of scanning your supply chain with cnspec. If you're new to cnspec, start with the Quickstart to install cnspec and run your first scan. For Terraform projects, read Secure Terraform Code with cnspec.
How cnspec reads OpenTofu
cnspec parses HCL configuration, plan JSON, and state JSON directly and never runs the tofu CLI, so OpenTofu doesn't need to be installed on the workstation or CI runner that performs the scan.
cnspec scan opentofu (or its alias, cnspec scan tofu) reads a directory the way OpenTofu does:
- It reads
.tofu,.tofu.json,.tofuvars, and.tofuvars.jsonfiles along with their Terraform equivalents (.tf,.tf.json,.tfvars, and.tfvars.json). - When a
.tofuflavored file shares a name with its Terraform equivalent in the same directory, the.tofufile wins and the Terraform file is not read. For example,main.tofureplacesmain.tf, andprod.tofuvarsreplacesprod.tfvars. - Files with no
.tofucounterpart are read as they are, so a configuration you haven't renamed is scanned unchanged.
cnspec resolves var.* and local.* references in block arguments to their effective values: variable defaults, overridden by values in variable files, with locals evaluated from those. References that can't be resolved statically, such as data sources and resource attributes, keep their reference string.
cnspec reports each asset under an OpenTofu platform: opentofu-hcl, opentofu-plan, or opentofu-state. These platforms belong to both the opentofu and the terraform platform families.
Prerequisites
To scan OpenTofu code with cnspec, you must have:
- cnspec installed on your workstation
- OpenTofu files to scan (HCL, plan JSON, or state JSON)
Scan OpenTofu code
Scan HCL configuration files in a directory:
cnspec scan opentofu /path/to/opentofu/Add --ignore-dot-terraform to skip the .terraform directory, which holds cached provider plugins and modules.
Scan an OpenTofu plan file:
tofu plan -out tfplan.binary
tofu show -json tfplan.binary > tfplan.json
cnspec scan opentofu plan tfplan.jsonScan an OpenTofu state file:
tofu show -json > state.json
cnspec scan opentofu state state.jsoncnspec reads plan and state files only in the JSON representation that tofu show -json produces. If you point cnspec at a raw terraform.tfstate file, or at an encrypted state or plan file, the scan fails with an error that tells you to convert it first. To scan encrypted state or plans, run tofu show -json with your encryption key configured and scan that output.
cnspec returns the results to stdout. If you're logged into Mondoo Platform, results are also reported there. To control the output format or send results to a file or CI system, read Report Results.
Scan options
| Option | Description |
|---|---|
--asset-name | Override the asset name |
--annotation | Add an annotation to the asset (key=value) |
--incognito | Run in incognito mode (do not report results to Mondoo Platform) |
-o, --output | Set the output format (compact, csv, full, hdf, json, junit, ocsf-json, ocsf-parquet, report, sarif, summary, yaml) |
-f, --policy-bundle | Path to a policy file (local path, s3:// URI, or http(s):// URL) |
--policy | Specify policies to execute (requires --policy-bundle) |
--risk-threshold | Exit with status 1 if any risk meets or exceeds this value (0-100) |
Name assets in CI/CD pipelines
cnspec names an OpenTofu asset after its platform and the file or directory it scanned. Scanning tfplan.json produces the asset name OpenTofu Plan tfplan. To tell apart plans from different environments, pass --asset-name:
cnspec scan opentofu plan tfplan.json --asset-name "checkout-service-staging"Policies for OpenTofu assets
The Terraform variants in Mondoo's cloud security policies and the Terraform Deprecations policy select assets by their Terraform platform (terraform-hcl, terraform-plan, or terraform-state), so they evaluate assets you scan with the Terraform connector.
Plan and state JSON is identical between the two tools, and cnspec reads it the same way with either connector. The connector only selects the platform the asset is reported under. To evaluate an OpenTofu plan or state file against those policies, scan it with cnspec scan terraform plan or cnspec scan terraform state.
To write your own checks for OpenTofu assets, filter on the platform family. Because OpenTofu platforms also belong to the terraform family, this filter matches both Terraform and OpenTofu assets:
policies:
- uid: lunalectric-iac
name: Lunalectric IaC standards
version: 1.0.0
groups:
- filters: asset.family.contains("terraform")
checks:
- uid: lunalectric-s3-no-public-acl
title: S3 buckets do not use a public canned ACL
mql: |
terraform.resources.where(nameLabel == "aws_s3_bucket").all(
arguments["acl"] != "public-read" && arguments["acl"] != "public-read-write"
)Because cnspec resolves variables, this check catches an acl argument set through var.bucket_acl as well as one set to a literal value.
To filter on OpenTofu assets only, use asset.family.contains("opentofu"). To learn more about writing policies, read Write Custom Policies.
Explore OpenTofu configurations
OpenTofu assets use the same MQL resources as Terraform. Open a cnspec shell to discover resources and try out checks:
cnspec shell opentofu /path/to/opentofu/List configuration files
cnspec> terraform.filesList all resources
cnspec> terraform.resourcesCompare resolved and unresolved arguments
arguments holds the argument values with variable and local references resolved. argumentReferences holds the same arguments with the references left in place:
cnspec> terraform.resources { arguments argumentReferences }
terraform.resources.list: [
0: {
argumentReferences: {
bucket: "var.bucket"
}
arguments: {
bucket: "lunalectric-logs"
}
}
]Explore plan and state files
When querying a plan file:
cnspec> terraform.plan.resourceChangesWhen querying a state file:
cnspec> terraform.state.resourcesLearn more
- Secure Terraform Code with cnspec: scan Terraform configurations, plans, and state files
- Terraform Resource Pack Reference: every resource and field cnspec can query in Terraform and OpenTofu code
- Write Effective MQL: guide to authoring checks and queries