doc/user/application_security/detect/sarif.md
{{< details >}}
{{< /details >}}
{{< history >}}
sarif_ingestion.
Disabled by default.{{< /history >}}
[!flag] The availability of this feature is controlled by a feature flag named
sarif_ingestion. For more information, see the history.
Use third-party SARIF reports to add findings from any SARIF 2.1.0 scanner into GitLab vulnerability management. A CI/CD job runs a SARIF-producing scanner and adds a SARIF artifact. GitLab parses, validates, and adds the artifacts as security findings.
After you add the report, findings appear alongside findings from native GitLab scanners in the following pages:
Third-party SARIF reports complement the built-in scanners that GitLab offers. Use them to integrate a third-party scanner that GitLab does not provide natively, or to consolidate findings from a tool you already run.
To add SARIF findings into GitLab:
Prerequisites:
In your .gitlab-ci.yml file, define a job that runs the scanner and saves its
SARIF output as an artifacts:reports:sarif artifact. Example:
sarif_scan:
image: <scanner-image>
script:
- <scanner-command> --output sarif.json
artifacts:
reports:
sarif: sarif.json
Commit and push the change. GitLab parses the SARIF file when the job completes.
View the added findings in the pipeline Security tab.
For the CI/CD artifact reference, see
artifacts:reports:sarif.
GitLab assigns a vulnerability report type for each SARIF finding based on the finding's location and identifiers. The type determines where the finding appears in the vulnerability report and how it interacts with security policies.
GitLab evaluates the following rules in order and assigns the first type that matches the finding.
| Rule | Assigned report type |
|---|---|
| Any identifier is a CVE. | Dependency scanning |
| Any identifier is a secret-related CWE. <sup>1</sup> | Secret detection |
| Default (none of the rules matched) | SAST |
Footnotes:
The following CWEs are secret-related:
GitLab reads identifiers from three sources in a result and its rule, in this order:
result.ruleId when the entry matches the format CVE-YYYY-N or CWE-N.rule.properties.tags[] when the entry matches the format cwe:N, cwe-N,
cve:YYYY-N, or cve-YYYY-N.rule.relationships[] when the relationship's
target.toolComponent.name is CWE.[!note] Findings without a CVE or supported CWE identifier are assigned as SAST. To change the type that GitLab assigns, configure your scanner to emit a matching CVE or CWE identifier.
GitLab assigns SARIF fields to fields that are compatible with GitLab according to the following rules.
| GitLab field | SARIF source | Required | Notes |
|---|---|---|---|
| Severity | See Severity resolution | {{< no >}} | Defaults to medium when no severity field is set. |
| Primary identifier | result.ruleId is matched to the corresponding value in run.tool.driver.rules[].id | {{< yes >}} | Findings without a ruleId are not added. |
| Secondary identifiers | rule.properties.tags[] and rule.relationships[] | {{< no >}} | Used to assign the report type. |
| Location | result.locations[0].physicalLocation | {{< yes >}} | Findings without a physical location are not added. |
| Scanner name | run.tool.driver.name | {{< yes >}} | Required for a valid SARIF |
| Scanner vendor | run.tool.driver.organization, then run.tool.driver.informationUri | {{< no >}} | First non-empty value is used |
| Scanner version | run.tool.driver.version, then run.tool.driver.semanticVersion | {{< no >}} | First non-empty value is used |
| Suppression | result.suppressions[] | {{< no >}} | Suppressed results are skipped unless every suppression is underReview or rejected. |
GitLab resolves the severity of a SARIF finding by checking the following fields in priority order. The first field that has a value is used.
result.rank. A float from 0.0 to 100.0.rule.properties.security-severity. A float from 0.0 to 10.0. The value is multiplied by 10 before bucketing.result.properties.security-severity. A float from 0.0 to 10.0. The value is multiplied by 10 before bucketing.result.level.rule.defaultConfiguration.level.medium as the default if no other matches.Numeric scores from result.rank or security-severity are assigned as severities
using these ranges:
| Score (0-100) | Severity |
|---|---|
0.0-9.9 | Info |
10.0-39.9 | Low |
40.0-69.9 | Medium |
70.0-89.9 | High |
90.0-100 | Critical |
SARIF level values are mapped as follows:
level | Severity |
|---|---|
error | High |
warning | Medium |
note | Low |
none | Info |
[!note] GitLab assigns
level: errorto high, not critical. To report a critical finding, setresult.rankto90or higher, or setsecurity-severityto9.0or higher.
When the SARIF file is well-formed but some of the results cannot be added, GitLab uses the percentage of results that it could not process to decide what to do with the scan as a whole.
| Drop rate | Behavior | Reported as |
|---|---|---|
| 0% | All findings are ingested. | No message. |
| 1% to 50% | The valid findings are ingested. | Warning with drop count. |
| More than 50% | The whole scan fails. No findings from the report are ingested. | Error with drop count. |
GitLab cannot process a result in any of the following cases:
ruleId is missing.physicalLocation is missing.The drop rate is calculated across the entire SARIF artifact, not for each run in the file. When
the share of unprocessable results across all runs exceeds the threshold, the
ingestion feedback is applied to every report emitted from the artifact.
Schema validation errors and unsupported SARIF versions cause the whole report to be rejected, regardless of drop rate.
A SARIF file can contain multiple tool runs, each with its own runs[] entry. For each run,
GitLab groups the findings by inferred report type and creates a separate scan record
for each group. A run that contains findings of more than one inferred type
produces more than one scan record. Each scan uses the run's tool.driver.name
as its scanner.
Use multi-run reports to combine the output of several scanners into a single artifact. For example, a job can run two scanners and emit a single SARIF file that contains two runs.
For the per-file run limit, see limits.
| Limit | Default | Configurable |
|---|---|---|
| Maximum SARIF artifact size | 10 MB (ci_max_artifact_size_sarif) | {{< yes >}} |
| Maximum runs per SARIF file | 20 | {{< no >}} |
| Maximum results per run | 5,000 | {{< no >}} |
| Maximum rules per run | 25,000 | {{< no >}} |
| Maximum tags per rule | 10 | {{< no >}} |
Maximum rule.name length | 255 characters | {{< no >}} |
Maximum shortDescription.text length | 1,024 characters | {{< no >}} |
Maximum fullDescription.text length | 1,024 characters, truncated to 255 when used as finding title | {{< no >}} |
Maximum message.text length | 1,024 characters, truncated to 255 when used as finding title | {{< no >}} |
Maximum helpUri length | 2,048 characters | {{< no >}} |
| Supported SARIF versions | 2.1.0 only | {{< no >}} |
When a per-run count exceeds its limit, GitLab process the first N entries and records a warning. When a result has a string field that exceeds its character limit, the whole result is skipped and counted toward the drop rate.
For GitLab Self-Managed instances, an administrator can change configurable limits through the instance limits.