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.
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.
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.