Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .github/workflows/scorecard-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
persist-credentials: false

- name: Run analysis
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with:
results_file: results.sarif
results_format: sarif
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecard-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
persist-credentials: false

- name: Run analysis
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with:
results_file: results.sarif
results_format: sarif
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ jobs:
with:
persist-credentials: false
- name: Run Scorecard
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with:
results_file: results.sarif
results_format: sarif
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Semantic Versioning where the repository publishes a release.

### Fixed

- Pinned OpenSSF Scorecard to one immutable action SHA (`2d1146689b8cda280b9bc96326124645441f03bc`, v2.4.4) on both the PR visibility job and the default-branch analysis job so a Dependabot split cannot execute a second unreviewed control sphere (CWE-829).
- Materialized base Python locks only when every package line is an exact SHA-256 pin or a bounded relative `-r`/`--requirement` include. A lone `--require-hashes` directive, a dotted include such as `./lock.txt`, or `-r other-hashes.txt` no longer enters the trusted build context.
Comment thread
seonghobae marked this conversation as resolved.
- Parsed `opencode.jsonc` as JSONC (stripping `//` and `/* */` comments outside string literals) in the reasoning-effort guard and its contract tests, instead of raw `json.loads`, which rejected the file the moment it carried its first explanatory comment (added for the `contextual-orchestrator` provider block) with `Expecting property name enclosed in double quotes`. Comment markers inside string values, such as the `$schema` URL, are left untouched.
- Download the pinned `uv` 0.12.1 exporter from the official GitHub Releases URL instead of `releases.astral.sh`, which now returns HTTP 403 and blocks org-wide OpenCode `coverage-evidence`. The SHA-256 pin is unchanged. The opener may follow one hop onto `release-assets.githubusercontent.com` or `objects.githubusercontent.com` and still rejects every other host, userinfo, non-HTTPS scheme, and nondefault port (ContextualWisdomLab/.github#1109).
- Compared the trusted `uv` executable's post-install `--version` output against the real GitHub Releases build's full string, `uv 0.12.1 (x86_64-unknown-linux-gnu)`, instead of the bare `uv 0.12.1` the prior check required; the genuine release binary always prints the target triple, so every installation was failing the pin check immediately after the archive download itself was fixed (ContextualWisdomLab/.github#1109).
Expand Down
25 changes: 25 additions & 0 deletions docs/doctoring/scorecard-action-single-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Scorecard action single-version pin

## Incident and buyer impact

Dependabot bumps `ossf/scorecard-action` one workflow at a time. If the
PR visibility job and the default-branch analysis job execute different
SHAs, a green Scorecard gate does not prove the scheduled posture scan
used the reviewed action.

## Decision

Pin both `scorecard-pr.yml` and `scorecard-analysis.yml` to
`2d1146689b8cda280b9bc96326124645441f03bc` (v2.4.4). A contract test
rejects a split.

CWE-829 forbids including functionality from an untrusted or unreviewed
control sphere (MITRE, 2026). A second SHA is a second control sphere.

## References

MITRE. (2026). *CWE-829: Inclusion of functionality from untrusted
control sphere*. https://cwe.mitre.org/data/definitions/829.html

OpenSSF. (n.d.). *Scorecard action*. GitHub. Retrieved August 13, 2026,
from https://github.com/ossf/scorecard-action
35 changes: 35 additions & 0 deletions tests/test_scorecard_action_pin_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Pin OpenSSF Scorecard to one immutable action SHA across workflows."""

from __future__ import annotations

import re
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[1]
SCORECARD_SHA = "2d1146689b8cda280b9bc96326124645441f03bc"
SCORECARD_TAG = "v2.4.4"
_PIN = re.compile(
r"ossf/scorecard-action@([0-9a-f]{40}) # (v\d+\.\d+\.\d+)"
)


def test_scorecard_pr_and_analysis_share_one_action_sha() -> None:
"""CWE-829: PR and scheduled Scorecard must execute one immutable SHA.

A Dependabot bump that updates only one workflow would analyze PRs with
a different trusted action than the default-branch posture job.
"""
shas: set[str] = set()
tags: set[str] = set()
for filename in ("scorecard-pr.yml", "scorecard-analysis.yml"):
workflow = (REPO_ROOT / ".github/workflows" / filename).read_text(
encoding="utf-8"
)
pins = _PIN.findall(workflow)
assert pins, f"{filename} has no pinned ossf/scorecard-action"
for sha, tag in pins:
shas.add(sha)
tags.add(tag)

assert shas == {SCORECARD_SHA}
assert tags == {SCORECARD_TAG}
Loading