GitHub Action¶
rossedman/sarifix is a GitHub Action that runs sarifix in a workflow. It installs a verified sarifix release and the scanners your sarifix.yaml names, then scans. What happens next depends on the event:
- Pushes, schedules and manual runs: it uploads the scan to code scanning and keeps one issue per batch (
sarifix fix --mode issues), for Claude or a person to fix. - Pull requests: it reports the findings the change introduced in the job summary and as annotations on the changed lines.
Quick start¶
Add a sarifix.yaml to the repository (the configuration guide explains it), then save this as .github/workflows/sarifix.yml:
# sarifix with the sarifix GitHub Action. On pushes to main, weekly and on
# demand it scans, uploads to code scanning and keeps one issue per batch for
# Claude (the task-queue plugin's agent-queue.yml) or a person to fix. On
# pull requests it reports what the change introduced.
name: sarifix
on:
push:
branches: [main]
pull_request:
schedule:
- cron: "23 6 * * 1" # Mondays
workflow_dispatch:
permissions: {}
concurrency:
group: sarifix-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
sarifix:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
actions: read # upload-sarif reads the run's metadata on private repos
security-events: write # code scanning upload
issues: write # one issue per batch
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # pull requests are compared with their merge base
persist-credentials: false
# Installs sarifix and the scanners sarifix.yaml names, then scans.
# SARIFIX_QUEUE (a repository variable) above 0 labels that many
# issues agent-ready, which starts paid agent runs; leave it unset to
# queue issues by hand.
# A tag reads better in an example; pin the tag's commit SHA in your repo.
- uses: rossedman/sarifix@v0.2.3 # zizmor: ignore[unpinned-uses]
with:
queue: ${{ vars.SARIFIX_QUEUE }}
That's the whole setup. Only rules listed in rules.allow become issues, and nothing is handed to an agent until you set the repository variable SARIFIX_QUEUE. Turn findings into issues Claude works through covers the agent side.
Modes¶
mode |
What it does | Permissions |
|---|---|---|
auto (default) |
check on pull requests, issues on every other event |
as below |
issues |
Scan, upload to code scanning, then open, refresh, close and queue one issue per batch | contents: read, security-events: write, actions: read (private repos), issues: write |
scan |
Scan and upload to code scanning only | contents: read, security-events: write, actions: read (private repos) |
check |
Scan the merge base and the pull request with the pull request's sarifix.yaml, then write the new findings to the job summary and as warnings. Needs fetch-depth: 0 |
contents: read |
install |
Install sarifix and the scanners, for a later step to use, such as an agent fixing a sarifix issue | contents: read |
Inputs¶
| Input | Default | Description |
|---|---|---|
mode |
auto |
One of the modes above |
config |
sarifix.yaml |
Path to the config |
scanners |
auto |
Scanners to install: auto (each scanner in the config that the action knows), none, or a comma-separated list. Scanners already on PATH are left alone |
upload-sarif |
true |
Upload the scan to code scanning (issues and scan modes) |
sarif-category |
sarifix |
The code scanning category |
queue |
(config) | Issues mode: how many issues to keep labeled agent-ready. Empty uses publish.issues.queue. Above 0, this starts paid agent runs |
dry-run |
false |
Issues mode: show the changes in the job summary without making them |
fail-on-new |
false |
Check mode: fail the step when the pull request introduces findings |
version |
the action's tag | The sarifix release to install, such as v0.2.3. Without a tag (a branch or SHA reference), the latest release |
install |
true |
Set false to use a sarifix already on PATH |
token |
github.token |
Token for the code scanning upload and the issues |
Outputs¶
| Output | Description |
|---|---|
mode |
The mode that ran |
sarif-dir |
Directory of the per-scanner SARIF files (issues and scan modes) |
opened, closed, queued |
Issues changed (issues mode) |
new |
Findings the pull request introduced (check mode) |
Scanners the action installs¶
With scanners: auto, each scanner in sarifix.yaml whose name is one of these is installed at a pinned version. Archives are checked against their release's published checksums, and Python scanners come from PyPI through pipx.
| Name | Version | From |
|---|---|---|
trivy |
0.76.1 | GitHub release, checksums |
golangci-lint |
2.15.0 | GitHub release, checksums. Needs Go: add actions/setup-go first |
gitleaks |
8.30.1 | GitHub release, checksums |
hadolint |
2.14.0 | GitHub release, checksum |
tfmetrics |
0.2.2 | GitHub release, checksums |
checkov |
3.3.30 | PyPI |
ruff |
0.17.1 | PyPI |
semgrep |
1.182.1 | PyPI |
The versions move with action releases, on purpose: a new scanner release adds rules, and those arrive as new issues. To use another version, or a scanner the action doesn't know, install it in an earlier step. The action leaves anything already on PATH alone.
Security¶
- The sarifix archive is checked against the release's
checksums.txt. The action doesn't verify that file's cosign signature; Supply chain shows how to, and pinning the action to a commit SHA fixes which release it installs. - Scan output goes to
$RUNNER_TEMP, outside the checkout, so no scanner reads another's output and nothing is committed. - Scanner messages in issues, annotations and job summaries are escaped, so they can't fake sarifix's markers, mention people, break tables or inject workflow commands.
- On pull requests from forks, the token is read-only. Check mode needs nothing more.