Skip to content
Closed
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1a25b12
test(security): require literal PR-head scanner checkout
seonghobae Aug 6, 2026
7d20fb7
ci(security): execute exact-head scanner contract
seonghobae Aug 6, 2026
e75172d
test(security): require literal-head SARIF attribution
seonghobae Aug 6, 2026
a7028f2
fix(security): scan and publish literal PR-head evidence
seonghobae Aug 6, 2026
115b2fc
ci(security): verify exact-head checkout and SARIF contracts
seonghobae Aug 6, 2026
fc37844
docs(security): record literal-head scanner evidence
seonghobae Aug 6, 2026
323c07b
docs: record exact-head security scanner repair
seonghobae Aug 6, 2026
682088b
test(security): prove unavailable dependency review fails closed
seonghobae Aug 7, 2026
2d1603f
test(security): execute dependency-review fail-closed contract
seonghobae Aug 7, 2026
7c0b6f9
fix(security): fail closed on unavailable dependency review
seonghobae Aug 7, 2026
3c1653a
docs(security): document fail-closed dependency review evidence
seonghobae Aug 7, 2026
5996f89
docs(security): record dependency-review fail-closed gate
seonghobae Aug 7, 2026
dfa2878
test(security): accept explicit unavailable-status diagnostic
seonghobae Aug 7, 2026
a5f39a4
docs(security): surface exact-head scanner operator contract
seonghobae Aug 7, 2026
acc0da8
test: require bounded body-discarding dependency probe
seonghobae Aug 7, 2026
c395c0f
chore(security): stage bounded dependency-review probe
seonghobae Aug 7, 2026
3ccb616
fix(security): bound dependency-review support probe
seonghobae Aug 7, 2026
e7690e3
chore(security): remove staged timeout patch artifact
seonghobae Aug 7, 2026
4dfde68
chore(ci): stage bounded PR 799 repair
seonghobae Aug 7, 2026
3a382eb
ci: bootstrap verified PR 799 repair
seonghobae Aug 7, 2026
3ff61fd
fix(ci): reap fatal review process groups
github-actions[bot] Aug 7, 2026
e4b7f0c
chore(stack): isolate exact-head scanner repair on current main
seonghobae Aug 7, 2026
667e9dd
chore(ci): restage bounded PR 799 repair
seonghobae Aug 7, 2026
6732b24
ci: rerun verified PR 799 repair
seonghobae Aug 7, 2026
9ad6b70
chore(ci): remove temporary PR 799 repair workflow
seonghobae Aug 7, 2026
a6cd746
chore(ci): remove encoded PR 799 repair payload
seonghobae Aug 7, 2026
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
1 change: 1 addition & 0 deletions .github/repairs/pr799-repair-v2.patch.gz.b64
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
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
73 changes: 73 additions & 0 deletions .github/workflows/repair-pr-799-evidence-v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Repair PR 799 exact-head evidence v2

on:
push:
branches:
- fix/security-scan-exact-head
paths:
- .github/repairs/pr799-repair-v2.patch.gz.b64
- .github/workflows/repair-pr-799-evidence-v2.yml

permissions:
contents: write
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed

concurrency:
group: repair-pr-799-exact-head-evidence-v2
cancel-in-progress: false

jobs:
repair:
if: github.repository == 'ContextualWisdomLab/.github'
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout repair head
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: fix/security-scan-exact-head
fetch-depth: 0
persist-credentials: true

- name: Apply bounded repair and remove bootstrap files
shell: bash
run: |
set -euo pipefail
base64 --decode .github/repairs/pr799-repair-v2.patch.gz.b64 | gzip --decompress > /tmp/pr799-repair.patch
git apply --check /tmp/pr799-repair.patch
git apply /tmp/pr799-repair.patch
rm -f .github/repairs/pr799-repair-v2.patch.gz.b64
rm -f .github/workflows/repair-pr-799-evidence-v2.yml
rmdir .github/repairs 2>/dev/null || true
bash -n scripts/ci/run_opencode_review_model_pool.sh
git diff --check

- name: Install trusted test toolchain
run: python3 -m pip install --disable-pip-version-check --require-hashes -r requirements-opencode-review-ci-hashes.txt

- name: Verify focused regressions
env:
PYTEST_DISABLE_PLUGIN_AUTOLOAD: "1"
run: |
python3 -m pytest -q \
tests/test_required_workflow_queue_contract.py::test_security_scan_fails_closed_when_dependency_review_is_unavailable \
tests/test_sandboxed_verify.py::test_main_reports_allowed_env_network_stderr_timeout_and_kept_sandbox \
tests/test_opencode_model_pool_runner.py::test_fatal_provider_error_kills_hung_opencode_run_early

- name: Verify complete Python evidence
env:
PYTEST_DISABLE_PLUGIN_AUTOLOAD: "1"
run: |
timeout --kill-after=30s 900 python3 -m coverage run -m pytest -q tests
python3 -m coverage report --show-missing --fail-under=100
python3 -m interrogate scripts/ci --fail-under=100

- name: Commit verified repair
shell: bash
run: |
set -euo pipefail
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add --all
git diff --cached --check
git commit -m "fix(ci): reap fatal review process groups"
git push origin HEAD:fix/security-scan-exact-head
44 changes: 44 additions & 0 deletions .github/workflows/security-scan-exact-head-quality-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Security Scan Exact-Head Quality CI

on:
pull_request:
paths:
- ".github/workflows/security-scan.yml"
- ".github/workflows/security-scan-exact-head-quality-ci.yml"
- "tests/test_security_scan_exact_head.py"
- "tests/test_security_scan_sarif_exact_head.py"

concurrency:
group: security-scan-exact-head-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
exact-head-contract:
runs-on: ubuntu-24.04
steps:
- name: Checkout literal pull request head
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
- name: Compile exact-head contracts
run: >-
python3 -m py_compile
tests/test_security_scan_exact_head.py
tests/test_security_scan_sarif_exact_head.py
- name: Execute dependency-free exact-head contracts
run: |
python3 - <<'PY'
from tests import test_security_scan_exact_head as checkout_contract
from tests import test_security_scan_sarif_exact_head as sarif_contract

checkout_contract.test_repository_scanners_checkout_the_literal_pull_request_head()
checkout_contract.test_dependency_review_checkout_is_bound_to_the_same_exact_head()
checkout_contract.test_dependency_review_support_probe_fails_closed_unless_api_returns_200()
sarif_contract.test_repository_scanner_sarif_is_attributed_to_the_literal_head()
print("security scan exact-head contracts passed")
PY
46 changes: 25 additions & 21 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
# pull_request workflows upload to refs/pull/N/merge, so no single ref ever holds
# all tools. Bundling at the workflow/check level is ref-independent.
#
# NOTE on dependency-review: dependency graph can be unavailable on some repos.
# Treat that as "not enforceable here" instead of making the required workflow
# unsatisfiable; keep medium-or-higher dependency findings hard-failing where the
# API is supported.
# NOTE on dependency-review: for this organization-owned hard gate, unavailable
# dependency-review evidence is not a clean result. Only an exact base/head API
# comparison that returns HTTP 200 may proceed to the pinned dependency-review
# action; every other support-probe outcome fails closed without printing the
# untrusted API response body.
#
# NOTE on trivy-fs: it scans the whole repo, so a pre-existing FIXABLE
# MEDIUM/HIGH/CRITICAL finding blocks every PR in that repo until it is fixed.
Expand Down Expand Up @@ -257,9 +258,11 @@ jobs:
contents: read
pull-requests: read
steps:
- name: Checkout
- name: Checkout exact head
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
- name: Check dependency review support
id: dependency_review_support
Expand All @@ -272,30 +275,23 @@ jobs:
set -euo pipefail

api_url="${GITHUB_API_URL:-https://api.github.com}"
response_file="$(mktemp)"
status="$(
curl -fsS -o "$response_file" -w '%{http_code}' \
curl -sS --connect-timeout 10 --max-time 30 \
-o /dev/null \
-w '%{http_code}' \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${api_url}/repos/${REPOSITORY}/dependency-graph/compare/${BASE_SHA}...${HEAD_SHA}" \
|| true
)"
Comment thread
seonghobae marked this conversation as resolved.

if [ "$status" = "200" ]; then
echo "supported=true" >>"$GITHUB_OUTPUT"
exit 0
fi

if [ "$status" = "403" ] || [ "$status" = "404" ]; then
echo "::warning::Dependency review is unavailable for ${REPOSITORY}; skipping dependency-review hard gate."
echo "supported=false" >>"$GITHUB_OUTPUT"
exit 0
if [ "$status" != "200" ]; then
echo "::error::Dependency review evidence unavailable for ${REPOSITORY} at exact base ${BASE_SHA} and head ${HEAD_SHA}: HTTP ${status:-unavailable}. Failing closed."
exit 1
fi

echo "::error::Dependency review support check failed with HTTP ${status}."
cat "$response_file"
exit 1
echo "supported=true" >>"$GITHUB_OUTPUT"
- name: Dependency review
if: steps.dependency_review_support.outputs.supported == 'true'
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
Expand All @@ -311,9 +307,11 @@ jobs:
security-events: write
actions: read
steps:
- name: Checkout
- name: Checkout exact head
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
Expand Down Expand Up @@ -387,6 +385,8 @@ jobs:
with:
sarif_file: trivy-results.sarif
category: trivy-fs
ref: refs/pull/${{ github.event.pull_request.number }}/head
sha: ${{ github.event.pull_request.head.sha }}
wait-for-processing: false
- name: Report Trivy SARIF upload failure
if: steps.upload_trivy_sarif.outcome == 'failure'
Expand All @@ -403,9 +403,11 @@ jobs:
contents: read
actions: read
steps:
- name: Checkout
- name: Checkout exact head
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
- name: Run Scorecard
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
Expand Down Expand Up @@ -461,6 +463,8 @@ jobs:
with:
sarif_file: results.sarif
category: scorecard
ref: refs/pull/${{ github.event.pull_request.number }}/head
sha: ${{ github.event.pull_request.head.sha }}
wait-for-processing: false
- name: Report Scorecard SARIF upload failure
if: steps.upload_scorecard_sarif.outcome == 'failure'
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Semantic Versioning where the repository publishes a release.

### Fixed

- Bound dependency-review support, Trivy, and Scorecard checkouts to the literal pull-request head repository and SHA; bound Trivy and Scorecard SARIF uploads to the matching `refs/pull/<number>/head` identity; and added permanent dependency-free exact-head regression evidence. Dependency-review availability now fails closed unless the exact base/head comparison returns HTTP 200, discards the untrusted API response body, and never translates 403, 404, transport failure, or another unavailable probe outcome into a green hard gate.
- Bound each review-agent invocation key to the wrapper's complete canonical payload, including the base branch and requesting actor; altered fields with a valid-format key now fail before durable-leader election or forwarding, and wrapper write permission is job-scoped.
- Bound both trusted-uv quality jobs to `github.event.pull_request.head.sha` and added a permanent two-checkout regression contract so exact-head compatibility, coverage, docstring, and compilation claims cannot silently measure GitHub's generated pull-request merge revision.
- Made Strix treat only a single LiteLLM provider-error line containing NVIDIA NIM context and model-catalog 404 evidence as cross-model fallback evidence, rejecting cross-line signal assembly and provider-like target source literals; moved the public default to Nemotron 3 Super 120B and added a second NVIDIA hosted candidate before GitHub Models without neutralizing reported vulnerabilities.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,32 @@ root cause, fix direction, and focused rerun command. Cancelled or superseded
checks must be described as queue or evidence blockers rather than invented
source-code findings.

## Security Scan exact-head operator contract

Organization-required repository scanners authorize evidence against the
literal pull-request head, not GitHub's generated merge revision. The central
`Security Scan` therefore binds dependency-review support, Trivy, and Scorecard
to the event's explicit head repository and immutable head SHA, and binds Trivy
and Scorecard SARIF uploads to `refs/pull/<number>/head` plus that same SHA.
A queued, cancelled, skipped, failed, missing, predecessor-head, or synthetic
merge run is not current-head security evidence.

Dependency review is a hard supply-chain gate. Its exact base-to-head capability
probe may proceed only on HTTP `200`; `403`, `404`, `000`, malformed or empty
status, timeout, transport failure, and other unexpected outcomes fail closed.
Operators must repair the repository or organization dependency-graph/security
capability, organization policy, entitlement, or read-token access and then
rerun the exact head. Do not convert an unavailable dependency-review endpoint
into a green skip, and do not treat OSV, Trivy, CodeQL, Semgrep, Secret Scan,
Scorecard, or Dependabot as substitutes for dependency-review evidence.
Private or internal repository exceptions require an explicit organization
policy backed by independently reviewable entitlement evidence rather than an
inference from a failed probe.

The authoritative rationale, rollback procedure, verification contracts, and
APA 7th primary-source references are maintained in
[`docs/doctoring/security-scan-exact-head.md`](docs/doctoring/security-scan-exact-head.md).

Operational cases folded into the central policy:

- `naruon`: approved PRs can become `BEHIND`; the scheduler treats that as an
Expand Down
Loading
Loading