Preview Rule Diffs
Coming Soon
The Preview API is planned but not yet available. This page describes the expected behavior. The endpoint path, authentication scheme, and response format may change before release.
The Preview API shows you exactly what Operational Rules will change in a module before you download it. You get a unified diff for every file that a rule modifies, along with the full rules manifest — without downloading the transformed module.
What the Preview API will do
- Accept a module, version, framework, and rule set
- Run the rule transformations in a dry-run mode
- Return a diff for every modified file, plus the rules manifest
- No module is cached or stored — this is a read-only preview
This lets platform teams and developers inspect rule changes before they reach a terraform init. It is particularly useful when enabling a new rule for your org, or when reviewing what a per-request ?rules= override on a framework host, or a ruleset on your organization's host, will produce.
Expected request format
Two routes, both GET, both on the registry host. They differ in what they can
see, which is why one needs credentials and the other does not — see
Availability below.
# Public route. No credentials and no organization, so `?rules=` is required:
# there is no Baseline here for an empty request to show.
curl "https://registry.compliance.tf/api/v1/modules/terraform-aws-modules/s3-bucket/aws/5.0.0/rules/preview?rules=lifecycle_prevent_destroy_data,lifecycle_ignore_tags"
# Private route. Previews against your organization's Baseline, so it accepts
# the additive forms and needs a signed-in session.
curl -H "Authorization: Bearer $CTF_TOKEN" \
"https://registry.compliance.tf/v1/rules/preview/terraform-aws-modules/s3-bucket/aws/5.0.0?add_rules=lifecycle_prevent_destroy_data"Expected response format
{
"module": "terraform-aws-modules/s3-bucket/aws",
"version": "5.0.0",
"framework": "soc2",
"diffs": [
{
"file": "main.tf",
"hunks": [
{
"header": "@@ -45,6 +45,10 @@",
"lines": [
" bucket = var.bucket",
" ",
" tags = var.tags",
"+",
"+ lifecycle {",
"+ prevent_destroy = true",
"+ ignore_changes = [tags, tags_all]",
"+ }",
" }"
]
}
]
}
],
"rules_manifest": {
"operational_rules": [
{ "rule": "lifecycle_prevent_destroy_data", "outcome": "enforced" },
{ "rule": "lifecycle_ignore_tags", "outcome": "enforced" }
],
"posture": {
"rules_hash": "3f9c2a71b0e4d8c5",
"degraded": []
}
}
}How to read the diff output
The diffs array contains one entry per modified file. Each entry includes:
file— the path of the modified file within the modulehunks— one or more diff hunks in unified diff format
Lines prefixed with + are additions. Lines prefixed with - are removals. Lines without a prefix are context (unchanged).
If no files are modified — the module contains no resource a rule targets, say — the diffs array will be empty and every rule in the manifest will carry an outcome other than enforced.
Understanding the rules manifest
The rules_manifest above mirrors the shipped compliancetf-manifest.json, deliberately: a preview that reported a different shape from the artifact would be a second thing to learn and a second thing to drift. The shipped manifest records the rules the build received, an outcome per rule, the set of file paths the build modified, and a variant fingerprint — see operational rules for how to read it. Note what is not there: the manifest records file paths, never resource addresses, and it does not attribute individual files to individual rules. A preview cannot report what the artifact does not carry, so read the resource-level detail from the diffs array instead.
Treat the endpoint shape as provisional until it exists. It would let you verify:
- Which rules the build received, and what each one did — from
outcome, not from presence - Which files a rule's transformation touches, from the diff hunks
- The
rules_hash— compare it across environments to confirm the same variant was built
Availability
The Preview API is not live yet. When it ships the split will not be "paid only":
- A public route over an allowlisted set of upstream modules, open to anonymous and free callers alike — the two receive byte-identical responses. It takes
?rules=(required, and a lower entry cap than a download), and refuses?add_rules=: an anonymous caller has no Baseline to add to. - A private route for a signed-in organization, which previews against that organization's Baseline and accepts the additive forms.
Both are read-only and neither affects cached modules or organization configuration.
Next steps
- Getting Started with Operational Rules — apply rules today with
?rules=or your organization's Baseline - Rule Catalog — browse the documented rules with before/after examples