Run Granska on every pull request: real scanner CLIs as ground truth, then LLM review lanes that triage and adversarially verify every high-severity finding before it ships. Findings gate the merge, upload to the code-scanning tab, and land as one sticky PR comment.
The Action is distributed from
dohgren-dev/granska-action
and is free for public repositories.
Quick start
name: granska
on:
pull_request:
permissions:
contents: read
security-events: write
pull-requests: write
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: granska
uses: dohgren-dev/granska-action@v2.0.0
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
target: .
scope: quick
fail-on: high
max-cost: '5'
Scope profiles
quick(default) — fast SAST + secrets + security-critical LLM lanes, sized for PR latency.full— every scanner + every LLM lane; run on a schedule.dast—fullplus a live DAST pass against a running target.
Cost
Measured on claude-sonnet-5, ubuntu-latest: ~$2 per quick-scope run
on a small target (cost.json is emitted every run, even aborted ones). You
bring your own Anthropic API key — Granska never proxies or meters your CI
compute.
Waivers and the code-scanning tab
Accepted findings go in .granska/baseline.yml. SARIF uploads to
Security → Code scanning once enabled for the repo; the upload step
degrades gracefully (continue-on-error: true) if it isn’t.
Full reference (all inputs/outputs, fork-PR limitations, nightly full-scope
example): docs/CI.md
in the repo.