Gate pull requests in CI
Run the CBX Guard engine on your Terraform plan in GitLab CI or GitHub Actions. A dangerous change fails the pipeline and blocks the merge, with the verdict posted as a PR/MR comment.
Gate pull requests in CI
The CBX Guard gate runs the same deterministic engine that watches your live cloud, but before a change ships — over a Terraform plan in your pipeline. A broad-internet ingress to a sensitive port on a production security group makes the engine exit non-zero, which fails the job and blocks the merge, and the verdict is posted as a pull-request / merge-request comment.
There are two ways to run it:
- Managed by the Console. When you enable the gate while connecting a repository (or from Getting started), CBX Guard posts the
cbxguard/policycheck for you — via the GitHub App's webhook, or a merge request that adds the job on GitLab. - In your own CI. Add the workflow below yourself. This page is the reference for that job — the same engine, same flags, whichever CI you run.
The default path is credential-free: it plans offline from empty state (plan_only=true + dummy AWS creds), so the gate runs on the very first PR with zero cloud secrets. For a real diff against your deployed baseline, swap in your remote-state backend.
This is one of two lanes. The CI gate reasons about the diff alone, offline. CBX Guard also runs an independent account-aware review on its own servers that resolves the same change against your captured live account — and can reach a sharper verdict on a diff the offline gate passes as clean. See Two lanes.
How the gate decides
Every gate job does the same three things:
- Render the plan.
terraform plan→terraform show -jsonproducesplan.json. - Run the engine. The
cloudguardCLI evaluates the plan and writes a machine report. - Report + gate. A human report is posted as a PR/MR comment, and the step exits non-zero when the change is gated — that non-zero exit is what fails the pipeline.
The CLI is an unpublished private workspace package, so the job runs it straight from a pinned checkout of the cbx-guard repo with Bun. Pin CBX_GUARD_REF to a commit you've verified and bump it deliberately.
Key flags:
| Flag | Meaning |
|---|---|
--provider terraform | The plan format being evaluated. |
--account / --region | The URN coordinates for the change. |
--trusted-cidr | Your office/VPN CIDR, so legitimate admin ingress isn't flagged. |
--fail-on | The gate floor. watch is recommended: a fresh exposure resolves to watch offline (reachability can't be confirmed from a plan), so high would let it pass. |
--suppressions | Added only when .cbxguard/suppressions.yaml exists (see below). |
Conditional --suppressions hardening. The flag is passed only when the suppressions file is present. This keeps the invocation identical across GitLab and GitHub and, crucially, decouples the gate from a suppress-capable CLI: a pinned CBX_GUARD_REF that predates the flag no longer fails with a usage error. Never pass --suppressions unconditionally.
GitLab CI
Include the reusable job and wire it into a guard stage. It clones the pinned cbx-guard via the built-in CI_JOB_TOKEN (the cbx-guard project allowlists the job token for inbound CI, so no long-lived secret is needed).
Set AWS_ACCOUNT_ID, AWS_REGION, and OFFICE_CIDR as CI/CD variables. GUARD_REPORT_TOKEN (optional) lets the job post the report as an MR comment.
These mirror the canonical reference templates, ci/cb-guard.gitlab-ci.yml and ci/cb-guard.github.yml. The terraform plan line takes whatever -vars your configuration needs — the reference templates pass plan_only=true (offline plan) plus a dummy value for their sample stack's variables. Keep plan_only=true for the credential-free path; add your own -vars as your Terraform requires.
GitHub Actions
The GitHub job is the twin of the GitLab one — same engine, same flags — only the CI plumbing differs. Add it as .github/workflows/cb-guard.yml.
Configure the repo (Settings → Secrets and variables → Actions):
- Variables:
AWS_ACCOUNT_ID,AWS_REGION,OFFICE_CIDR(your trusted office/VPN CIDR). - Secrets:
CBX_GUARD_TOKEN— a read-only token for the privatecbx-guardrepo. GitHub has no cross-repoCI_JOB_TOKENequivalent, so this one secret is required. The built-inGITHUB_TOKENauthors the PR comment.
Make it block merges
The job failing isn't enough on its own — mark it a required status check:
- GitHub: Settings → Branches → branch protection rule for your default branch → Require status checks to pass before merging → select CBX Guard.
- GitLab: the
guardjob runs on merge requests; require the pipeline to succeed under Settings → Merge requests → Pipelines must succeed.
Suppressing a known finding
To waive a finding you've reviewed, commit .cbxguard/suppressions.yaml to the repo. When the file is present, the job passes it to the engine and the waived finding passes with a warning instead of failing the gate. When it's absent, the flag is omitted entirely (the hardening above).
Next steps
- Connect a repository — GitHub App or GitLab OAuth/bot, then arm the managed gate.
- Getting started — connect a repo and a cloud account, enable the gate, read your first verdict.