Cross-Scanner Compliance Evidence and Waiver Normalisation in GitHub Actions
key claims
- Confidence: high. An organization should treat SARIF as the shared interchange backbone for multi-scanner compliance evidence because OASIS designed it for cross-tool aggregation and GitHub already ingests SARIF 2.1.0 into code scanning without requiring a custom user interface. Sources: https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html ; https://docs.github.com/en/code-security/reference/code-scanning/sarif-files/sarif-support-for-code-scanning
- Confidence: high. A single normalized severity field is the wrong abstraction for a heterogeneous scanner estate, because GitHub code scanning uses `Error` or `Warning` or `Note`, Spectral uses lint severities, Checkov uses thresholdable policy severities, and GraphQL Inspector signals breaking-change impact instead of security risk. Sources: https://docs.github.com/en/code-security/concepts/code-scanning/about-code-scanning-alerts ; https://docs.stoplight.io/docs/spectral/branches/develop/9ffa04e052cc1-spectral-cli ; https://www.checkov.io/2.Basics/CLI%20Command%20Reference.html ; https://the-guild.dev/graphql/inspector/docs/products/action
- Confidence: high. The minimum viable normalized evidence record should preserve stable rule identity, artifact location, fingerprint, presentation level, business severity, workflow category, and policy version, because those are the fields that enable deduplication, routing, auditability, and user interface placement across scanner boundaries. Sources: https://docs.github.com/en/code-security/reference/code-scanning/sarif-files/sarif-support-for-code-scanning ; https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html ; https://semgrep.dev/docs/semgrep-appsec-platform/json-and-sarif
- Confidence: high. Waivers should be keyed to the normalized finding identity in a central registry with approver, justification, expiry, and policy-version metadata, because scanner-native suppressions such as `nosemgrep`, `checkov:skip`, and `noqa` are useful locally but do not provide a uniform audit contract. Sources: https://semgrep.dev/docs/ignoring-files-folders-code ; https://www.checkov.io/2.Basics/Suppressing%20and%20Skipping%20Policies.html ; https://docs.sqlfluff.com/en/latest/configuration/ignoring_configuration.html ; https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html
- Confidence: high. CodeQL, Semgrep, Checkov, and Spectral findings that already fit SARIF should be uploaded into GitHub code scanning under distinct categories, because GitHub otherwise treats same-tool same-category uploads as replacements and because location-aware alerts benefit from the native security tab and pull request surfaces. Sources: https://docs.github.com/en/code-security/how-tos/scan-code-for-vulnerabilities/integrate-with-existing-tools/uploading-a-sarif-file-to-github ; https://www.checkov.io/8.Outputs/SARIF.html ; https://semgrep.dev/docs/semgrep-appsec-platform/json-and-sarif ; https://docs.stoplight.io/docs/spectral/branches/develop/9ffa04e052cc1-spectral-cli
- Confidence: medium. GraphQL Inspector should remain a check-and-annotation adapter instead of being forced into the same alert channel as every other tool, because its documented model is schema-diff feedback with `fail-on-breaking` and label-based approval rather than SARIF-based persistent alert lifecycle. Source: https://the-guild.dev/graphql/inspector/docs/products/action
- Confidence: medium. SQLFluff should start as a check-run or job-summary signal until the team proves that a maintained converter is worth the effort, because the retrieved official SQLFluff documentation emphasizes rule selection and `noqa` suppression rather than native SARIF output. Sources: https://docs.sqlfluff.com/en/latest/configuration/ignoring_configuration.html ; https://docs.sqlfluff.com/en/stable/reference/cli.html
- Confidence: high. The safest rollout sequence is normalize first, observe duplicate and category stability second, centralize waivers third, and enforce blocking policy last, because fingerprint churn or weak mappings create developer distrust when they are introduced directly as hard merge gates. Sources: https://docs.github.com/en/code-security/reference/code-scanning/sarif-files/sarif-support-for-code-scanning ; https://github.com/davidamitchell/Research/blob/main/Research/completed/2026-03-22-compliance-scanning-gh-actions.md
Research Question
How should an organisation running multiple compliance scanners in GitHub Actions normalise evidence, severity, waiver handling, and developer-facing output so that heterogeneous tools behave like one coherent compliance system rather than a collection of unrelated failing checks?
Findings
Executive Summary
- [inference] A coherent multi-scanner compliance system in GitHub Actions should normalize every scanner result into a shared SARIF-aligned evidence contract and keep waivers in a separate organization-owned registry, because the retrieved tools expose incompatible severity models and incompatible suppression syntaxes. Sources: Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification ; GitHub Docs — SARIF support for code scanning ; Semgrep docs — Ignoring files, folders, and code ; Checkov docs — Suppressing and Skipping Policies ; GraphQL Inspector docs — GitHub Action
- [inference] The recommended normalization strategy is to split severity into presentation level, business severity, and merge-gate policy instead of forcing GraphQL Inspector, Spectral, Checkov, Semgrep, and GitHub code scanning into one ordinal ladder. Sources: GitHub Docs — About code scanning alerts ; Spectral docs — CLI ; Checkov docs — Command Line Interface (CLI) reference ; GraphQL Inspector docs — GitHub Action
- [inference] GitHub code scanning should host only SARIF-capable, location-aware findings with stable identifiers, while check runs, annotations, and job summaries should carry scanner outputs that do not naturally behave like persistent source-code alerts. Sources: GitHub Docs — About code scanning alerts ; GitHub Docs — Uploading a SARIF file to GitHub ; GraphQL Inspector docs — GitHub Action ; SQLFluff docs — CLI reference
- [inference] The practical implementation path is to build adapters first, then stabilize fingerprinting and categories, then enforce central waiver expiry, and only then make normalized policy outcomes blocking for merges. Sources: GitHub Docs — SARIF support for code scanning ; Prior related item — `Research/completed/2026-03-22-compliance-scanning-gh-actions.md`
Key Findings
- [inference] Confidence: high. An organization should treat SARIF as the shared interchange backbone for multi-scanner compliance evidence because OASIS designed it for cross-tool aggregation and GitHub already ingests SARIF 2.1.0 into code scanning without requiring a custom user interface. Sources: Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification ; GitHub Docs — SARIF support for code scanning
- [inference] Confidence: high. A single normalized severity field is the wrong abstraction for a heterogeneous scanner estate, because GitHub code scanning uses
ErrororWarningorNote, Spectral uses lint severities, Checkov uses thresholdable policy severities, and GraphQL Inspector signals breaking-change impact instead of security risk. Sources: GitHub Docs — About code scanning alerts ; Spectral docs — CLI ; Checkov docs — Command Line Interface (CLI) reference ; GraphQL Inspector docs — GitHub Action - [inference] Confidence: high. The minimum viable normalized evidence record should preserve stable rule identity, artifact location, fingerprint, presentation level, business severity, workflow category, and policy version, because those are the fields that enable deduplication, routing, auditability, and user interface placement across scanner boundaries. Sources: GitHub Docs — SARIF support for code scanning ; Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification ; Semgrep docs — JavaScript Object Notation (JSON) and SARIF fields
- [inference] Confidence: high. Waivers should be keyed to the normalized finding identity in a central registry with approver, justification, expiry, and policy-version metadata, because scanner-native suppressions such as
nosemgrep,checkov:skip, andnoqaare useful locally but do not provide a uniform audit contract. Sources: Semgrep docs — Ignoring files, folders, and code ; Checkov docs — Suppressing and Skipping Policies ; SQLFluff docs — Ignoring Errors and Files ; Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification - [inference] Confidence: high. CodeQL, Semgrep, Checkov, and Spectral findings that already fit SARIF should be uploaded into GitHub code scanning under distinct categories, because GitHub otherwise treats same-tool same-category uploads as replacements and because location-aware alerts benefit from the native security tab and pull request surfaces. Sources: GitHub Docs — Uploading a SARIF file to GitHub ; Checkov docs — SARIF output ; Semgrep docs — JavaScript Object Notation (JSON) and SARIF fields ; Spectral docs — CLI
- [inference] Confidence: medium. GraphQL Inspector should remain a check-and-annotation adapter instead of being forced into the same alert channel as every other tool, because its documented model is schema-diff feedback with
fail-on-breakingand label-based approval rather than SARIF-based persistent alert lifecycle. Source: GraphQL Inspector docs — GitHub Action - [inference] Confidence: medium. SQLFluff should start as a check-run or job-summary signal until the team proves that a maintained converter is worth the effort, because the retrieved official SQLFluff documentation emphasizes rule selection and
noqasuppression rather than native SARIF output. Sources: SQLFluff docs — Ignoring Errors and Files ; SQLFluff docs — CLI reference - [inference] Confidence: high. The safest rollout sequence is normalize first, observe duplicate and category stability second, centralize waivers third, and enforce blocking policy last, because fingerprint churn or weak mappings create developer distrust when they are introduced directly as hard merge gates. Sources: GitHub Docs — SARIF support for code scanning ; Prior related item — `Research/completed/2026-03-22-compliance-scanning-gh-actions.md`
Assumptions
- [assumption] The organization can keep normalized
rule_idvalues and workflow categories stable across tool upgrades. Justification: GitHub's duplicate-prevention logic depends on stable identifiers, but the retrieved documentation cannot guarantee internal governance discipline. Sources: GitHub Docs — SARIF support for code scanning ; GitHub Docs — Uploading a SARIF file to GitHub - [assumption] The waiver registry can be implemented as either a repository-governed manifest or an external system, provided it is queryable in workflows and keeps historical state. Justification: the public sources define interoperable result and alert constraints, but they do not prescribe a single storage architecture for waivers. Sources: GitHub Docs — About code scanning alerts ; Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification
Analysis
- [inference] The central design choice is to normalize evidence more aggressively than user interface behavior. This works because a shared record can drive several surfaces at once, while a shared surface cannot recover semantics that were discarded during ingestion. Sources: Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification ; GitHub Docs — About code scanning alerts
- [inference] Keeping
presentation_level,business_severity, andmerge_gateseparate turns severity into a translation layer instead of a lossy compromise, which is the only way to accommodate both policy scanners and schema-change scanners under one governance model. Sources: GitHub Docs — About code scanning alerts ; GraphQL Inspector docs — GitHub Action ; Spectral docs — CLI ; Checkov docs — Command Line Interface (CLI) reference - [inference] Centralizing waivers reduces long-term compliance drift because expiry, approver identity, and policy-version traceability become first-class metadata instead of comments hidden inside unrelated source files. Sources: Checkov docs — Suppressing and Skipping Policies ; Semgrep docs — Ignoring files, folders, and code ; SQLFluff docs — Ignoring Errors and Files
- [inference] The platform should prefer native GitHub surfaces when they match the scanner's semantics and avoid forced conversions when they do not, because every adapter choice trades implementation simplicity against user-context quality. Sources: GitHub Docs — About code scanning alerts ; GraphQL Inspector docs — GitHub Action ; SQLFluff docs — CLI reference
Risks, Gaps, and Uncertainties
- [fact] GitHub code scanning only shows pull request alerts when the identified lines are present in the diff, so repository-level governance findings without precise locations will need a different surface. Sources: GitHub Docs — About code scanning alerts ; GitHub Docs — SARIF support for code scanning
- [inference] Fingerprint instability or category drift will create duplicate or disappearing alerts, which will undermine trust before the platform's governance model matures. Source: GitHub Docs — SARIF support for code scanning
- [inference] The public sources leave open whether maintaining custom SARIF converters for non-native tools is cheaper than keeping mixed surfaces. That trade-off depends on internal engineering capacity and desired user experience consistency. Sources: GraphQL Inspector docs — GitHub Action ; SQLFluff docs — CLI reference
- [inference] Inline suppressions remain a governance risk even under a central registry if workflows do not reconcile source-level suppressions back to the registry on every run. Sources: Semgrep docs — Ignoring files, folders, and code ; Checkov docs — Suppressing and Skipping Policies ; SQLFluff docs — Ignoring Errors and Files
Open Questions
- [inference] Should the organization standardize on a repository-resident waiver manifest for maximum transparency, or move directly to an external evidence store for stronger history and access control?
- [inference] Which non-SARIF tools, if any, are worth converting into SARIF rather than preserving as native checks and summaries?
- [inference] How should business severity be assigned for schema-breaking changes that are operationally critical but not security findings?
Output
- [fact] Type: knowledge. Source: github.com
- [inference] Description: This item defines a hub-and-adapter operating model for multi-scanner compliance in GitHub Actions, centered on a SARIF-aligned evidence schema, a separate waiver registry, split severity dimensions, and layered GitHub presentation surfaces. Sources: Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification ; GitHub Docs — SARIF support for code scanning ; GitHub Docs — About code scanning alerts
- [fact] Three key sources: Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification ; GitHub Docs — SARIF support for code scanning ; GitHub Docs — About code scanning alerts
sources
- [x] GitHub Docs — About code scanning alerts
- [x] GitHub Docs — SARIF support for code scanning
- [x] GitHub Docs — Uploading a SARIF file to GitHub
- [x] Organization for the Advancement of Structured Information Standards (OASIS) SARIF 2.1.0 specification
- [x] Semgrep docs — Ignoring files, folders, and code
- [x] Semgrep docs — JavaScript Object Notation (JSON) and SARIF fields
- [x] Checkov docs — Command Line Interface (CLI) reference
- [x] Checkov docs — Suppressing and Skipping Policies
- [x] Checkov docs — SARIF output
- [x] Spectral docs — CLI
- [x] Spectral repository
- [x] GraphQL Inspector docs — GitHub Action
- [x] SQLFluff docs — Ignoring Errors and Files
- [x] SQLFluff docs — CLI reference
- [x] Prior related item —
Research/completed/2026-03-22-compliance-scanning-gh-actions.md