Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/codeql-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
category: "/language:${{ matrix.language }}"
upload: false
Expand Down Expand Up @@ -197,13 +197,13 @@ jobs:
ref: ${{ format('refs/pull/{0}/merge', github.event.pull_request.number) }}

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
category: "/language:${{ matrix.language }}-merge"
upload: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ jobs:
if: always() && hashFiles('bandit-results.sarif') != ''
# The explicit gate below still fails on every Medium+ Bandit result.
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: bandit-results.sarif
category: bandit
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sast-semgrep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
- name: Upload Semgrep SARIF to code scanning
if: always() && hashFiles('semgrep-results.sarif') != ''
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: semgrep-results.sarif
category: semgrep
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/scheduled-security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ jobs:
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
continue-on-error: true
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
category: "/language:${{ matrix.language }}-scheduled"

Expand Down Expand Up @@ -131,7 +131,7 @@ jobs:
- name: Upload Trivy SARIF to code scanning
if: always() && hashFiles('trivy-results.sarif') != ''
continue-on-error: true
uses: github/codeql-action/upload-sarif@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: trivy-results.sarif
category: trivy-fs-scheduled
2 changes: 1 addition & 1 deletion .github/workflows/scorecard-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ jobs:
# Scorecard posture is preserved in its SARIF-generation log; an
# installation upload quota outage must not fail the default branch.
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: results.sarif
2 changes: 1 addition & 1 deletion .github/workflows/secret-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:
- name: Upload gitleaks SARIF to code scanning
if: always() && hashFiles('gitleaks-results.upload.sarif') != ''
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: gitleaks-results.upload.sarif
category: gitleaks
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ jobs:
# The reporter above is the vulnerability gate. Preserve an upload
# quota failure in this step's log without reclassifying it as a CVE.
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: results.sarif
# results.sarif is produced after checkout of the pull request head.
Expand Down Expand Up @@ -384,7 +384,7 @@ jobs:
if: always() && hashFiles('trivy-results.sarif') != ''
# The parser above fails on every fixable Medium+ finding independently.
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: trivy-results.sarif
category: trivy-fs
Expand Down Expand Up @@ -458,7 +458,7 @@ jobs:
id: upload_scorecard_sarif
# Scorecard is soft repository-posture evidence; upload quota is external.
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with:
sarif_file: results.sarif
category: scorecard
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ Semantic Versioning where the repository publishes a release.

### Fixed

- Aligned every central `github/codeql-action` `init`, `analyze`, and
`upload-sarif` use to the official v4.37.7 commit so analyzer and evidence
upload steps run one immutable, reviewed release across security workflows.
- Publish only the sanitized cumulative Strix report tree, avoiding a later
copy of relative scanner output that could reintroduce known internal warning
text into uploaded security evidence.
Expand Down
33 changes: 33 additions & 0 deletions docs/doctoring/codeql-action-single-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# CodeQL Action single-version boundary

## Incident boundary

The central security workflows referenced three CodeQL Action releases:
v4.37.0 for pull-request analysis, v4.37.5 for scheduled analysis, and v4.37.4
for most SARIF uploads. The open v4.37.6 alignment (#918) predated the official
v4.37.7 release, while the v4.37.7 dependency update (#1107) covered only the
two workflows containing `init` and `analyze` steps. Five upload-only workflows
would therefore have remained on a different reviewed artifact.

## Decision

Pin every central `github/codeql-action/{init,analyze,upload-sarif}` use to
`ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd`, the commit referenced by the
official annotated v4.37.7 tag. GitHub documents that a full commit SHA is
unique and immutable and must be verified against the action repository
(GitHub, n.d.). The v4.37.7 release updates the default CodeQL bundle to
v2.26.3 (GitHub, 2026).

The change does not alter workflow permissions, event triggers, SARIF paths,
finding thresholds, or fail-closed gates. A repository-wide contract parses
every central workflow occurrence, rejects malformed pins, requires all three
CodeQL Action entry points, and admits only the reviewed SHA and release tag.

## References

GitHub. (2026, August 13). *CodeQL Action v4.37.7* [Software release].
https://github.com/github/codeql-action/releases/tag/v4.37.7

GitHub. (n.d.). *Using pre-written building blocks in your workflow*.
Retrieved August 24, 2026, from
https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/find-and-customize-actions
25 changes: 25 additions & 0 deletions tests/test_codeql_pr_workflow_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,31 @@ def test_codeql_action_steps_use_one_version_per_workflow() -> None:
assert len(refs) == 1, f"{filename} mixes CodeQL action refs: {sorted(refs)}"


def test_all_codeql_actions_share_the_reviewed_current_release() -> None:
"""Pin every central CodeQL action use to the reviewed v4.37.7 commit."""
expected = ("ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd", "v4.37.7")
pattern = re.compile(
r"github/codeql-action/(?P<action>init|analyze|upload-sarif)@"
r"(?P<sha>[^\s]+)\s+#\s+(?P<tag>v[^\s]+)"
)
actions: set[str] = set()
observed: set[tuple[str, str]] = set()

for path in sorted((REPO_ROOT / ".github/workflows").glob("*.y*ml")):
for line_number, line in enumerate(
path.read_text(encoding="utf-8").splitlines(), start=1
):
if "uses:" not in line or "github/codeql-action/" not in line:
continue
match = pattern.search(line)
assert match is not None, f"malformed CodeQL pin: {path}:{line_number}"
actions.add(match.group("action"))
observed.add((match.group("sha"), match.group("tag")))

assert actions == {"init", "analyze", "upload-sarif"}
assert observed == {expected}
Comment thread
seonghobae marked this conversation as resolved.


def test_codeql_sarif_gate_logs_and_fails_only_unsuppressed_medium_plus(
tmp_path: Path,
) -> None:
Expand Down
Loading