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.
CI/CD · GitHub Actions

Terraform security scanning in GitHub Actions

There are three ways to put audytx's cross-resource AWS Terraform review in front of a pull request, in rising order of effort. Most teams need only the first. The second gives you a hard build gate inside GitHub Actions; the third adds resolved-value precision. All three run the same engine and suppress the same false positives.

Level 1 · recommended

GitHub App

Zero config. One comment per PR, SARIF to Code Scanning. No workflow file.

Level 2 · a hard gate

Actions + MCP

A short workflow fails the build on High/Critical findings. Free Client ID.

Level 3 · precision

Plan enrichment

Upload the resolved terraform plan over OIDC for variable-accurate findings.

Level 1

The zero-config path: the GitHub App

Before you write a workflow, know that you may not need one. The audytx GitHub App reviews every pull request on install — no Actions file, no token to store. It reads your .tf/.tfvars files, runs the whole engine, posts one comment with the findings and their suppression rationales, adds inline annotations, and uploads a SARIF document to GitHub Code Scanning so findings show in the Security tab.

The App is the whole product for most teams: it installs in about a minute and needs no CI wiring. Reach for a workflow when you specifically want to fail the build on a finding — the App comments and reports, it does not block your Actions run.
Level 2

A hard gate in GitHub Actions

To block a merge on a High or Critical finding, add a workflow that calls the audytx MCP API and fails the job on the result. This needs a free Client ID — store it as the repository secret AUDYTX_CLIENT_ID. The workflow bundles your Terraform, POSTs one JSON-RPC call, and exits non-zero when the severity summary crosses your threshold:

.github/workflows/audytx.yml
name: audytx Terraform security gate
on: [pull_request]
permissions:
  contents: read
jobs:
  audytx:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Scan Terraform with audytx
        env:
          AUDYTX_CLIENT_ID: ${{ secrets.AUDYTX_CLIENT_ID }}
        run: |
          # Bundle every .tf/.tfvars file into one JSON-RPC request.
          # Pass the whole tree — cross-resource reasoning needs it.
          req=$(find . \( -name '*.tf' -o -name '*.tfvars' \) -print0 \
            | xargs -0 -I{} jq -n --arg p "{}" --rawfile c "{}" \
                '{path:$p, content:$c}' \
            | jq -s '{jsonrpc:"2.0", id:1, method:"tools/call",
                      params:{name:"scan_terraform", arguments:{files:.}}}')

          resp=$(curl -sf https://audytx.com/mcp \
            -H "Content-Type: application/json" \
            -H "X-Client-ID: $AUDYTX_CLIENT_ID" --data "$req")

          # List the High/Critical findings for the log …
          echo "$resp" | jq -r '.result.structuredContent.findings[]
            | select(.severity=="CRITICAL" or .severity=="HIGH")
            | "\(.severity)  \(.rule_id)  \(.file):\(.line_start)  \(.title)"'

          # … then fail the build if any exist.
          gate=$(echo "$resp" \
            | jq '.result.structuredContent.summary | .critical + .high')
          if [ "$gate" -gt 0 ]; then
            echo "::error::audytx found $gate High/Critical AWS security findings"
            exit 1
          fi

The response carries a summary block (critical/high/medium/low counts) and a findings array with rule_id, severity, file, line_start, and remediation — the same contract the docs describe. Move the gate to .critical alone for a looser policy, or add .medium for a stricter one.

The MCP call is metered against your free monthly quota (500 calls/month), and only successful calls count. The context layer still suppresses false positives here — it removed 85 of them in our corpus study — so a red build means a finding worth stopping for. Prefer the App for the SARIF/Code-Scanning surface and use this workflow purely as the blocking gate; they work well together.
Level 3

Resolved-value precision with a plan upload

Static parsing can't resolve values behind variables, count/for_each expansion, or resources inside modules. If you want findings computed against the resolved plan, add the plan-upload workflow. It authenticates with the run's GitHub OIDC tokenno secret to store — runs terraform show -json, and POSTs the plan so audytx re-scans with final values folded in. It's strictly additive: the normal scan keeps working with or without it.

The full workflow and its permissions: id-token: write block are documented on the plan-scanning page. Pair it with either level above.

The plan upload enriches the GitHub App's PR comment (it's fire-and-forget — if the upload fails, your normal scan still stands). It does not, by itself, return a pass/fail to your Actions run; use Level 2 for the blocking decision.
CloudFormation

The same gate for CloudFormation

Building CloudFormation instead of Terraform? The MCP gate works unchanged — audytx normalizes stack templates into the same resource model and returns the same response shape. Point find at your templates and call scan_cloudformation:

          req=$(find . \( -name '*.yaml' -o -name '*.yml' -o -name '*.json' \) -print0 \
            | xargs -0 -I{} jq -n --arg p "{}" --rawfile c "{}" \
                '{path:$p, content:$c}' \
            | jq -s '{jsonrpc:"2.0", id:1, method:"tools/call",
                      params:{name:"scan_cloudformation", arguments:{files:.}}}')
CloudFormation is live on the MCP server and the GitHub App: the zero-config Level 1 path now covers stack templates changed in a PR (same one-comment review and SARIF upload as Terraform). The MCP gate above is still what hard-fails a CI build on findings. The offline CLI still scans Terraform exclusively. Track surface rollout at /status (supported_iac).
FAQ

Common questions

Do I need a GitHub Actions workflow at all?

No. The GitHub App reviews every pull request on install with no workflow file — one comment plus SARIF to Code Scanning. You only need a workflow if you want to fail the build on a finding, which the App doesn't do. Many teams run the App alone.

Is there a prebuilt CLI or Marketplace Action I can drop in?

Not yet — the blocking gate today is the MCP call shown above, which any repository can run with a free Client ID. A packaged CLI and a Marketplace Action are on the roadmap; we shipped the MCP API first because it's the same engine the App and coding agents already use, so every surface reports the same findings.

Does the workflow send my Terraform anywhere it's stored?

The MCP call sends file contents to audytx, which parses them in memory and discards them when the response returns — the same privacy posture as the GitHub App path. Only aggregate scan metadata (counts, engine version) is recorded, never file contents or secrets.

How do the findings reach the GitHub Security tab?

Through the GitHub App, which uploads a SARIF v2.1.0 document to Code Scanning automatically — including the context-suppressed findings as SARIF suppressions with their rationale. The Level 2 workflow is a build gate, not a SARIF uploader; run both to get the gate and the Security-tab surface.

Open beta

Put the gate in front of your next PR

Install the GitHub App for zero-config review, or drop in the workflow to fail the build on High/Critical findings — free during the beta.