compliance.tf

Preview rule diffs

The Rules Preview API applies Operational Rules to a module and returns the diff without serving the module. Nothing is downloaded, cached into your project, or changed in your organization's configuration. The Rules Playground is the browser UI over the public route; this page is the API behind it.


Two routes

Public routePrivate route
Pathhttps://registry.compliance.tf/api/v1/modules/{namespace}/{name}/{provider}/{version}/rules/previewhttps://registry.compliance.tf/v1/rules/preview/{namespace}/{name}/{provider}/{version}
WhoAnyone. No account, and a free account gets the same responseA signed-in organization member (the dashboard session, not a registry token)
ModulesThe reviewed allowlist, at the version pinned for eachAny module in the catalog
Rules come from?rules= only, and it is requiredYour organization's Baseline, plus ?add_rules=, ?ruleset= or rp64
Rule ids per request850
BudgetCache misses per IP: 6 a minute, 60 an hour, 2 builds at onceA per-day quota by plan

Both routes refuse ?framework=, ?enable= and ?disable= with PREVIEW_PARAM_NOT_ACCEPTED rather than ignoring them: a silently dropped parameter would leave you believing you had previewed something you had not. The public route also refuses ?add_rules= for the same reason - there is no Baseline there to add to - and answers PREVIEW_TIER_REQUIRED to ?ruleset= and rp64.

The public route serves only the pinned version of an allowlisted module. Any other version, including latest, answers PREVIEW_VERSION_NOT_PINNED. The Playground shows the pinned version for each module.


Request

# Public route: no credentials. `?rules=` is required and comma-separated.
curl "https://registry.compliance.tf/api/v1/modules/terraform-aws-modules/s3-bucket/aws/5.15.4/rules/preview?rules=lifecycle_prevent_destroy_data,lifecycle_ignore_tags"

The private route takes the same module path after https://registry.compliance.tf/v1/rules/preview/ and is called from a signed-in dashboard session. It previews the module against the organization's Baseline, so an empty request shows what the Baseline alone would do, and ?add_rules= adds to it.


Response

The body has nine top-level keys. Trimmed from a real public-route response for the request above:

{
  "schema": "1.0",
  "module": { "namespace": "terraform-aws-modules", "name": "s3-bucket", "provider": "aws", "version": "5.15.4" },
  "rules": {
    "requested": ["lifecycle_prevent_destroy_data", "lifecycle_ignore_tags"],
    "add_requested": [],
    "resolved": ["lifecycle_ignore_tags", "lifecycle_prevent_destroy_data"],
    "source": "query",
    "baseline": null
  },
  "summary": {
    "success": true,
    "error": null,
    "files_scanned": 4,
    "files_changed": 1,
    "full_text_omitted": false,
    "scope_coverage": "module_root_only",
    "submodules_omitted": ["modules/notification", "modules/object"]
  },
  "outcomes": {
    "lifecycle_prevent_destroy_data": { "outcome": "enforced", "errors": [] },
    "lifecycle_ignore_tags": { "outcome": "enforced", "errors": [] }
  },
  "files": [
    {
      "path": "main.tf",
      "unified": "--- main.tf (original)\n+++ main.tf (after rules)\n@@ -54,6 +54,10 @@\n ...",
      "before": "...",
      "after": "..."
    }
  ],
  "conflicts": [],
  "danger": [],
  "cache": { "key_version": 4, "preview_id": "1b6a45f7..." }
}
  • rules.resolved is the list the engine ran, in the order it ran them. On the private route rules.baseline reports the organization's Baseline state instead of null.
  • outcomes has one entry per resolved rule id. enforced means the rule changed something; not_applicable means nothing in the module matched; a configured-but-empty rule reports not_configured. Read this, not the presence of a rule in the request, to know what happened.
  • files has one entry per changed file: path, a unified diff, and the full before and after text. When the module is large the full text is dropped and summary.full_text_omitted says so; the unified diff stays.
  • summary.scope_coverage is module_root_only when the preview ran on the root module only; submodules_omitted lists what was not previewed. A rule whose target lives in a submodule can report not_applicable here and still apply at download.
  • conflicts lists rules that could not be applied together; danger lists transformations the engine flags as risky. Both are empty in the normal case.

A download built with the same rules writes the same outcomes into compliancetf-manifest.json. The preview is the manifest before the fact; the manifest is the record after it. See Operational Rules for how to read it.


Errors

Errors are JSON with code, error, remediation and a request_id to quote when asking for help. The ones you will meet:

CodeMeaning
PREVIEW_VERSION_NOT_PINNEDPublic route: the version is not the one pinned for this module. Use the version the Playground shows.
PREVIEW_MODULE_NOT_ALLOWLISTEDPublic route: the module is not on the reviewed list.
PREVIEW_PARAM_NOT_ACCEPTEDA posture parameter this route does not take (add_rules on the public route, framework, enable, disable on either).
RULE_LIST_TOO_LONGMore than 8 ids on the public route, or 50 on the private one.
RULE_UNKNOWNAn id that is not in the catalog. The definitions page lists every selectable id.
RATE_LIMITEDThe cache-miss budget (public) or the daily quota (private) is spent. The response says when it resets.
PREVIEW_ENGINE_CATALOG_SKEWThe engine and the rule catalog disagree about a rule. Not transient: quote the request_id.

Next steps

On this page

Ask AI about this

Help improve this page