sarif-kit
Convert the native output of scanners and linters into valid SARIF 2.1.0, ready for GitHub Code Scanning.
pip-audit, codespell and yamllint all report things worth fixing, and none of them can
emit SARIF, the format GitHub Code Scanning reads.
The feature requests asking for it have been open for years, the codespell one since 2020.
sarif-kit converts what those tools already print into SARIF you can hand straight to
github/codeql-action/upload-sarif.
In GitHub Actions
Run the tool the way you already do, convert what it printed, then upload:
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v7
- name: Lint YAML
run: pipx run yamllint -f parsable . > yamllint.txt || [ $? -eq 1 ]
- name: Convert to SARIF
uses: sarif-kit/sarif-kit@v0.1.1
with:
tool: yamllint
input: yamllint.txt
output: yamllint.sarif
- name: Upload to Code Scanning
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: yamllint.sarif
category: yamllint
The action runs from a prebuilt container image, so nothing installs Python on your
runner. Give each tool its own category on upload. Without that, they overwrite each
other's alerts.
| input | required | meaning |
|---|---|---|
tool |
yes | pip-audit, yamllint, codespell, or auto to detect it from the input |
input |
yes | file holding the tool's native output |
output |
no | SARIF file to write, defaults to results.sarif |
src-root |
no | repository root, used to rewrite absolute paths as relative ones |
dep-file |
no | manifest that pip-audit findings point at, defaults to requirements.txt |
fail-on-findings |
no | set to true to exit 1 when the converted file has findings |
The guard on the lint line matters. Most linters exit nonzero when they find something, and you want the job to carry on to the upload rather than stop at the scan. Each adapter page below gives the exact capture command for that tool, since the exit codes differ.
sarif-kit/demo is a repository broken on purpose that runs all three tools this way, if you want to see the alerts before wiring anything up.
On your machine
Either of these puts a sarif-kit command on your PATH:
uv tool install sarif-kit
pipx install sarif-kit
For a one-off run without installing anything, uvx sarif-kit works too.
Python 3.11 or newer. The only dependency is jsonschema.
yamllint -f parsable . > yamllint.txt || [ $? -eq 1 ]
sarif-kit convert --tool yamllint -i yamllint.txt -o results.sarif
Supported tools
- pip-audit: one alert per advisory, linked to its osv.dev page and reported as an error
- yamllint: line and column preserved, yamllint's own error and warning levels kept
- codespell: one rule per typo, so alerts read
"lenght" should be "length"instead of all sharing a title
Here is a pip-audit finding as GitHub renders it, converted by sarif-kit:
Commands
sarif-kit convert (--tool NAME | --auto) -i PATH -o PATH [--src-root PATH] [--dep-file PATH] [--fail-on-findings]
sarif-kit validate PATH
sarif-kit merge -o PATH INPUT [INPUT ...]
--auto works out the adapter from the shape of the input, and refuses to guess when the
input matches nothing or matches two tools at once. -i and -o accept - for stdin and
stdout. --src-root rewrites absolute paths relative to your repository root, which is
what makes the file links in an alert resolve. merge combines SARIF files into one
upload, one file per tool, because GitHub rejects a file whose runs share an analysis
category.
| exit code | meaning |
|---|---|
| 0 | success |
| 1 | findings present under convert --fail-on-findings, or the file failed validation under validate |
| 2 | conversion, usage or IO error |
Full reference: man -l man/sarif-kit.1 from a clone.
Nearby tools that sound similar
- microsoft/sarif-tools and the "SARIF Converter" Marketplace action go the other way, turning SARIF into CSV or HTML. sarif-kit produces the SARIF they read.
- MegaLinter and reviewdog want you to adopt their whole pipeline. sarif-kit is one command you drop into the CI you already run.
- node-sarif-builder is a library for tool authors writing SARIF by hand. sarif-kit is the finished converter for people who just want a scanner's findings in the Security tab.
Status
The converter core, the first three adapters, the CLI and the GitHub Action are done, covered by 124 tests with golden files for every adapter. From here the adapter order follows whatever people actually ask for, with ty and vulture the current front runners.
Passing the schema is not what makes an adapter finished here. Every adapter is uploaded to a real repository and inspected in GitHub's Code Scanning UI, and if the alert does not show the right title, severity and file link, it goes back. The action gets the same treatment: it is not documented here until it has run green in the demo repository and the alerts it produced have been read.
Development
uv sync
uv run pytest # unit, golden and schema tests
UPDATE_GOLDEN=1 uv run pytest # refresh golden files after an intentional change
The upload gate
A schema-valid file can still be turned away by GitHub, which applies rules of its own, so the real test is an upload. The "Upload gate" workflow does exactly that. Start it from the Actions tab, and it runs each supported tool against its committed fixture, converts the fresh output with the CLI built from that commit, uploads one SARIF per tool, then merges two of them and uploads the combined file as well.
Afterwards, look under Security, then Code scanning. Every alert should carry the right title and severity and link to a real line of a real file. Running the gate on a fork needs Code Scanning enabled, which is free on public repositories and needs GitHub Advanced Security on private ones.
To build the minimal gate file locally:
uv run python scripts/gate_minimal_sarif.py gate.sarif
Metadata
Release files for sarif-kit 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sarif_kit-0.1.1.tar.gz | 543.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sarif_kit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 584.9 kB
Release files / sarif_kit-0.1.1.tar.gz
| Download URL | sarif_kit-0.1.1.tar.gz |
|---|---|
| Size | 543.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12b72bb62889161fb33bb7c7f61ff7b4d80b8275f15845536d268703948045fb
|
|
BLAKE2b-256 checksum How to use checksums |
08d40e0bfa21fcfb7ceae13a03d2cbe189b6b48a11384831fd850d5f66acbc28
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency logRelease files / sarif_kit-0.1.1-py3-none-any.whl
| Download URL | sarif_kit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 41.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
903ea012824e95221e52558983019f109f3dd006201d8da0c36605ca63e2476a
|
|
BLAKE2b-256 checksum How to use checksums |
5a6a402a9132b41c147597d33a082624390ee689f12a0dfaf980a9b08cc05bf8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency log