The short version: the hard part of putting an AI security scanner in your pipeline isn't the AI — it's already solved by a boring file format. SARIF is the JSON schema GitHub's Code Scanning tab reads natively, and the new agentic scanners emit it on purpose. OpenAI open-sourced its Codex Security CLI (@openai/codex-security, Apache 2.0) in late July 2026 with diff-scoped CI scans and SARIF export; Anthropic shipped a Claude Security plugin on the same timeline. So the whole job is three steps — scan the diff, write results.sarif, upload it — plus one branch-protection setting that turns decoration into a blocking gate. Here it is, end to end.
Why SARIF is the whole trick#
Every scanner speaks a different dialect, but they can all export one lingua franca: SARIF (Static Analysis Results Interchange Format, OASIS 2.1.0). It's a JSON file listing each finding — rule id, severity, file, line, message, sometimes a fix. GitHub Code Scanning ingests SARIF 2.1.0 directly, so any SARIF-emitting tool — CodeQL, Semgrep, or Codex Security — lands in the same place with no custom code. The first question to ask a new scanner isn't "how smart is the model," it's "does it export SARIF?" If yes, everything below just works.
Step 1 — scan the diff in a GitHub Actions job#
Scan changed files only. Whole-tree scans on every PR are slow, and for a token-metered agentic scanner they're also expensive. A minimal job:
name: ai-security-scan
on: pull_request
permissions:
contents: read
security-events: write # required to upload SARIF
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 } # need history for a diff-scoped scan
- name: Run agentic scanner (diff-scoped)
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: npx @openai/codex-security scan --base "$GITHUB_BASE_REF" --format sarif --output results.sarif
That last line is the vendor-specific part — the Codex Security CLI documents diff-scoped CI scanning and a SARIF --format/export step; check the CLI quickstart for the exact subcommands, because the contract that matters here is only this: it writes a results.sarif. Swap in Semgrep (semgrep --sarif --output results.sarif) or any other tool and the rest of the pipeline is identical.
Step 2 — upload the SARIF#
One official action does it. This is the piece that makes findings appear inline on the diff and in Security → Code scanning:
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: codex-security # distinct category per tool
The category matters if you run more than one scanner: it namespaces results so a Semgrep run and a Codex run don't overwrite each other. GitHub merges them in the same tab, each tagged by source.
The format is the integration. Once a scanner emits SARIF, adding it to your pipeline is a five-line job — and removing it is deleting that job. That's the freedom you want; don't let a vendor talk you out of it.
Step 3 — make it block, not just annotate#
By default, Code Scanning is advisory: it decorates the PR, and anyone can merge past a red finding. To turn it into a gate, go to your default branch's branch protection rule or ruleset and enable code-scanning merge protection, requiring the Code Scanning results check to pass — with a severity threshold (block on high/critical). Now a qualifying finding fails the PR check and merge is blocked until it's fixed or dismissed with a reason. The blocking behavior lives in branch protection, not in the scanner — a detail teams miss, then wonder why their "gate" never stopped anything.
The one setting that decides whether this works#
AI scanners are recall-happy — they reason about code paths, which is exactly why they catch indirect injection and auth-bypass flows a pattern matcher misses, and exactly why they raise more false positives. If your first move is to block on everything, the team mutes the check within a week, and a muted gate protects nothing.
Calibrate first:
- Week one, report-only. Run the scanner on a non-critical service (or on your main repo without the required check) and just collect noise. Watch the false-positive rate per severity band.
- Then gate narrow. Set the blocking threshold where the signal is trustworthy — usually high/critical only to start — and let medium/low land as advisory annotations.
- Feed back dismissals. Codex Security takes false-positive feedback; use it so the tool learns your baseline instead of relearning it every PR.
The setup worth copying#
Pair two layers. A deterministic scanner (Semgrep or CodeQL) runs on every push — fast, cheap, predictable — as the floor you always have. An agentic scanner (Codex Security, or the Claude Security plugin) runs on pull requests, diff-scoped, as the second reviewer that reasons about the changes. Both emit SARIF into the same Code Scanning tab under different categories. You get deterministic coverage for free and pay the model only where its judgment earns it. That's the whole architecture — and because it's all SARIF, every part of it is swappable the day something better ships.



