notra·
CI/CD integration

Notra in GitHub Actions.

Deploy, then gate: one step that starts an audit against the freshly-deployed target, polls until it finishes, and fails the build if a verified critical or high finding shipped. No GitHub App, no webhook, no marketplace install — any step that can run curl can gate on Notra. (On GitLab instead? The GitLab CI version uses the same script unchanged.)

How the gate works

Start the audit

After your deploy step, the workflow starts a Notra audit against the target that just shipped — same scan, same verified findings as the dashboard.

Poll, don't block

An audit takes minutes, so the script polls a cheap status read instead of holding one HTTP request open for the whole run.

Exit non-zero on crit/high

The gate reads the scan's stored severity counts and fails the job if anything at or above your threshold shipped. Verified findings only — every one carries its own proof.

What the step looks like

The gate script (notra-gate.sh) does the start → poll → exit-code sequence for you. It is a small, readable bash file — vendor it into your repo rather than fetching it at CI time if you want that supply chain pinned.

.github/workflows/deploy.yml — illustrativecontract lives in the docs
# Illustrative shape, not a copy-paste contract — the endpoints, auth, and the
# gate script's env contract are documented at /docs/ci-cd and /docs/api.
- name: Notra security gate
  env:
    NOTRA_API_KEY: ${{ secrets.NOTRA_API_KEY }}   # API key from the Notra dashboard
    NOTRA_TARGET: staging.example.com
    NOTRA_FAIL_ON: high        # critical | high | medium | low | info (default high)
  run: |
    curl -O https://your-notra-domain/notra-gate.sh
    chmod +x notra-gate.sh
    ./notra-gate.sh
    # exit 0 = pass · 1 = findings at/above threshold · 2 = could not start / timed out

The same step can use the workflow's built-in GITHUB_TOKEN if you also want a PR comment when the gate fails — but nothing Notra-side requires one. The exact endpoints, auth header, and env contract are documented in the CI/CD gate docs and the API reference.

Before your first run

An API key

Generate one in the Notra dashboard. It is org-scoped and bearer-authenticated — treat it like any deploy secret and put it in GitHub secrets, never in the YAML.

An authorized domain

The target must already be ownership-verified for your org, the same gate as a dashboard scan. An unauthorized domain is refused outright — the API will not scan what you cannot prove you own.

A scan credit

The gate runs a real audit, so it consumes a credit like one. If the org is out, the API says so and links the checkout instead of failing silently.

Questions before you wire it up

Does this need a GitHub App, webhook, or marketplace install?

No. Notra is deliberately CI-agnostic: the gate is a small shell script plus a REST call, so anything that can run curl — GitHub Actions, GitLab CI, Jenkins, a cron job — can gate on it. That is why the same script works unchanged in the GitLab CI version of this page.

What actually happens when the gate fails?

The step exits non-zero and the job goes red. The findings themselves live in the dashboard report and on the findings endpoint — every one carrying the exact request/response that proved it — so the engineer who picks up the failure can reproduce it immediately. Fix, push, re-run.

Why start-and-poll instead of one blocking request?

A real audit takes minutes — longer than an HTTP request should hold a CI step open. So the script starts the scan, polls a cheap status read, and only then asks the gate endpoint for the verdict, which is a synchronous read of the scan's already-stored severity counts, not a blocking wait.

The full contract is two short docs pages.

Endpoints, auth, error codes, and the gate script's env contract — everything the snippet above deliberately leaves out.

Read the integration docs

Related: the CI/CD gate reference, the REST API, running Notra from your AI assistant via the MCP server, a sample verified report, and what the credits cost.