One security engine. Terraform and CloudFormation.
audytx normalizes CloudFormation templates into the same resource model its Terraform
engine reasons about — so most of the 250+ checks, the cross-resource context checks, and the
false-positive suppression run on your stacks, and a finding on a mapped resource type carries the
same AWS_* rule id it would carry on Terraform. A few checks
(AWS_CFN_*) exist only for CloudFormation. 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
the same thing when it fires on a stack template. Resource types that are not mapped yet are not covered.
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 not 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; the findings of a scan (rule, message, resource, file and lines) are kept for 90 days. 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. Full tool docs →
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 detected and reviewed with cross-template context from the rest of the repository. If you're migrating from cfn_nag, 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, and the VS Code extension scans templates in the editor.
Does audytx scan CDK apps and SAM templates?
CDK: yes. Pass the whole cdk.out cloud assembly (manifest included); findings come back keyed by construct path. SAM: yes. AWS::Serverless::* resources are expanded into the CloudFormation resources the transform would generate and scanned with the same checks. Some SAM types are not expanded yet, so a stack that relies on them is only partly covered.
Are the rule ids the same as on Terraform?
For mapped resource types, 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. A few checks (AWS_CFN_*) apply only to CloudFormation.
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. The Free plan includes 100 scans a month.