Every scanner in a modern pipeline speaks its own output dialect, and without a common format findings cannot be deduplicated, tracked across runs or trusted as audit evidence. SARIF, the Static Analysis Results Interchange Format, is the OASIS standard that fixes this by defining one JSON structure for results from static analysis, secret scanning, infrastructure as code checks and many dependency scanners. This guide explains what the standard contains, the properties that decide whether results are matched or duplicated, the security risks inside SARIF files themselves, and how to build a reliable SARIF pipeline. It is written for AppSec engineers, platform teams and auditors who consume or produce SARIF, and goes deeper than the ASPM Buyer's Guide, which covers the platforms that aggregate it.
Key takeaways
- Version 2.1.0 is the one to target. The current OASIS Standard is SARIF 2.1.0 Plus Errata 01 (28 August 2023), and GitHub code scanning accepts only 2.1.0.
- Fingerprints decide alert quality. Stable
ruleId, consistent relative paths andpartialFingerprintsare what stop every scan from creating a new set of duplicate alerts. - SARIF files are sensitive artefacts. They can carry code snippets, absolute paths with user names and, for secret scanners, the secret itself, so store and share them like source code.
- The upload credential is a non-human identity. A token with
security-events: writecan create, overwrite and in effect hide findings, so scope it per repository and keep it short-lived. - Validate before you ingest. Schema validation plus platform rule checks (size, runs, results, locations) catch most silent data loss before it reaches dashboards or auditors.
What it is and who it applies to
SARIF is a JSON format, standardised by the OASIS SARIF Technical Committee, for the output of static analysis tools. A SARIF file (conventionally with a .sarif extension) records which tool ran, what it analysed, which rules it applied and every result it produced, with precise locations, code flows, suggested fixes and suppression state. It does not tell you how to analyse code; it only standardises how results are reported, so any tool can feed any viewer, tracker or posture platform.
The format is used well beyond classic SAST. Secret scanners, infrastructure as code linters, container and dependency scanners and AI-assisted code reviewers commonly emit it, and code hosting platforms ingest it to show alerts in pull requests. SARIF matters to four groups:
- Tool producers: scanner authors and teams writing in-house checks, who must emit valid, stable SARIF.
- Pipeline owners: platform and DevSecOps teams who run scanners in CI and upload results. See the DevSecOps Guide.
- Consumers: AppSec teams, ASPM and vulnerability platforms that aggregate, deduplicate and prioritise findings. See the Application Security Posture Management (ASPM) Guide.
- Assurance: auditors and customers who accept scan output as evidence of secure development practice.
| Item | Status as checked 8 November 2026 |
|---|---|
| Standard | SARIF Version 2.1.0 Plus Errata 01, OASIS Standard incorporating Approved Errata, 28 August 2023 |
| Original 2.1.0 approval | Listed on the OASIS TC page as an OASIS Standard dated 27 March 2020 |
| Schema URI | https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json |
| Companion schema | External property file schema, for splitting large logs into separate files |
| Older versions | Pre-2.1.0 files should be converted, for example with the SARIF Multitool rewrite mode and --sarif-output-version Current |
Structure and key requirements
A SARIF log is a tree. The root sarifLog object (spec section 3.13) holds version, $schema and an array of runs. Each run (3.14) describes one invocation of one tool and contains its results. Knowing a handful of objects well is enough to read, debug and govern most files.
| Object or property | Spec section | What it holds | Why it matters for security teams |
|---|---|---|---|
run.tool (driver and extensions) | 3.14.6 | Tool name, version and rule metadata (reportingDescriptor, 3.49) | Proves which scanner and rule set produced the evidence |
run.automationDetails | 3.14.3 | Identifier for the analysis, for example category/run-id | Keeps parallel analyses of one commit from overwriting each other |
run.versionControlProvenance | 3.14.13 | Repository URI, revision and branch analysed | Links findings to an exact commit for audit |
run.invocations | 3.14.11 | Command line, working directory, success flag, tool notifications | Shows whether the scan actually completed; can leak paths and arguments |
run.artifacts and originalUriBaseIds | 3.14.15, 3.14.14 | Files analysed and the base URIs for relative paths | Relative paths keep fingerprints stable across build agents |
run.taxonomies | 3.14.8 | External classifications such as CWE | Lets results be reported against CWE or internal standards |
result.ruleId | 3.27.5 | The rule that fired | Must not change between runs or every alert is reopened |
result.kind and level | 3.27.9, 3.27.10 | Kind: notApplicable, pass, fail, review, open, informational. Level: none, note, warning, error | Drives gating; a missing level falls back to the rule default |
result.locations and codeFlows | 3.27.12, 3.27.18 | Physical and logical locations, data flow paths from source to sink | Needed to triage injection-type findings |
fingerprints and partialFingerprints | 3.27.16, 3.27.17 | Stable identifiers for a result across runs | Core of deduplication and new versus existing logic |
result.suppressions | 3.27.23, 3.35 | Kind inSource or external; status accepted, underReview, rejected; justification | Records risk acceptance; must be reviewed, not trusted blindly |
result.baselineState | 3.27.24 | new, unchanged, updated, absent against a baseline run | Supports "no new high findings" gates |
result.fixes | 3.27.30 | Proposed replacements in artefacts | Machine-applied fixes need review like any code change |
run.redactionTokens | 3.14.28 | Strings that replaced redacted sensitive values | Signals that the producer removed secrets or personal data |
Severity: level versus security-severity
The standard's level is a four-value scale aimed at all analysis, not just security. Platforms add their own security severity on top. GitHub code scanning reads a numeric properties.security-severity on the rule (greater than 0.0 up to 10.0) and maps it to alert severity: over 9.0 critical, 7.0 to 8.9 high, 4.0 to 6.9 medium, 0.1 to 3.9 low; 0.0 or out-of-range values mean no security severity. This is a platform property bag convention, not part of the OASIS schema, so other consumers may ignore it. Decide which field your gates use and document it. For vulnerability scoring itself, see the CVSS v4 Guide.
Platform ingestion limits
Consumers impose limits that the schema does not. GitHub's published limits are a useful reference for what "too big" means in practice:
| Item | GitHub code scanning limit | What happens beyond it |
|---|---|---|
| File size (gzip compressed) | 10 MB | Upload rejected |
| Runs per file | 20 | Rejected |
| Results per run | 25,000 | Only the top 5,000 by severity are shown |
| Rules per run | 25,000 | Rejected |
| Tool extensions per run | 100 | Rejected |
| Locations per result | 1,000 | 100 shown |
| Thread flow locations per result | 10,000 | Top 1,000 shown |
| Tags per rule | 20 | 10 shown |
Truncation is the quiet risk: a scanner that reports 30,000 results looks healthy in the pipeline while most findings never reach a human. Narrow the rule set or split analyses by category instead.
Identity and NHI requirements
SARIF itself has no identity model, but every SARIF pipeline runs on machine credentials, and the files carry data those credentials protect.
- Upload tokens: uploading to GitHub code scanning needs the workflow permission
security-events: write(plusactions: readon private repositories) and a user or app with write access. Grant it per job, not at workflow level, and prefer the built-in short-lived workflow token over long-lived personal access tokens. A stolen token with this scope can upload a clean SARIF file for the same tool and category and replace real results. See the GitHub and GitHub Actions Security Guide. - Aggregator service accounts: ASPM and vulnerability platforms that pull SARIF from many repositories hold broad read access to code and findings. Inventory them, scope them to the repositories they need and rotate their credentials. See the CI/CD Pipeline Identity Security Guide.
- Secrets inside results: secret scanners may place the detected secret in the message, snippet or region. Check whether your tool redacts (and records
redactionTokens); if it does not, treat the SARIF file as containing live credentials, restrict access and expire artefacts quickly. Revoke the secret, do not just close the alert. See the Developer Secret Scanning Triage. - Path and environment leakage: the specification itself warns (section 3.10.1) that URIs can reveal unwanted information such as a developer's account name in a file path. Absolute paths, command lines in
invocationsand environment variables can expose user names, internal hostnames and token values passed as arguments. - Suppression authority: an
inSourcesuppression is just a code comment any committer can add. Require review of new suppressions as you would a change to access policy.
Implementation steps
- Inventory producers and consumers. List every scanner, its SARIF support (native, plugin or converter) and every system that ingests results. Note which already emit fingerprints.
- Standardise on 2.1.0 and validate. Add a validation step after each scan: schema validation against the 2.1.0 schema, plus a consumer check such as the Microsoft SARIF validator or
Sarif.Multitool validate. Fail the job on invalid output, not silently skip upload. - Make results stable. Emit relative URIs with
originalUriBaseIds(or rebase with the Multitoolrebaseurimode), keepruleIdstable across tool upgrades and populatepartialFingerprints. GitHub notes that itsupload-sarifaction fills fingerprints if missing but the REST API does not, so compute them yourself for API uploads. - Separate analyses by category. Give each analysis of the same commit a unique category (
categoryinput,--sarif-categoryin the CodeQL CLI, or a uniquerunAutomationDetails.id). Without it, a second upload for the same commit and tool replaces the first. - Scope and protect the upload identity. Grant
security-events: writeonly to the upload job, pin third-party actions to commit SHAs and keep SARIF artefacts in restricted storage with short retention. - Pilot gating in report-only mode. For two to four weeks, record what a gate would block (for example, any new
erroror security severity of high or above withbaselineStatenew) without failing builds. Tune rules and fix fingerprint problems first. - Enforce, with a rollback path. Turn the gate on for a pilot ring of repositories, then widen. Keep a documented bypass (an approved, time-limited exception) and a switch back to report-only if a scanner upgrade floods results.
- Govern suppressions. Route new suppressions to review, require a justification, and report accepted suppressions by age. Link exceptions to the Vulnerability Risk Acceptance and Exception Template.
Choosing an approach
| Situation | Better choice | Trade-off |
|---|---|---|
| Small team, one code host, a few scanners | Upload SARIF directly to the code host's native alerting | Simple, but limited cross-tool deduplication and reporting |
| Many scanners, many repositories, audit reporting | Central aggregation (ASPM or vulnerability platform) consuming SARIF | Better correlation, but a privileged aggregator identity to secure |
| Tool emits its own format only | Convert (Multitool convert or vendor converter) | Converters may drop code flows and fingerprints; test fidelity |
| Very large monorepo | Split by category or language, or use external property files | More runs to correlate; must keep categories stable |
Evidence and assessment
SARIF is useful audit evidence precisely because it records tool, version, rules, commit and outcome together. To make it hold up:
- Completeness: check
invocations[].executionSuccessfuland tool notifications. A run that crashed on half the codebase still produces a valid file. - Provenance: keep
versionControlProvenanceand the tool driver version, and store files with a hash and timestamp so evidence cannot be swapped later. - Coverage: compare analysed artefacts with the repository inventory; files excluded by configuration do not appear as results.
- Suppression review: sample suppressions with status
acceptedand confirm each has a justification and an approver.
Metrics that show the pipeline is working:
- Share of repositories producing valid SARIF on every default-branch build (target: above 95 per cent).
- Duplicate alert rate after scanner upgrades or runner changes (a sudden rise means fingerprint or path drift).
- Upload rejections and truncations per week (target: zero truncated runs).
- Median age of open high and critical results, split by
baselineStatenewversusunchanged. - Count and age of accepted suppressions, and the share with a reviewed justification.
Mapping to other frameworks
| Framework | Reference | How SARIF supports it |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SA-11 Developer Testing and Evaluation; SA-11(1) Static Code Analysis | Standard record of static analysis performed and results |
| NIST SP 800-53 Rev. 5 | RA-5 Vulnerability Monitoring and Scanning; SI-2 Flaw Remediation | Feeds tracking from detection to fix, with baseline state |
| NIST SP 800-53 Rev. 5 | SA-15 Development Process, Standards, and Tools; CA-7 Continuous Monitoring | Consistent tool output across the SDLC and over time |
| NIST CSF 2.0 | ID.RA-01; PR.PS-06 | Vulnerabilities identified and recorded; secure development practices monitored |
| NIST SSDF (SP 800-218) | PW.7 code review and analysis; PW.8 testing executable code | Evidence format for analysis results. See the NIST Secure Software Development Framework (SSDF, SP 800-218) Guide |
| ISO/IEC 27001:2022 Annex A | A.8.28 Secure coding; A.8.29 Security testing in development and acceptance | Shows tests ran and findings were handled |
| CIS Controls v8.1 | Control 16 Application Software Security | Supports code-level security checks and tracking of flaws |
Common pitfalls
- Absolute paths from ephemeral runners: each build agent has a different working directory, so results look new every run and alerts churn. Rebase to relative URIs.
- Rule ID changes on upgrade: a scanner release that renames rules closes every old alert and opens new ones, wiping triage history. Test upgrades on a branch and map old to new IDs.
- Silent overwrite: two jobs uploading the same tool for the same commit without distinct categories, so one analysis replaces the other and coverage quietly drops.
- Trusting the file blindly: treating any valid SARIF as proof that a scan ran. A file with zero results and a failed invocation is still valid. Check execution success and expected result counts.
- Publishing secrets in artefacts: attaching unredacted secret scanning SARIF to public build logs or tickets. Treat it as credential material.
- Unreviewed suppressions: in-source suppression comments added in the same pull request that introduces the flaw, approved without anyone noticing.
Practitioner checklist
- Confirm every scanner emits SARIF 2.1.0 and convert or rewrite anything older.
- Validate every file against the schema and the consumer's rules before upload, and fail on errors.
- Emit relative paths, stable rule IDs and partial fingerprints; recompute fingerprints for API uploads.
- Give each analysis of a commit a unique category or automation ID.
- Scope
security-events: writeto the upload job and avoid long-lived personal tokens. - Check secret scanner output for unredacted secrets and restrict and expire SARIF artefacts.
- Monitor uploads for rejections, truncation and failed invocations.
- Gate on new results only after a report-only pilot, with a documented rollback.
- Review new suppressions and report accepted ones by age and justification.
Standards and references
- OASIS: Static Analysis Results Interchange Format (SARIF) Version 2.1.0 Plus Errata 01
- OASIS: Static Analysis Results Interchange Format (SARIF) Technical Committee
- OASIS SARIF TC: SARIF specification and schema repository
- GitHub Docs: SARIF support for code scanning
- GitHub Docs: Uploading a SARIF file to GitHub
- Microsoft: SARIF SDK Multitool usage
- NIST: SP 800-218 Secure Software Development Framework Version 1.1
- NIST: SP 800-53 Rev. 5
Related NHI Mgmt Group resources: CodeQL Guide · Semgrep Guide · SAST Triage Guide · ASPM Buyer's Guide · OSV and Open Source Vulnerability Databases