Pre-Beta Pre-beta signups are open now. The full audytx engine is live for pre-beta. Everything free today stays free — paid tiers arrive Sep 01, 2026 from $20/month for unlimited repositories.
CloudFormation · JSON · YAML · SAM · CDK output

One security engine. Terraform and CloudFormation.

audytx normalizes CloudFormation templates into the same resource model its Terraform engine reasons about — so the 250+ checks, the cross-resource context axes, and the false-positive suppression all run on your stacks, and every finding carries the same AWS_* rule id it would carry on Terraform. One findings vocabulary for the whole estate, in either language.

Where it's live today. CloudFormation scanning shipped first on the hosted MCP server: the scan_cloudformation tool is in the live tools/list, and GET /status reports supported_iac: ["terraform", "cloudformation"] — check it yourself. Autofix is live there too: autofix_cloudformation applies the sound, precisely-anchored fixes server-side, with dry_run_autofix_cloudformation to preview the diffs first. The GitHub App now reviews CloudFormation pull requests too — templates changed in a PR get the same one-comment review and SARIF upload as Terraform, and a CI workflow can POST DescribeChangeSet output to /changeset-upload (OIDC-authenticated) to re-scan with resolved values. The offline CLI still scans Terraform only.

Same rule ids, and why that matters

Most teams don't get to choose one IaC language — they inherit both.

CloudFormation-only scanners give CloudFormation-only findings vocabularies: a hardcoded secret is one id in your Terraform scanner and a different id in your template linter, and every triage decision, baseline entry, and dashboard has to be made twice. audytx takes the other path: the parser front-end maps CFN resource types onto the engine's resource vocabulary before any rule runs, so AWS::S3::Bucket and aws_s3_bucket are judged by the identical check, with the identical id, severity, and remediation text. A rule your team has already reviewed on Terraform means exactly the same thing when it fires on a stack template.

The intrinsics are a language, and we treat them like one

A scanner that half-reads Fn::If and !Sub manufactures the very false positives audytx is supposed to remove — so the template front-end reads them properly.

JSON and YAML, including short tags

Both syntaxes parse, including the YAML short-tag forms (!Ref, !GetAtt, !Sub, !If) that trip up JSON-first tooling. SAM templates are accepted the same way, and a CDK cloud assembly — the whole cdk.out, manifest included — is recognized as one: findings come back keyed by construct path, not hash-suffixed logical IDs.

Intrinsics get a real evaluator

References, Fn::Sub interpolation, and Fn::ForEach expansion are resolved where they can be, and ARNs that depend on runtime values are tracked symbolically instead of being guessed at.

Fn::If is downgraded, never guessed

When a security-relevant attribute hides behind a condition the template alone can't resolve, audytx evaluates both branches. If they disagree, the finding is downgraded one severity step and marked conditional, with a note saying why. It isn't dropped, and it isn't reported as more certain than it is.

Cross-resource context, validated on CFN

The reasoning axes that decide what survives — invocation graphs, DLQ identity, IAM trust graphs, exposure — run on the normalized stack, and each axis is exercised by CloudFormation-specific positive and negative test suites plus a benign-template corpus, the same false-positive discipline the Terraform engine is held to.

Scan a template from your agent, right now

The MCP server is stateless and read-only: templates are parsed in memory and discarded per request. Mint a free Client ID at the dashboard.

# One-time: register audytx with your agent (Claude Code shown)
claude mcp add --transport http audytx https://audytx.com/mcp \
  --header "X-Client-ID: YOUR_CLIENT_ID"

# Or call the tool directly
curl -s https://audytx.com/mcp \
  -H 'Content-Type: application/json' -H 'X-Client-ID: YOUR_CLIENT_ID' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
        "name":"scan_cloudformation",
        "arguments":{"files":[{"path":"stack.yaml","content":"..."}]}}}'

The response shape is identical to scan_terraform — findings with rule ids and line numbers, context-suppressed findings each with a printed reason, and a parse_warning whenever a template couldn't be fully read. A .audytx-baseline.yaml can be passed the same way. Full tool docs →

Coming to the other surfaces

We shipped the MCP surface first on purpose: more and more new CloudFormation is written by coding agents, and the agent that wrote the template is in the best position to act on its findings. GitHub App pull-request review followed — templates changed in a PR are sniff-detected and reviewed with cross-template context from the rest of the repository. The offline CLI walks .tf files only for now — CloudFormation lands there next, and this page and /status will say so when it does. If you're migrating from cfn_nag in the meantime, there's a dedicated migration page.

Frequently asked questions

Can audytx scan CloudFormation today?

Yes — on the hosted MCP server, via the scan_cloudformation tool, live now (verify with tools/list or GET /status), with server-side autofix via autofix_cloudformation and a dry-run preview. The GitHub App reviews CloudFormation pull requests too. The offline CLI still scans Terraform only; CloudFormation support there is rolling out next.

Does audytx scan CDK apps and SAM templates?

CDK: yes — pass the whole cdk.out cloud assembly (manifest included; that synthesized output is the artifact CloudFormation actually deploys) and findings come back keyed by construct path rather than hash-suffixed logical IDs, CDK's metadata and bootstrap tooling resources are suppressed with a visible rationale, and Export/ImportValue references are stitched across stacks so multi-stack apps don't produce false no-consumer findings. SAM: yes — AWS::Serverless::* resources are expanded into the CloudFormation resources the transform would generate, including the auto-created IAM roles, event-source mappings, and API stages, and scanned with the same rules, with top-level Globals sections merged the way the transform would — resource values win, lists prepend. The one gap: a template that configures an implicit API through Globals (an Api/HttpApi event with no explicit target plus a matching Globals section) isn't expanded yet, and the scan result says so rather than reporting a silent clean.

Are the rule ids the same as on Terraform?

Yes. CloudFormation is normalized into the engine's resource vocabulary before rules run, so findings reuse the same AWS_* ids, severities, and remediation text as Terraform scans — one vocabulary across a mixed estate.

Which false positives does context remove on CloudFormation?

The same classes as on Terraform: a Lambda flagged for a missing dead-letter queue when nothing invokes it asynchronously, a queue that is itself a DLQ flagged for not having its own, encryption findings on resources whose encryption comes from another declaration, and so on. Every suppression is surfaced with its rationale — the mechanism is documented here.

Open beta

Point your agent at the engine

A free Client ID takes a minute, and your first CloudFormation scan takes one tool call — free during the beta.