> ## Documentation Index
> Fetch the complete documentation index at: https://gecko.security/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SARIF export

> Export findings as SARIF 2.1.0 for any tool that reads SARIF.

Gecko exports findings as [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html),
the format GitHub code scanning, GitLab, Azure DevOps, and most security
dashboards read. Download a file from the app, or pull one from the API in CI
and upload it wherever your team already reviews alerts.

## Export from the app

| Where | How |
| - | - |
| Repository page | **Export to**, pick the statuses to include, then **SARIF** |
| Repositories table | Row menu > **Export to** > **SARIF** |
| Findings list | Right-click a status group > **Export to** > **SARIF** |
| Finding drawer | Export menu > **SARIF** |
| Scan page | **Export** > **SARIF** |

The same menus also export CSV, Markdown, and JSON.

## Export from the API

`GET /vulnerabilities/sarif` returns one SARIF file for every finding that
matches your filters. It takes the same filters as
`GET /vulnerabilities` in the [v1 API](https://gecko.security/docs/api-reference/introduction.md): `repository`, `scan_id`,
`status`, `severity`, `type`, `cwe`, `pull_request`, `created_after`, and
`created_before`. The key needs the `vulns.read` permission, so a
[service account](https://gecko.security/docs/admin/service-accounts.md) with the **Read Only** role is
enough.

```bash theme={null}
curl "https://app.gecko.security/api/v1/vulnerabilities/sarif?repository=acme/api" \
  -H "Authorization: Bearer $GECKO_API_KEY" \
  -o gecko.sarif
```

Gecko never truncates an export, because a partial upload would close the
alerts it leaves out. If the filters match more than 10,000 findings, or span
more than 20 repositories (GitHub's limit for one file), the request fails with
`export_too_large`. Narrow it with `repository`, `scan_id`, `status`, or
`severity`.

## Upload to GitHub code scanning

Run the export on a schedule and upload the result with GitHub's
`upload-sarif` action. Store a service account token as the `GECKO_API_KEY`
repository secret.

```yaml .github/workflows/gecko-sarif.yml theme={null}
name: Gecko findings
on:
  schedule:
    - cron: "0 6 * * *"
  workflow_dispatch:

permissions:
  security-events: write

jobs:
  upload:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Export Gecko findings
        run: |
          curl --fail-with-body \
            "https://app.gecko.security/api/v1/vulnerabilities/sarif?repository=${{ github.repository }}" \
            -H "Authorization: Bearer ${{ secrets.GECKO_API_KEY }}" \
            -o gecko.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: gecko.sarif
```

Gecko findings then appear under **Security** > **Code scanning** next to your
other tools, and close there as they are fixed in Gecko.

## What the file contains

* **One run per repository.** Each run's `automationDetails.id` is
  `gecko/<repository>/`, so repeated uploads update the same alerts instead of
  creating new ones.
* **One rule per finding**, with its CWE as an `external/cwe/cwe-N` tag and its
  CVSS score as `security-severity`. Critical and high map to `error`, medium
  to `warning`, and low to `note`.
* **The call chain** as a `codeFlow`, from source to sink.
* **A stable fingerprint** in `partialFingerprints["geckoFingerprint/v1"]`, so
  an alert keeps its identity across scans.
* **Triage state.** Findings marked **False positive** or **Accepted risk** are
  included as suppressed results, so code scanning dismisses them too. Fixed
  findings are left out, which closes their alerts.
* **Gecko context** in each result's `properties`: `status`, `scanId`,
  `cvssVector`, `commitSha`, and `branch`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.