ChangeGate is a fast, graph-aware Terraform/OpenTofu risk gate for CI/CD. It reads the plan that is actually about to apply, builds a graph of changing infrastructure, and returns one deployment decision: ALLOW, WARN, or BLOCK.
Use it when you want fewer noisy scanner findings and more trusted deploy decisions.
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
changegate scan --plan tfplan.jsonBy default, ChangeGate runs offline from plan JSON. It does not require a SaaS account, cloud credentials, telemetry, or an AI decision-maker.
Most IaC scanners inspect source files and produce checklists. ChangeGate gates the planned change.
| ChangeGate focuses on | Why it matters |
|---|---|
| Plan-aware analysis | Evaluates the resources and actions Terraform/OpenTofu is about to apply. |
| Graph-aware risk | Understands relationships between load balancers, security groups, IAM, compute, networks, and data stores. |
| High-confidence blocking | Blocks only risks that meet policy, severity, confidence, and context thresholds. |
| One deploy decision | Produces a deterministic allow/warn/block result for CI. |
| Governed exceptions | Supports expiring waivers and baselines for existing debt. |
| Evidence-rich output | Emits findings with evidence, graph paths, remediation, fingerprints, and audit bundles. |
- Plan-aware deployment gating: evaluates Terraform/OpenTofu plan JSON and returns one CI-friendly deploy decision.
- Blast-radius graph: maps changing resources to public entrypoints, IAM edges, networks, workloads, and sensitive assets.
- Attack-path evidence: highlights deterministic public-to-sensitive-data and IAM privilege-escalation paths.
- Review Intelligence: generates security impact statements, PR/MR comments, GitHub annotations, GitLab Code Quality output, and visual graph artifacts.
- AWS architecture visualization: turns read-only AWS context snapshots into self-contained account, network, public-exposure, data, IAM, compute, and resource diagrams.
- Governed adoption: supports baselines, new-risk-only mode, expiring waivers, audit bundles, and stable finding fingerprints.
- External scanner imports: ingests SARIF, Checkov, Trivy, KICS, Grype, and generic JSON findings for graph-aware correlation.
- Optional cloud context: collects redacted AWS read-only snapshots while keeping normal scans offline and credential-free.
- Module risk tests: write regression tests for infrastructure modules and expected ChangeGate decisions.
- Portable distribution: ships a single binary plus release archives, checksums, SBOMs, signed artifacts, Docker images, Linux packages, and an npm installer package.
ChangeGate includes review-oriented commands for pull requests, merge requests, approval workflows, and module regression tests:
changegate impact --plan tfplan.json --format markdown
changegate graph path --plan tfplan.json --from aws_lb.admin --to aws_db_instance.customer
changegate graph exposure --plan tfplan.json --resource aws_ecs_service.admin
changegate graph visualize --plan tfplan.json --view exposure --resource aws_ecs_service.admin --out exposure.html
changegate attack-paths --plan tfplan.json --to-sensitive-data
changegate attack-paths visualize --plan tfplan.json --out attack-paths.html
changegate review github --report changegate.json --comment --annotations
changegate review gitlab --report changegate.json --comment
changegate context aws snapshot --out .changegate/aws-context.json --collect=all
changegate architecture aws visualize --context-file .changegate/aws-context.json --view account --out aws-architecture.html
changegate test examples/risk-testsThese commands reuse the same deterministic scan engine and graph model. The default path remains local and credential-free; AWS cloud context is opt-in and produces redacted offline snapshots. See Review Intelligence, Security Impact Statement, Blast-Radius Graph, AWS Architecture Visualization, and Attack Paths.
Use a redacted AWS context snapshot to generate a self-contained architecture map without running a scan. The default account map focuses on deployed resources, not IAM policy internals or individual AWS API action nodes:
changegate context aws snapshot --collect=network,edge,compute,data,iam --out .changegate/aws-context.json
changegate architecture aws visualize --context-file .changegate/aws-context.json --view account --out aws-architecture.htmlOr collect read-only AWS inventory and render in one command:
changegate architecture aws visualize --regions us-east-1 --view account --out aws-architecture.htmlLive AWS collection uses the standard AWS SDK credential chain. Use a read-only AWS role or profile for context collection:
changegate architecture aws visualize --profile readonly --regions us-east-1 --out aws-architecture.htmlScope live snapshots or diagrams to tagged resources when you want a team-specific view:
changegate context aws snapshot --collect=all --regions us-east-1 --tag team=payments --out .changegate/payments-context.json
changegate architecture aws visualize --regions us-east-1 --tag team=payments --out payments-architecture.htmlThe HTML viewer includes account, region, VPC, subnet, service, and resource grouping; search and role filters; collapsible containers; draggable resources; edge highlighting; a minimap; saved browser layouts; and a right-side resource inspector. IAM detail is available through the IAM view without expanding every granted AWS API action into the main architecture map. See AWS architecture visualization and Cloud Context.
The built-in AWS rule pack currently includes 63 stable high-confidence rules, including:
- public administrative services and database exposure
- world-open security group ingress on admin, database, and all-port ranges
- production RDS replacement, backup reduction, disabled final snapshots, disabled backups, and disabled deletion protection
- DynamoDB PITR, S3 versioning/logging, CloudTrail, AWS Config, and ECR production guardrails
- public S3 policies and ACLs, public Lambda function URLs, public admin API Gateway routes, and weak public load balancer listeners
- broad IAM admin, NotAction, sensitive wildcard access, PassRole, assume-role, KMS decrypt, and Secrets Manager read paths
- public-to-sensitive datastore graph paths
- sensitive storage without encryption, logging, or versioning
- public subnet, EFS, ElastiCache, private subnet, and transit/peering blast-radius expansion
See the rule reference for the full list.
Release install:
export CHANGEGATE_VERSION=vX.Y.Z
# Requires cosign on PATH for signed checksum verification.
curl -fsSL "https://raw.githubusercontent.com/Gabriel0110/changegate/${CHANGEGATE_VERSION}/scripts/install.sh" | bashThe installer verifies the signed checksum manifest with cosign, verifies the archive checksum, and refuses mismatches. Set CHANGEGATE_VERIFY_SIG=false only in trusted test environments where signature verification is intentionally unavailable. Set CHANGEGATE_VERSION to another release tag when upgrading. Release artifacts include checksums, signed checksums, SBOMs, attestations, signed Docker images, and Linux .deb, .rpm, and .apk packages.
Docker:
docker run --rm ghcr.io/gabriel0110/changegate:vX.Y.Z version
docker run --rm -v "$PWD:/work:ro" ghcr.io/gabriel0110/changegate:vX.Y.Z scan --plan /work/tfplan.jsonPublished image tags include vX.Y.Z, X.Y.Z, X.Y, X, and latest.
npm:
npx changegate version
npx changegate scan --plan tfplan.jsonThe npm package installs the matching platform binary from GitHub Releases, verifies the signed checksum manifest with cosign, and verifies the archive checksum before extraction. Set CHANGEGATE_NPM_VERIFY_SIG=false only in trusted test environments.
See Install Options for Docker tags and npm installer behavior.
Development build:
go build -o bin/changegate ./cmd/changegate
bin/changegate versionTerraform:
terraform init
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
changegate scan --plan tfplan.jsonOpenTofu:
tofu init
tofu plan -out=tfplan
tofu show -json tfplan > tfplan.json
changegate scan --plan tfplan.jsonExit codes are stable:
| Exit code | Meaning |
|---|---|
0 |
Deployment is allowed. |
1 |
ChangeGate found a blocking risk. |
2 |
Usage or flag error. |
3 |
Input parsing error. |
4 |
Policy/configuration error. |
5 |
Cloud-context error. |
6 |
Internal error. |
7 |
Unsupported input or provider. |
Use changegate init when you want ChangeGate to create starter files for a repository instead of wiring everything by hand:
changegate init --dry-run
changegate init --github-actions --audit-modeThe initializer writes safe audit-mode defaults so you can collect signal before enforcing block decisions. It never overwrites existing files unless --force is passed.
Common options:
| Option | Creates |
|---|---|
--github-actions |
.github/workflows/changegate.yml with audit-mode scan, PR review comment, SARIF upload, and audit bundle upload. |
--gitlab-ci |
.gitlab-ci.yml with audit-mode scan, GitLab Code Quality output, MR note, and audit bundle artifact. |
--baseline |
.changegate/README.md with baseline creation commands for existing-risk adoption. |
--waivers |
.changegate/waivers.yaml starter file for governed exceptions. |
--audit-mode |
.changegate.yaml configured for evidence collection before enforcement. |
--dir PATH |
Writes starter files into a specific repository directory. |
--force |
Allows overwriting generated files after review. |
Typical rollout:
changegate init --github-actions --baseline --waivers --audit-modeAfter reviewing the generated files, commit them with your Terraform/OpenTofu root conventions and adjust paths as needed.
Use console output locally:
changegate scan --plan tfplan.jsonGenerate machine-readable output:
changegate scan --plan tfplan.json --format json --out changegate.json
changegate scan --plan tfplan.json --format sarif --out changegate.sarif
changegate scan --plan tfplan.json --format markdown --out changegate.md
changegate graph path --plan tfplan.json --from aws_lb.admin --to aws_db_instance.customer --format mermaid --out graph-path.mmd
changegate graph export --plan tfplan.json --format dot --out graph.dotGenerate visual review artifacts:
changegate graph visualize --plan tfplan.json --out graph.html
changegate graph visualize --plan tfplan.json --view path --from aws_lb.admin --to aws_db_instance.customer --out path.html
changegate attack-paths visualize --plan tfplan.json --out attack-paths.html
changegate architecture aws visualize --context-file .changegate/aws-context.json --view account --out aws-architecture.html
changegate architecture aws visualize --context-file .changegate/aws-context.json --view public-exposure --out public-exposure.html
changegate architecture aws diff --before-context-file old-context.json --after-context-file new-context.json
changegate graph render --plan tfplan.json --view exposure --resource aws_ecs_service.admin --render-format svg --out exposure.svgArchitecture maps are self-contained HTML files with search, role filters, a resource inventory, collapsible containers, draggable resources and containers, connected-edge highlighting, a minimap, saved browser layouts, and a right-side resource inspector.
Archive audit evidence:
changegate scan --plan tfplan.json --audit-bundle changegate-audit.zipSee output formats and audit evidence.
ChangeGate can ingest findings from other scanners and normalize them into the same decision, waiver, baseline, graph-correlation, and output model as native findings. Keep tools like Checkov, Trivy, KICS, Grype, and SARIF-producing scanners while using ChangeGate as the deployment risk gate.
changegate scan --plan tfplan.json --import-sarif checkov.sarif
changegate scan --plan tfplan.json --import-checkov checkov.json
changegate scan --plan tfplan.json --import-trivy trivy.json
changegate scan --plan tfplan.json --import-kics kics.json
changegate scan --plan tfplan.json --import-grype grype.jsonChangeGate does not install or run external scanners. It reads existing JSON or SARIF artifacts, deduplicates repeated findings, correlates imported findings to changed graph resources where possible, and keeps native ChangeGate findings authoritative when richer graph evidence exists.
See external scanner adapters.
name: infrastructure-risk
on:
pull_request:
paths:
- "infra/**"
permissions:
contents: read
security-events: write
jobs:
changegate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: hashicorp/setup-terraform@v3
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
- name: Terraform plan
working-directory: infra
run: |
terraform init
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
- name: Install ChangeGate
env:
CHANGEGATE_VERSION: vX.Y.Z
CHANGEGATE_INSTALL_DIR: ${{ runner.temp }}/changegate-bin
run: |
curl -fsSL "https://raw.githubusercontent.com/Gabriel0110/changegate/${CHANGEGATE_VERSION}/scripts/install.sh" -o /tmp/install-changegate.sh
bash /tmp/install-changegate.sh
echo "${CHANGEGATE_INSTALL_DIR}" >> "${GITHUB_PATH}"
- name: ChangeGate scan
id: changegate
working-directory: infra
run: |
status=0
changegate scan --plan tfplan.json --format sarif --out changegate.sarif || status=$?
changegate scan --plan tfplan.json --format github-step-summary --out "$GITHUB_STEP_SUMMARY" || true
echo "exit_code=$status" >> "$GITHUB_OUTPUT"
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@4c50b6f6fd9dc6fe03111c2d045c8be2a724cce1 # v3.28.11
with:
sarif_file: infra/changegate.sarif
- name: Enforce ChangeGate decision
if: always() && steps.changegate.outputs.exit_code != '0'
run: exit "${{ steps.changegate.outputs.exit_code }}"See GitHub Actions, GitLab CI, Atlantis, and Terraform Cloud/Enterprise.
Define deterministic risk test manifests for Terraform/OpenTofu module fixtures and run them with changegate test. Risk tests assert ChangeGate decisions, required or forbidden findings, attack paths, graph paths, risk movement, waiver state, and stable output snapshots. See risk tests.
ChangeGate also includes a sanitized example corpus that doubles as executable documentation:
changegate test examples/risk-testsAdopt ChangeGate in phases:
- Run in audit mode and collect evidence.
- Create a baseline for existing risks.
- Enforce only new findings with
--new-only. - Add expiring waivers for accepted temporary exceptions.
- Move from audit to warn to block once the signal matches your deployment policy.
changegate scan --plan tfplan.json --mode audit --audit-bundle changegate-audit.zip
changegate baseline create --plan tfplan.json --out .changegate/baseline.json
changegate scan --plan tfplan.json --baseline .changegate/baseline.json --new-onlychangegate init --baseline --waivers --audit-mode can scaffold the repository files used by this rollout path.
See audit rollout, baselines, and waivers.
ChangeGate works with no config, but .changegate.yaml can tune policy, modes, rule packs, waivers, baselines, custom docs links, custom YAML rules, and custom Rego policies.
Run changegate init --dry-run to preview a starter .changegate.yaml before writing it.
mode: block
thresholds:
block:
min_severity: high
min_confidence: high
baseline:
file: .changegate/baseline.json
mode: new-findings-only
waivers:
file: .changegate/waivers.yaml
require_expiration: trueSee policy config, config schema, and custom policy.
Want to see ChangeGate output before wiring it into your own pipeline? Start with the public admin path demo, which includes a sanitized plan fixture, scan output, PR/MR comment output, attack-path output, and graph visualizations.
For additional runnable fixtures and validation coverage, see the validation matrix and risk tests.
Additional examples:
ChangeGate is on the stable v1.x release line. Start in audit or warning mode against real Terraform/OpenTofu plans, then move to blocking when the signal matches your deployment policy. It includes stable exit codes, JSON/SARIF-oriented output, signed-release infrastructure, baselines, waivers, rule documentation, security reporting, and AWS architecture visualization.
See known limitations for current scope and boundaries.
Start here:
- Start here
- Five-minute quickstart
- Rule reference
- Validation matrix
- GitHub Actions
- CI adoption
- Troubleshooting
- FAQ
Operators:
- Audit rollout
- Baselines
- Waivers
- Cloud context
- AWS architecture visualization
- Security model
- Known limitations
Reference:
- Architecture
- Decision model
- Security Impact Statement
- Review Intelligence
- Performance and scale
- JSON report schema
- Graph JSON schema
- OPA input schema
Issues and pull requests are welcome. For substantial behavior changes, open an issue first so the expected user impact can be discussed before implementation.
Read CONTRIBUTING.md before opening a pull request.
Please do not open public issues for suspected vulnerabilities. Use the private reporting process in SECURITY.md.
ChangeGate is released under the Apache License 2.0.
Third-party notices for embedded detection metadata are listed in THIRD_PARTY_NOTICES.md.

