Skip to content

Route release jobs through the ca-trust-guard + locked-tools composite actions - #159

Merged
gontzess merged 4 commits into
mainfrom
steve.gontzes/sh10-probe-report
Oct 22, 2026
Merged

gontzess merged 4 commits into
mainfrom
steve.gontzes/sh10-probe-report

Conversation

@gontzess

@gontzess gontzess commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Why

GitHub-hosted runner images may still trust the compromised eMudhra intermediates until patched images roll out (actions/runner-images#15018). Release jobs must (a) measure, deny, and redirect TLS trust and (b) install only hash-locked tools — before any credential. Both mechanisms ship as composite actions in this repo (ca-trust-guard, locked-tools); this PR adopts them in release.yaml and removes the per-job inline installs.

What

  • Every guarded job (9) opens with the _workflows checkout at job.workflow_sha (persist-credentials: false; validate-inputs gains contents: read (checkout uses the default read-scoped token; not persisted)), then runs ca-trust-guard and, in the 6 tool-using jobs, locked-tools via local paths (./_workflows/.github/actions/...). Workflow, action code, fixtures, and canonical tool lock are always the same commit — no self-referential action SHAs (enforced by a CI assertion).
  • Ordering: _workflows checkout → guard → locked-tools (id: tools; preflight's stays conditional on the Go checks) → caller checkout + event-SHA verification → secrets. notify-release-failure remains exempt, with no bootstrap there.
  • Module gates (6 sites) run the action-local verify-locked-go.sh module with expected version, lock hash, and lock path taken from the locked-tools step's outputs (one reader of the lock per job); standalone version gates and the inline gon step are removed (the action asserts the runtime version; gon builds inside the action).
  • Per-job install/verify/gon-checkout steps and the four transitional wrappers (install-tool.{sh,ps1}, gon-source.sh, verify-locked-go.sh) are deleted; verify-release-checkout.sh, setup-release-buildx.sh, derive-iam-role-name.sh stay.
  • ci.yaml covers release.yaml; test-tool-integrity.py enforces local-path ordering, output-bound gate env, tool lists, the notify exemption, and the no-self-SHA rule.

Evidence

Staged rollout: safe to promote v4 only after this lands — see #165 for the window details.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit c799fde4c34b

General PR Review: SH10: offline runner trust-store probe (report + interim-residual mitigation; freeze/interim enforce ready)

Blocking Issues: 0 | Suggestions: 4 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: full
View review run

Review Summary

This PR adds committed .sh10/ fixtures: two eMudhra leaf/intermediate chains, the vulnerable roots, and a curl/Mozilla bundle from 2026-10-20 that lacks those roots. All SHA256SUMS entries verify locally. It also adds an identical ~100-line offline openssl verify probe step to 9 release jobs. In the shipped report + SH10_APPLY_DISTRUST=true mode, if any physical store trusts a chain, the step points SSL_CERT_FILE/CURL_CA_BUNDLE/GIT_SSL_CAINFO/REQUESTS_CA_BUNDLE/AWS_CA_BUNDLE/NPM_CONFIG_CAFILE (native-path git/curl only on Windows) and git's http.sslCAInfo at that bundle for later steps. Physical-store trust then fails a job only under enforce. I scanned the full PR diff for security and correctness. The $GITHUB_ENV writes and the PowerShell thumbprint interpolation use only fixture-derived or fixed values, so there is no injection path, and the new checkouts use persist-credentials: false. No repo-local criteria loaded, so the base criteria were applied. I did not read the PEM fixture contents cert by cert beyond the bundle header and the checksum check, and I did not re-run the canary.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (medium) .github/workflows/release.yaml:224 (×9 copies): ERR=1 → exit 1 runs before the SH10_MODE check, so in report mode any probe ERROR fails every release job. Runner-image drift is enough to trigger it, e.g. a missing brew etc/ca-certificates/cert.pem (L173), a changed OpenSSL error string, or a moved Git-Bash OPENSSLDIR. That conflicts with "enforcement is OFF".
  • New (high) .github/workflows/release.yaml:135: the probe is copy-pasted into 9 jobs, so the documented freeze/interim switch means editing 18 env values in sync. A missed copy gives inconsistent enforcement. There is also a redundant identical-branch case at L216.
  • New (medium) .github/workflows/release.yaml:195: the frozen Mozilla snapshot replaces the trust store for curl/git/Python/AWS/npm, and for Go on Linux via SSL_CERT_FILE, with no age check. Also, docker push through dockerd (goreleaser-docker) still uses the system store and is not listed in not_covered.
  • New (low) .github/workflows/release.yaml:481: release-preflight pins fixtures with job.workflow_sha, while every other job uses the needs.determine-workflows-ref.outputs.ref that this job already depends on. This is not the "same pin/ref" the PR describes, and an empty value would fall back to the default branch.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 224 (and the matching line in all 9 probe copies): the `if [ "$ERR" = 1 ] ... exit 1` runs regardless of SH10_MODE, so report mode still fails release jobs on any probe ERROR (missing store, changed openssl output). When SH10_MODE=report, emit a ::warning and continue; fail closed only when SH10_MODE=enforce.
- Around line 135: the ~100-line probe script is duplicated in 9 jobs. Move it to a hash-manifested `.sh10/probe.sh` (already checked out at the pinned SHA in each job), and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env so the freeze/interim choice is a single edit. Also drop the redundant identical-branch `case "$os"` around line 216.
- Around line 195: the committed clean-ca-bundle.pem becomes the trust store for later steps with no staleness guard. Add a max-age check that parses the "Certificate data from Mozilla as of" header and warns or fails past a threshold, and add "dockerd (docker push)" to the not_covered output.
- Around line 481: in release-preflight, use `ref: ${{ needs.determine-workflows-ref.outputs.ref }}` instead of `${{ job.workflow_sha }}` to match the pin source the other jobs use.

Comment thread .github/workflows/release.yaml Outdated
if [ "$PHYS_BAD" = 1 ]; then summary=STILL_TRUSTS_COMPROMISED; [ "$MITIGATED" = 1 ] && summary=PHYSICAL_STORE_TRUSTS_BUT_MITIGATED_BY_CLEAN_BUNDLE; fi
[ "$ERR" = 1 ] && summary=ERROR
echo "sh10-probe {\"image\":\"$img\",\"os\":\"$os\",\"summary\":\"$summary\",\"mode\":\"$SH10_MODE\",\"apply_distrust\":\"$SH10_APPLY_DISTRUST\",\"residual\":\"$([ "$PHYS_BAD" = 1 ] && echo physical-store-trusts-chain || echo none)\",\"not_covered\":\"action-tarball-downloads-before-step-1;runner-agent-dotnet-client;go(version-gated>=1.27.3);steps-running-arbitrary-node-without-step-level-NODE_OPTIONS\"}"
if [ "$ERR" = 1 ]; then echo "::error title=SH10::probe ERROR (fixture/store problem) — failing closed"; exit 1; fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion (confidence: medium): this exit runs before the SH10_MODE check, so in report mode any probe ERROR still fails all 9 release jobs. Image drift is enough to trigger it: a store that goes missing (e.g. brew's etc/ca-certificates/cert.pem at L173), a changed OpenSSL error string, or a moved Git-Bash OPENSSLDIR. That conflicts with "enforcement is OFF". Consider emitting ::warning and continuing when SH10_MODE=report, and failing closed only under enforce.

Comment thread .github/workflows/release.yaml Outdated
- name: SH10 runner trust-store probe (offline v3)
shell: bash
env:
SH10_MODE: report # report | enforce

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion (confidence: high): this ~100-line probe is pasted 9 times, so switching to freeze or interim-residual means editing 18 values in sync. Miss one copy and enforcement silently differs per job. Because every job already checks out _workflows at the pinned SHA, the script could live as a hash-manifested .sh10/probe.sh, with the mode set once in workflow-level env:.

Comment thread .github/workflows/release.yaml Outdated
apply_distrust() {
# Preferred mechanism (SH10-R2): point OpenSSL-based clients at a COMMITTED, hash-verified Mozilla bundle that already lacks
# the two roots (clean-ca-bundle.pem, checked by SHA256SUMS above). No download at job start, no sudo, inherited by later steps.
B="$PWD/clean-ca-bundle.pem"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion (confidence: medium): the committed snapshot (Mozilla as of Oct 20 2026) becomes the whole trust store for later curl/git/Python/AWS/npm traffic, and for Go on Linux via SSL_CERT_FILE. Nothing checks its age, so future Mozilla removals won't apply and new roots will be missing. Also, docker push from dockerd keeps using the system store and isn't listed in not_covered. Consider a max-age check on the bundle header and documenting the dockerd gap.

uses: actions/checkout@v5
with:
repository: ConductorOne/github-workflows
ref: ${{ job.workflow_sha }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion (confidence: low): the PR says this uses the "same pin/ref as the existing _workflows checkouts", but every other job in this file pins via needs.determine-workflows-ref.outputs.ref (from get-workflow-version-action). This job already needs: determine-workflows-ref, so using that output keeps a single pin source. Otherwise, if job.workflow_sha ever resolves empty, checkout silently falls back to the default branch.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit bfa528bbd99d

General PR Review: SH10: offline runner trust-store probe (report + interim-residual mitigation; freeze/interim enforce ready)

Blocking Issues: 0 | Suggestions: 4 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: full
View review run

Review Summary

This PR adds committed .sh10/ fixtures: two eMudhra leaf/intermediate chains, the vulnerable roots, and a curl/Mozilla bundle from 2026-10-20 that lacks those roots. All SHA256SUMS entries verify locally. It also adds an identical ~100-line offline openssl verify probe step to 9 release jobs. In the shipped report + SH10_APPLY_DISTRUST=true mode, if any physical store trusts a chain, the step points SSL_CERT_FILE/CURL_CA_BUNDLE/GIT_SSL_CAINFO/REQUESTS_CA_BUNDLE/AWS_CA_BUNDLE/NPM_CONFIG_CAFILE (native-path git/curl only on Windows) and git's http.sslCAInfo at that bundle for later steps. Physical-store trust then fails a job only under enforce. I scanned the full PR diff for security and correctness. The $GITHUB_ENV writes and the PowerShell thumbprint interpolation use only fixture-derived or fixed values, so there is no injection path, and the new checkouts use persist-credentials: false. No repo-local criteria loaded, so the base criteria were applied. I did not read the PEM fixture contents cert by cert beyond the bundle header and the checksum check, and I did not re-run the canary.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (medium) .github/workflows/release.yaml:224 (×9 copies): ERR=1 → exit 1 runs before the SH10_MODE check, so in report mode any probe ERROR fails every release job. Runner-image drift is enough to trigger it, e.g. a missing brew etc/ca-certificates/cert.pem (L173), a changed OpenSSL error string, or a moved Git-Bash OPENSSLDIR. That conflicts with "enforcement is OFF".
  • New (high) .github/workflows/release.yaml:135: the probe is copy-pasted into 9 jobs, so the documented freeze/interim switch means editing 18 env values in sync. A missed copy gives inconsistent enforcement. There is also a redundant identical-branch case at L216.
  • New (medium) .github/workflows/release.yaml:195: the frozen Mozilla snapshot replaces the trust store for curl/git/Python/AWS/npm, and for Go on Linux via SSL_CERT_FILE, with no age check. Also, docker push through dockerd (goreleaser-docker) still uses the system store and is not listed in not_covered.
  • New (low) .github/workflows/release.yaml:481: release-preflight pins fixtures with job.workflow_sha, while every other job uses the needs.determine-workflows-ref.outputs.ref that this job already depends on. This is not the "same pin/ref" the PR describes, and an empty value would fall back to the default branch.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 224 (and the matching line in all 9 probe copies): the `if [ "$ERR" = 1 ] ... exit 1` runs regardless of SH10_MODE, so report mode still fails release jobs on any probe ERROR (missing store, changed openssl output). When SH10_MODE=report, emit a ::warning and continue; fail closed only when SH10_MODE=enforce.
- Around line 135: the ~100-line probe script is duplicated in 9 jobs. Move it to a hash-manifested `.sh10/probe.sh` (already checked out at the pinned SHA in each job), and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env so the freeze/interim choice is a single edit. Also drop the redundant identical-branch `case "$os"` around line 216.
- Around line 195: the committed clean-ca-bundle.pem becomes the trust store for later steps with no staleness guard. Add a max-age check that parses the "Certificate data from Mozilla as of" header and warns or fails past a threshold, and add "dockerd (docker push)" to the not_covered output.
- Around line 481: in release-preflight, use `ref: ${{ needs.determine-workflows-ref.outputs.ref }}` instead of `${{ job.workflow_sha }}` to match the pin source the other jobs use.

Reviewed commit: c799fde4c34b

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

@gontzess gontzess changed the title SH10: offline runner trust-store probe (report + interim-residual mitigation; freeze/interim enforce ready) Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle Oct 21, 2026
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit bfa528bbd99d

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 4 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since c799fde
View review run

Review Summary

The new commit (bfa528b) changes SH10_MODE from report to enforce in all 9 SH10 probe copies in .github/workflows/release.yaml. It also adds a "Runner Trust-Store Probe" section to docs/release-workflow.md saying the workflow ships with enforce + distrust, and listing what the mitigation doesn't cover (including dockerd pushes). I scanned the full PR diff for security and correctness: the probe script, the sparse .sh10 checkouts, .gitattributes, the fixtures and the docs. I found no security issues. With distrust on, enforce adds a failure only when the clean bundle can't be verified effective. A probe ERROR already fails the job in every mode. No repo-local criteria loaded, so the base criteria applied. The incremental diff was complete (partial: false). I did not review the fixture PEM/JSON contents byte by byte. The probe checks them against SHA256SUMS before it runs.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (high confidence on the mismatch, low on actual breakage) .github/workflows/release.yaml:135 (×9): the code and docs now ship SH10_MODE: enforce. The PR body still says the initial values are report + distrust, with enforce only as a later follow-up flip. The only on-runner canary cited (run 39645149700) used report+distrust. Either update the description and canary evidence, or revert to report.
  • Prior — still present (open thread) .github/workflows/release.yaml:135: the ~100-line probe is still copy-pasted into 9 jobs. This commit had to edit 9 separate SH10_MODE lines in sync, which is exactly the drift risk the earlier thread raised. The identical-branch case "$os" at L216 is also still there.
  • Prior — still present (open thread) .github/workflows/release.yaml:195: the frozen Mozilla snapshot still has no age or staleness check. The dockerd gap is now documented in docs/release-workflow.md, but it is still not in the probe's not_covered output.
  • Prior — still present (open thread) .github/workflows/release.yaml:481: release-preflight still pins .sh10 with job.workflow_sha rather than needs.determine-workflows-ref.outputs.ref. The new docs now describe this behavior, but it still differs from the pin source the other jobs use.

Resolved prior findings

  • ERR=1 → exit 1 runs before the mode check (L224), which conflicted with "report mode = enforcement off": obsolete as written. The workflow now ships enforce, and the docs (docs/release-workflow.md, "proceeds only when … no probe ERROR occurred") describe fail-closed on ERROR. The remaining inconsistency with the PR body is covered by the new suggestion above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 135 (and all 9 SH10 probe copies): SH10_MODE is now `enforce`, but the PR description says it ships as `report` and the on-runner canary only covered report+distrust. Either update the PR description and run an on-runner canary with enforce, or set SH10_MODE back to `report` and update docs/release-workflow.md to match.
- Around line 135: move the duplicated probe script into a hash-manifested `.sh10/probe.sh` and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env, so mode changes become a single edit. Remove the redundant identical-branch `case "$os"` near line 216.
- Around line 195: add an age check on clean-ca-bundle.pem (e.g. warn when the snapshot is older than N days) and add dockerd/docker push to the probe's `not_covered` output.
- Around line 481: in release-preflight, use `ref: ${{ needs.determine-workflows-ref.outputs.ref }}` instead of `${{ job.workflow_sha }}`, and update the docs sentence that describes this pin.

Comment thread .github/workflows/release.yaml Outdated
- name: SH10 runner trust-store probe (offline v3)
shell: bash
env:
SH10_MODE: enforce # report | enforce

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: This commit sets SH10_MODE: enforce in all 9 probe copies. The PR description still says the initial values are report + distrust, and that enforce comes later "after a few days of clean summaries". The cited on-runner canary (run 39645149700) also ran report+distrust, so enforce on real runners has only been smoke-tested off-runner. Please either update the PR description and canary evidence to match the enforce rollout, or revert to report (docs/release-workflow.md now says enforce ships first).

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit d60d8f0c3901

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 4 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since c799fde
View review run

Review Summary

The new commit (bfa528b) changes SH10_MODE from report to enforce in all 9 SH10 probe copies in .github/workflows/release.yaml. It also adds a "Runner Trust-Store Probe" section to docs/release-workflow.md saying the workflow ships with enforce + distrust, and listing what the mitigation doesn't cover (including dockerd pushes). I scanned the full PR diff for security and correctness: the probe script, the sparse .sh10 checkouts, .gitattributes, the fixtures and the docs. I found no security issues. With distrust on, enforce adds a failure only when the clean bundle can't be verified effective. A probe ERROR already fails the job in every mode. No repo-local criteria loaded, so the base criteria applied. The incremental diff was complete (partial: false). I did not review the fixture PEM/JSON contents byte by byte. The probe checks them against SHA256SUMS before it runs.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (high confidence on the mismatch, low on actual breakage) .github/workflows/release.yaml:135 (×9): the code and docs now ship SH10_MODE: enforce. The PR body still says the initial values are report + distrust, with enforce only as a later follow-up flip. The only on-runner canary cited (run 39645149700) used report+distrust. Either update the description and canary evidence, or revert to report.
  • Prior — still present (open thread) .github/workflows/release.yaml:135: the ~100-line probe is still copy-pasted into 9 jobs. This commit had to edit 9 separate SH10_MODE lines in sync, which is exactly the drift risk the earlier thread raised. The identical-branch case "$os" at L216 is also still there.
  • Prior — still present (open thread) .github/workflows/release.yaml:195: the frozen Mozilla snapshot still has no age or staleness check. The dockerd gap is now documented in docs/release-workflow.md, but it is still not in the probe's not_covered output.
  • Prior — still present (open thread) .github/workflows/release.yaml:481: release-preflight still pins .sh10 with job.workflow_sha rather than needs.determine-workflows-ref.outputs.ref. The new docs now describe this behavior, but it still differs from the pin source the other jobs use.

Resolved prior findings

  • ERR=1 → exit 1 runs before the mode check (L224), which conflicted with "report mode = enforcement off": obsolete as written. The workflow now ships enforce, and the docs (docs/release-workflow.md, "proceeds only when … no probe ERROR occurred") describe fail-closed on ERROR. The remaining inconsistency with the PR body is covered by the new suggestion above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 135 (and all 9 SH10 probe copies): SH10_MODE is now `enforce`, but the PR description says it ships as `report` and the on-runner canary only covered report+distrust. Either update the PR description and run an on-runner canary with enforce, or set SH10_MODE back to `report` and update docs/release-workflow.md to match.
- Around line 135: move the duplicated probe script into a hash-manifested `.sh10/probe.sh` and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env, so mode changes become a single edit. Remove the redundant identical-branch `case "$os"` near line 216.
- Around line 195: add an age check on clean-ca-bundle.pem (e.g. warn when the snapshot is older than N days) and add dockerd/docker push to the probe's `not_covered` output.
- Around line 481: in release-preflight, use `ref: ${{ needs.determine-workflows-ref.outputs.ref }}` instead of `${{ job.workflow_sha }}`, and update the docs sentence that describes this pin.

Reviewed commit: bfa528bbd99d

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit d60d8f0c3901

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 1 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since bfa528b
View review run

Review Summary

The new commits change all 9 probe copies (now v3.8) and the docs:

  • Docker CA files: on Linux, the probe copies the clean bundle into /etc/docker/certs.d/<host>/ca.crt for six registries (L210-215).
  • Bundle age check: the probe warns when the bundle's Mozilla data is more than 90 days old (L143).
  • Duplicate branch removed: the redundant case "$os" around check_store is gone.
  • not_covered updated: the list now names Node, Windows and dockerd gaps.
  • Pinned checkout: the .sh10 checkouts in validate-inputs and release-preflight now use actions/checkout@fbc6f399…, which I checked is the current v5 tag.

I scanned the full PR diff for security and correctness. The incremental diff was complete (not partial). No repo-local criteria loaded, so only the base criteria apply. I reviewed the fixture .pem/.json contents only through the probe's SHA256SUMS check and the bundle date header; I did not inspect them byte by byte.

Security Issues

None found.

Correctness Issues

  • New (blocking-correctness, high confidence) .github/workflows/release.yaml:210-215 (×9 copies): the dockerd certs.d leg does not remove any trust.
    • Moby's registry.ReadCertsDirectory adds certs.d/<host>/*.crt to tlsconfig.SystemCertPool(), so chains through the eMudhra intermediates that end at a system root still verify.
    • The image builds/pushes run under docker/setup-buildx-action (L1809, docker-container driver), so BuildKit never reads the host's certs.d.
    • The probe still emits distrust: dockerd-certs.d and drops Linux dockerd from not_covered. The docs also claim this "covers daemon-side TLS for both image pulls and ECR pushes", so the summary reports coverage that does not exist.

Suggestions

  • Prior — still present (open thread) .github/workflows/release.yaml:135 (and the other 8 copies): the workflow ships SH10_MODE: enforce. The PR body says the initial values are report + distrust, and the cited on-runner canary (run 39645149700) used report. Either update the PR body and canary evidence, or set the mode back to report.
  • Prior — still present (open thread) .github/workflows/release.yaml:135: the ~110-line probe is still copy-pasted into 9 jobs, and this push again had to make identical edits 9 times (date check, docker leg, not_covered). The redundant case "$os" is now gone, but the duplication remains.
  • Prior — still present (open thread) .github/workflows/release.yaml:495: release-preflight still pins .sh10 with job.workflow_sha rather than needs.determine-workflows-ref.outputs.ref, the pin the other jobs use.

Resolved prior findings

  • Fixed: frozen Mozilla snapshot had no staleness check. L143 now warns when ## Certificate data from Mozilla as of: is older than 90 days; the current bundle is dated Oct 20 2026. dockerd on macOS/Windows is now in the summary not_covered (L230).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Correctness Issues

In `.github/workflows/release.yaml`:
- Around line 210-215 (repeated in all 9 SH10 probe copies): the Linux dockerd leg copies the clean bundle into /etc/docker/certs.d/<host>/ca.crt. Docker appends certs.d CAs to the system pool rather than replacing it, so chains through the compromised intermediates still verify. Buildx (docker-container driver) pushes also never read host certs.d. Remove this leg, keep "dockerd" (all OSes) in the probe's not_covered output, and stop emitting the "dockerd-certs.d" distrust record. Alternatively, implement real distrust (e.g. replace the daemon's system CA store and pass the bundle into the buildkit container) and verify it against the fixture chains.

In `docs/release-workflow.md`:
- Around the "On Linux runners with Docker installed" paragraph: remove or correct the claim that certs.d "covers daemon-side TLS for both image pulls and ECR pushes".

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 135 (all 9 copies): SH10_MODE is `enforce`, but the PR description says it ships as `report` and was canaried as report. Either update the PR description and canary evidence, or set SH10_MODE back to `report` and update docs/release-workflow.md.
- Around line 135: move the duplicated probe script into a hash-manifested `.sh10/probe.sh` and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env, so each change is a single edit.
- Around line 495: in release-preflight, use `ref: ${{ needs.determine-workflows-ref.outputs.ref }}` instead of `${{ job.workflow_sha }}`, and update the docs sentence that describes this pin.

Comment thread .github/workflows/release.yaml Outdated
export SSL_CERT_FILE="$B" CURL_CA_BUNDLE="$B" GIT_SSL_CAINFO="$B" REQUESTS_CA_BUNDLE="$B" AWS_CA_BUNDLE="$B" NPM_CONFIG_CAFILE="$B"
git config --global http.sslCAInfo "$B"; git config --global http.sslVerify true
# Linux dockerd: per-registry CA (daemon ignores job env). Hosts the release path pushes to / pulls from.
if [ "$os" = Linux ] && command -v docker >/dev/null && [ -d /etc/docker ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Bug: dockerd treats /etc/docker/certs.d/<host>/*.crt as roots it adds on top of the system pool (moby registry.ReadCertsDirectory appends them to tlsconfig.SystemCertPool()). So chains through the compromised intermediates that end at a system root still verify, and this leg removes no trust at all. The release image builds also go through setup-buildx-action (docker-container driver), so BuildKit pushes never read host certs.d. Either drop this leg and keep "dockerd" in not_covered with the docs saying so, or replace the daemon's system trust store and prove VERIFIED-DISTRUST against the fixture chains (high confidence).

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 26a56988311e

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 1 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since bfa528b
View review run

Review Summary

The new commits change all 9 probe copies (now v3.8) and the docs:

  • Docker CA files: on Linux, the probe copies the clean bundle into /etc/docker/certs.d/<host>/ca.crt for six registries (L210-215).
  • Bundle age check: the probe warns when the bundle's Mozilla data is more than 90 days old (L143).
  • Duplicate branch removed: the redundant case "$os" around check_store is gone.
  • not_covered updated: the list now names Node, Windows and dockerd gaps.
  • Pinned checkout: the .sh10 checkouts in validate-inputs and release-preflight now use actions/checkout@fbc6f399…, which I checked is the current v5 tag.

I scanned the full PR diff for security and correctness. The incremental diff was complete (not partial). No repo-local criteria loaded, so only the base criteria apply. I reviewed the fixture .pem/.json contents only through the probe's SHA256SUMS check and the bundle date header; I did not inspect them byte by byte.

Security Issues

None found.

Correctness Issues

  • New (blocking-correctness, high confidence) .github/workflows/release.yaml:210-215 (×9 copies): the dockerd certs.d leg does not remove any trust.
    • Moby's registry.ReadCertsDirectory adds certs.d/<host>/*.crt to tlsconfig.SystemCertPool(), so chains through the eMudhra intermediates that end at a system root still verify.
    • The image builds/pushes run under docker/setup-buildx-action (L1809, docker-container driver), so BuildKit never reads the host's certs.d.
    • The probe still emits distrust: dockerd-certs.d and drops Linux dockerd from not_covered. The docs also claim this "covers daemon-side TLS for both image pulls and ECR pushes", so the summary reports coverage that does not exist.

Suggestions

  • Prior — still present (open thread) .github/workflows/release.yaml:135 (and the other 8 copies): the workflow ships SH10_MODE: enforce. The PR body says the initial values are report + distrust, and the cited on-runner canary (run 39645149700) used report. Either update the PR body and canary evidence, or set the mode back to report.
  • Prior — still present (open thread) .github/workflows/release.yaml:135: the ~110-line probe is still copy-pasted into 9 jobs, and this push again had to make identical edits 9 times (date check, docker leg, not_covered). The redundant case "$os" is now gone, but the duplication remains.
  • Prior — still present (open thread) .github/workflows/release.yaml:495: release-preflight still pins .sh10 with job.workflow_sha rather than needs.determine-workflows-ref.outputs.ref, the pin the other jobs use.

Resolved prior findings

  • Fixed: frozen Mozilla snapshot had no staleness check. L143 now warns when ## Certificate data from Mozilla as of: is older than 90 days; the current bundle is dated Oct 20 2026. dockerd on macOS/Windows is now in the summary not_covered (L230).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Correctness Issues

In `.github/workflows/release.yaml`:
- Around line 210-215 (repeated in all 9 SH10 probe copies): the Linux dockerd leg copies the clean bundle into /etc/docker/certs.d/<host>/ca.crt. Docker appends certs.d CAs to the system pool rather than replacing it, so chains through the compromised intermediates still verify. Buildx (docker-container driver) pushes also never read host certs.d. Remove this leg, keep "dockerd" (all OSes) in the probe's not_covered output, and stop emitting the "dockerd-certs.d" distrust record. Alternatively, implement real distrust (e.g. replace the daemon's system CA store and pass the bundle into the buildkit container) and verify it against the fixture chains.

In `docs/release-workflow.md`:
- Around the "On Linux runners with Docker installed" paragraph: remove or correct the claim that certs.d "covers daemon-side TLS for both image pulls and ECR pushes".

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 135 (all 9 copies): SH10_MODE is `enforce`, but the PR description says it ships as `report` and was canaried as report. Either update the PR description and canary evidence, or set SH10_MODE back to `report` and update docs/release-workflow.md.
- Around line 135: move the duplicated probe script into a hash-manifested `.sh10/probe.sh` and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env, so each change is a single edit.
- Around line 495: in release-preflight, use `ref: ${{ needs.determine-workflows-ref.outputs.ref }}` instead of `${{ job.workflow_sha }}`, and update the docs sentence that describes this pin.

Reviewed commit: d60d8f0c3901

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking issues found — see the full review report

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 26a56988311e

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 1 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since d60d8f0
View review run

Review Summary

The new commits move the inline Linux dockerd certs.d loop (repeated in 9 jobs) into a hash-manifested .sh10/dockerd-certs.sh. The helper checks each installed ca.crt by SHA-256, and in enforce mode a failed install now fails the probe (ERR=1). Docs move to v3.10 with nine fixtures. I scanned the full PR diff for security and correctness. No repo-local criteria loaded, so I applied only the base criteria. The incremental diff was complete (not partial).

Security Issues

None found.

Correctness Issues

  • Prior — still present (blocking-correctness, high confidence) .github/workflows/release.yaml:211 (×9 copies), .sh10/dockerd-certs.sh:166-171: the dockerd certs.d mechanism is unchanged and still removes no trust.
    • Moby's registry.ReadCertsDirectory appends certs.d/<host>/*.crt to SystemCertPool(), so chains through the eMudhra intermediates still verify.
    • Image builds and pushes go through docker/setup-buildx-action (L1785, docker-container driver), and BuildKit does not read the host's certs.d.
    • This push makes it worse: under enforce, a failed install sets ERR=1 and fails the release. Releases are now gated on a mitigation that has no effect.
    • docs/release-workflow.md:212 still claims it "covers daemon-side TLS for both image pulls and ECR pushes", and the probe emits distrust: dockerd-certs.d.
    • I posted a fresh inline comment because the old thread is outdated.

Suggestions

  • New (medium confidence) PR description: it says "The v3.8 enforce-mode canary of this exact branch is linked below", but only the v3.5 and v3.7 (report-mode) runs are linked. The branch is now v3.10 and ships enforce, so the on-runner evidence for the shipped mode is missing.
  • Prior — still present .github/workflows/release.yaml:132-234: the ~100-line probe is still copied into 9 jobs, and this push again made the same edit 9 times. Moving it into a checksummed .sh10/probe.sh would turn each change into a single edit.
  • Prior — still present .github/workflows/release.yaml:487: release-preflight pins .sh10 with job.workflow_sha, while the other release jobs use needs.determine-workflows-ref.outputs.ref. This is documented, but the two pins can disagree.

Resolved prior findings

  • SH10_MODE: enforce vs. a description saying report (release.yaml:135): fixed. The PR body now says "Shipped values: SH10_MODE: enforce + SH10_APPLY_DISTRUST: "true"", and docs/release-workflow.md:35 says the workflow ships with SH10_MODE: enforce. The missing enforce canary is tracked as a new suggestion above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Correctness Issues

In `.github/workflows/release.yaml` and `.sh10/dockerd-certs.sh`:
- Around release.yaml line 211 (and the 8 other probe copies at 387, 571, 823, 1259, 1649, 2046, 2399, 2669): Docker's /etc/docker/certs.d/<host>/ca.crt is ADDED to the system cert pool (moby registry.ReadCertsDirectory), so installing the clean bundle there removes no trust. BuildKit under docker/setup-buildx-action (docker-container driver, L1785) also ignores the host certs.d. Either remove the dockerd leg (and stop failing enforce-mode releases with ERR=1 when it can't install), add "dockerd/buildkit on Linux" to the not_covered list in the summary line, and correct docs/release-workflow.md lines ~208-225 so they no longer claim daemon-side TLS coverage; or replace it with a mechanism that actually replaces the trust pool (e.g. pass a buildkitd config with the clean bundle via setup-buildx-action's `config-inline`, and for dockerd replace the system bundle it reads), and add a probe check that proves the replacement works.

## Suggestions

In the PR description:
- The text promises a "v3.8 enforce-mode canary of this exact branch ... linked below", but no such link exists, and the branch is now v3.10 shipping enforce. Run and link an enforce-mode canary of the current head, or remove the claim.

In `.github/workflows/release.yaml`:
- Around lines 132-234 (×9): move the duplicated probe script into a hash-manifested `.sh10/probe.sh` and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env, so each change is a single edit.
- Around line 487: consider pinning release-preflight's `.sh10` checkout to the same ref as the other jobs (`needs.determine-workflows-ref.outputs.ref`), or explain in the docs why job.workflow_sha is required there.

Comment thread .github/workflows/release.yaml Outdated
export SSL_CERT_FILE="$B" CURL_CA_BUNDLE="$B" GIT_SSL_CAINFO="$B" REQUESTS_CA_BUNDLE="$B" AWS_CA_BUNDLE="$B" NPM_CONFIG_CAFILE="$B"
git config --global http.sslCAInfo "$B"; git config --global http.sslVerify true
# Linux dockerd: per-registry CA (daemon ignores job env). Re-run this script after any later Docker provisioning step.
if [ "$SH10_MODE" = enforce ]; then bash ./dockerd-certs.sh "$B" || { echo "::error title=SH10::docker daemon mitigation could not be installed"; ERR=1; }; else bash ./dockerd-certs.sh "$B" || true; fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Bug: Moving the leg into dockerd-certs.sh still doesn't remove any trust. Moby's registry.ReadCertsDirectory appends certs.d/<host>/*.crt to tlsconfig.SystemCertPool(), so eMudhra chains that end at a system root still verify. The image pushes also run through docker/setup-buildx-action (L1785, docker-container driver), and BuildKit never reads the host's certs.d. Enforce mode now fails releases (ERR=1) if this step can't install, so releases are gated on a mitigation that does nothing. The docs at docs/release-workflow.md:212 also still say it "covers daemon-side TLS". Either drop the leg and list dockerd/BuildKit under not_covered, or add a mechanism that replaces the pool (for example, a buildkitd config with the clean bundle plus a replaced system bundle for dockerd).

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 281977cfb1b3

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 1 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since d60d8f0
View review run

Review Summary

The new commits move the inline Linux dockerd certs.d loop (repeated in 9 jobs) into a hash-manifested .sh10/dockerd-certs.sh. The helper checks each installed ca.crt by SHA-256, and in enforce mode a failed install now fails the probe (ERR=1). Docs move to v3.10 with nine fixtures. I scanned the full PR diff for security and correctness. No repo-local criteria loaded, so I applied only the base criteria. The incremental diff was complete (not partial).

Security Issues

None found.

Correctness Issues

  • Prior — still present (blocking-correctness, high confidence) .github/workflows/release.yaml:211 (×9 copies), .sh10/dockerd-certs.sh:166-171: the dockerd certs.d mechanism is unchanged and still removes no trust.
    • Moby's registry.ReadCertsDirectory appends certs.d/<host>/*.crt to SystemCertPool(), so chains through the eMudhra intermediates still verify.
    • Image builds and pushes go through docker/setup-buildx-action (L1785, docker-container driver), and BuildKit does not read the host's certs.d.
    • This push makes it worse: under enforce, a failed install sets ERR=1 and fails the release. Releases are now gated on a mitigation that has no effect.
    • docs/release-workflow.md:212 still claims it "covers daemon-side TLS for both image pulls and ECR pushes", and the probe emits distrust: dockerd-certs.d.
    • I posted a fresh inline comment because the old thread is outdated.

Suggestions

  • New (medium confidence) PR description: it says "The v3.8 enforce-mode canary of this exact branch is linked below", but only the v3.5 and v3.7 (report-mode) runs are linked. The branch is now v3.10 and ships enforce, so the on-runner evidence for the shipped mode is missing.
  • Prior — still present .github/workflows/release.yaml:132-234: the ~100-line probe is still copied into 9 jobs, and this push again made the same edit 9 times. Moving it into a checksummed .sh10/probe.sh would turn each change into a single edit.
  • Prior — still present .github/workflows/release.yaml:487: release-preflight pins .sh10 with job.workflow_sha, while the other release jobs use needs.determine-workflows-ref.outputs.ref. This is documented, but the two pins can disagree.

Resolved prior findings

  • SH10_MODE: enforce vs. a description saying report (release.yaml:135): fixed. The PR body now says "Shipped values: SH10_MODE: enforce + SH10_APPLY_DISTRUST: "true"", and docs/release-workflow.md:35 says the workflow ships with SH10_MODE: enforce. The missing enforce canary is tracked as a new suggestion above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Correctness Issues

In `.github/workflows/release.yaml` and `.sh10/dockerd-certs.sh`:
- Around release.yaml line 211 (and the 8 other probe copies at 387, 571, 823, 1259, 1649, 2046, 2399, 2669): Docker's /etc/docker/certs.d/<host>/ca.crt is ADDED to the system cert pool (moby registry.ReadCertsDirectory), so installing the clean bundle there removes no trust. BuildKit under docker/setup-buildx-action (docker-container driver, L1785) also ignores the host certs.d. Either remove the dockerd leg (and stop failing enforce-mode releases with ERR=1 when it can't install), add "dockerd/buildkit on Linux" to the not_covered list in the summary line, and correct docs/release-workflow.md lines ~208-225 so they no longer claim daemon-side TLS coverage; or replace it with a mechanism that actually replaces the trust pool (e.g. pass a buildkitd config with the clean bundle via setup-buildx-action's `config-inline`, and for dockerd replace the system bundle it reads), and add a probe check that proves the replacement works.

## Suggestions

In the PR description:
- The text promises a "v3.8 enforce-mode canary of this exact branch ... linked below", but no such link exists, and the branch is now v3.10 shipping enforce. Run and link an enforce-mode canary of the current head, or remove the claim.

In `.github/workflows/release.yaml`:
- Around lines 132-234 (×9): move the duplicated probe script into a hash-manifested `.sh10/probe.sh` and put SH10_MODE / SH10_APPLY_DISTRUST in workflow-level env, so each change is a single edit.
- Around line 487: consider pinning release-preflight's `.sh10` checkout to the same ref as the other jobs (`needs.determine-workflows-ref.outputs.ref`), or explain in the docs why job.workflow_sha is required there.

Reviewed commit: 26a56988311e

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking issues found — see the full review report

Copy link
Copy Markdown
Contributor Author

Thank you for the blocking-correctness catch on the dockerd certs.d leg — verified from source on both counts (moby loadTLSConfig appends certs.d to the system pool and cannot distrust a chain whose root remains in the host store; setup-buildx-action's default docker-container driver means BuildKit never reads host certs.d for build-time pulls). The leg guarded a no-op, and the coverage claim was wrong. The branch is being corrected: the leg, its fixture, and every daemon-coverage sentence are removed; daemon/BuildKit TLS is documented as residual (the image path is bound by the digest pins, immutable tags, and deploy-by-recorded-digest instead). Exactly the class of false-coverage claim worth blocking on — appreciated.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 4 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since 26a5698
View review run

Review Summary

The new commit only changes docs/release-workflow.md. The docs no longer claim that the certs.d helper covers daemon-side TLS. They now say outright that Linux dockerd is not covered: certs.d only adds CAs to the system pool, and the Buildx docker-container driver ignores host certs.d. They also add Linux to the list of uncovered dockerd platforms. No workflow or script code changed. I scanned the full PR diff for security and correctness issues and found nothing new. No repo-local criteria loaded, so I applied only the base criteria.

The probe step now claims no coverage it lacks in the docs, so I've downgraded the remaining dockerd problems to suggestions. Those problems are telemetry that doesn't match the docs, and an enforce gate tied to a helper that does nothing. The helper itself is inert for TLS trust and is not a security regression.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present (downgraded from blocking, medium confidence) .github/workflows/release.yaml:211 (×9 copies), .sh10/dockerd-certs.sh:9-20. The certs.d helper is still invoked, and it still removes no trust.
    • Under SH10_MODE: enforce, a failed install sets ERR=1 and fails the release. A release can therefore be blocked by a mitigation that the docs now admit has no effect.
    • The helper still prints "distrust":"dockerd-certs.d".
    • The final summary's not_covered (L226, plus the 8 other copies) still lists only dockerd-on-macOS/Windows. That contradicts the docs at docs/release-workflow.md:60. I posted an inline comment at L226.
  • New (low) docs/release-workflow.md:65-66: "pending the architect's patch ruling" is internal process wording in user-facing docs. State the current behavior instead, or link a tracking issue.
  • Prior — still present .github/workflows/release.yaml:132-234: the ~100-line probe is still copied into 9 jobs. Moving it into a hash-manifested .sh10/probe.sh would turn each change into a single edit.
  • Prior — still present .github/workflows/release.yaml:487: release-preflight pins .sh10 to job.workflow_sha, while the other release jobs use needs.determine-workflows-ref.outputs.ref. The two pins can disagree.

Resolved prior findings

  • Docs claimed daemon-side TLS coverage (part of the dockerd blocker, threads at L211 and the outdated thread): fixed by docs/release-workflow.md:60-66, which now says "Linux dockerd is not covered by this mitigation", and by L78, which adds "dockerd on Linux". The code-side remainder is tracked as a suggestion above.
  • SH10_MODE: enforce vs. a description saying report (L135 thread): fixed. The PR body states that the shipped values are enforce + distrust true.
  • Missing enforce-mode canary evidence: fixed. The PR body now links run 39650815924 (v3.8, shipped enforce mode).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 211 (and 387, 571, 823, 1259, 1649, 2046, 2399, 2669): the dockerd certs.d helper doesn't distrust anything. Either remove the call, or stop setting ERR=1 under enforce when it fails, so releases aren't gated on a no-op.
- Around line 226 (and the 8 other summary lines): add Linux dockerd/BuildKit to the `not_covered` list, e.g. `dockerd-on-Linux/macOS/Windows`, so the runtime output matches docs/release-workflow.md.
- Around lines 132-234 (×9): move the duplicated probe script into a hash-manifested `.sh10/probe.sh`.
- Around line 487: pin release-preflight's `.sh10` checkout to `needs.determine-workflows-ref.outputs.ref`, or document why `job.workflow_sha` is required there.

In `.sh10/dockerd-certs.sh`:
- Around lines 9-20: change the `"distrust":"dockerd-certs.d"` label (e.g. to `"additive":"dockerd-certs.d"`) so it doesn't claim distrust.

In `docs/release-workflow.md`:
- Around lines 65-66: replace "pending the architect's patch ruling" with a statement of the current behavior, or link a tracking issue.

Comment thread .github/workflows/release.yaml Outdated
summary=ok; [ "${UNK:-0}" -gt 0 ] && summary="ok-with-${UNK}-unknown-cause-rejections"
if [ "$PHYS_BAD" = 1 ]; then summary=STILL_TRUSTS_COMPROMISED; [ "$MITIGATED" = 1 ] && summary=PHYSICAL_STORE_TRUSTS_BUT_MITIGATED_BY_CLEAN_BUNDLE; fi
[ "$ERR" = 1 ] && summary=ERROR
echo "sh10-probe {\"image\":\"$img\",\"os\":\"$os\",\"summary\":\"$summary\",\"mode\":\"$SH10_MODE\",\"apply_distrust\":\"$SH10_APPLY_DISTRUST\",\"residual\":\"$([ "$PHYS_BAD" = 1 ] && echo physical-store-trusts-chain || echo none)\",\"not_covered\":\"action-tarball-downloads-before-step-1;runner-agent-dotnet-client;go(version-gated>=1.27.3);js-actions-and-node-steps-without-NODE_OPTIONS=--use-openssl-ca;dockerd-on-macOS/Windows;windows-node-bundled-roots\"}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The docs now say Linux dockerd is not covered, but this summary line still lists only dockerd-on-macOS/Windows in not_covered. dockerd-certs.sh also still prints "distrust":"dockerd-certs.d". Add Linux dockerd/BuildKit to not_covered here and in the other 8 copies, so the runtime telemetry matches docs/release-workflow.md:60.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 281977cfb1b3

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 4 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since 26a5698
View review run

Review Summary

The new commit only changes docs/release-workflow.md. The docs no longer claim that the certs.d helper covers daemon-side TLS. They now say outright that Linux dockerd is not covered: certs.d only adds CAs to the system pool, and the Buildx docker-container driver ignores host certs.d. They also add Linux to the list of uncovered dockerd platforms. No workflow or script code changed. I scanned the full PR diff for security and correctness issues and found nothing new. No repo-local criteria loaded, so I applied only the base criteria.

The probe step now claims no coverage it lacks in the docs, so I've downgraded the remaining dockerd problems to suggestions. Those problems are telemetry that doesn't match the docs, and an enforce gate tied to a helper that does nothing. The helper itself is inert for TLS trust and is not a security regression.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present (downgraded from blocking, medium confidence) .github/workflows/release.yaml:211 (×9 copies), .sh10/dockerd-certs.sh:9-20. The certs.d helper is still invoked, and it still removes no trust.
    • Under SH10_MODE: enforce, a failed install sets ERR=1 and fails the release. A release can therefore be blocked by a mitigation that the docs now admit has no effect.
    • The helper still prints "distrust":"dockerd-certs.d".
    • The final summary's not_covered (L226, plus the 8 other copies) still lists only dockerd-on-macOS/Windows. That contradicts the docs at docs/release-workflow.md:60. I posted an inline comment at L226.
  • New (low) docs/release-workflow.md:65-66: "pending the architect's patch ruling" is internal process wording in user-facing docs. State the current behavior instead, or link a tracking issue.
  • Prior — still present .github/workflows/release.yaml:132-234: the ~100-line probe is still copied into 9 jobs. Moving it into a hash-manifested .sh10/probe.sh would turn each change into a single edit.
  • Prior — still present .github/workflows/release.yaml:487: release-preflight pins .sh10 to job.workflow_sha, while the other release jobs use needs.determine-workflows-ref.outputs.ref. The two pins can disagree.

Resolved prior findings

  • Docs claimed daemon-side TLS coverage (part of the dockerd blocker, threads at L211 and the outdated thread): fixed by docs/release-workflow.md:60-66, which now says "Linux dockerd is not covered by this mitigation", and by L78, which adds "dockerd on Linux". The code-side remainder is tracked as a suggestion above.
  • SH10_MODE: enforce vs. a description saying report (L135 thread): fixed. The PR body states that the shipped values are enforce + distrust true.
  • Missing enforce-mode canary evidence: fixed. The PR body now links run 39650815924 (v3.8, shipped enforce mode).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 211 (and 387, 571, 823, 1259, 1649, 2046, 2399, 2669): the dockerd certs.d helper doesn't distrust anything. Either remove the call, or stop setting ERR=1 under enforce when it fails, so releases aren't gated on a no-op.
- Around line 226 (and the 8 other summary lines): add Linux dockerd/BuildKit to the `not_covered` list, e.g. `dockerd-on-Linux/macOS/Windows`, so the runtime output matches docs/release-workflow.md.
- Around lines 132-234 (×9): move the duplicated probe script into a hash-manifested `.sh10/probe.sh`.
- Around line 487: pin release-preflight's `.sh10` checkout to `needs.determine-workflows-ref.outputs.ref`, or document why `job.workflow_sha` is required there.

In `.sh10/dockerd-certs.sh`:
- Around lines 9-20: change the `"distrust":"dockerd-certs.d"` label (e.g. to `"additive":"dockerd-certs.d"`) so it doesn't claim distrust.

In `docs/release-workflow.md`:
- Around lines 65-66: replace "pending the architect's patch ruling" with a statement of the current behavior, or link a tracking issue.

Reviewed commit: 9b866f18fc24

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 281977cfb1b3

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since 26a5698
View review run

Review Summary

The new commit removes the Docker daemon certs.d mitigation completely:

  • It deletes .sh10/dockerd-certs.sh and drops its entry from SHA256SUMS.
  • It removes the dockerd-certs.sh call, and the ERR=1 enforce gate on it, from all 9 probe copies.
  • It extends both not_covered summary strings to name dockerd/BuildKit TLS on every platform.
  • It rewrites the Docker section of docs/release-workflow.md to say that daemon/BuildKit TLS is residual.

I scanned the full PR diff for security and correctness. The client-env clean-bundle path (SSL_CERT_FILE/CURL_CA_BUNDLE/GIT_SSL_CAINFO/…) and the enforce logic did not change. No repo-local criteria loaded, so only the base criteria applied. The incremental artifact is not partial: nothing was dropped or truncated.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (high confidence) docs/release-workflow.md:56-59 and the not_covered text at .github/workflows/release.yaml:224 (×9): the stated compensating control is "base-image digests (content-addressed pulls)" / mitigated-by-image-digests+immutable-tags. That control doesn't exist for base images, so dockerd/BuildKit base-image pulls stay unmitigated even though the docs say they're covered.
    • templates/.Dockerfile-template.tmpl:1 (FROM gcr.io/distroless/static-debian13:nonroot) and templates/.Dockerfile-lambda-template.tmpl:1 (FROM public.ecr.aws/lambda/provided:al2023) pull by tag, not by digest.
    • ECR tag immutability is also not configured or verified anywhere in this repo.
  • Prior — still present .github/workflows/release.yaml:132-234: the ~100-line probe is still copied into 9 jobs, and this push made the same edit 9 times again. A hash-manifested .sh10/probe.sh would make each change a single edit.
  • Prior — still present .github/workflows/release.yaml:483: release-preflight pins .sh10 to job.workflow_sha. The later release jobs (L735, 1169, …) use needs.determine-workflows-ref.outputs.ref, so the two pins can disagree.

Resolved prior findings

  • dockerd certs.d leg removes no trust / gates enforce releases on an ineffective mitigation (blocking; threads prior-0, prior-1, review reports 5604214436 and 5604336664): fixed.
    • .sh10/dockerd-certs.sh is deleted, and its SHA256SUMS line is gone.
    • The call and its ERR=1 path are removed from all 9 probe copies (e.g. release.yaml:207-210).
    • docs/release-workflow.md:50-54 now states that certs.d is additive and that BuildKit uses its own store.
  • not_covered omits Linux dockerd (prior-2): fixed. release.yaml:224 (×9) now lists dockerd-and-buildkit-TLS-on-all-platforms, and docs/release-workflow.md:65 lists dockerd on Linux, macOS, and Windows.
  • SH10_MODE: enforce vs. description (prior-3, L135): fixed. The PR body states the shipped values are enforce + distrust true, and the v3.8 enforce-mode canary run is now linked.
  • "pending the architect's patch ruling" wording in docs: fixed. That text no longer appears in docs/release-workflow.md.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `docs/release-workflow.md`:
- Around line 56-59: The doc claims base-image digests (content-addressed pulls) bind the image path, but templates/.Dockerfile-template.tmpl:1 and templates/.Dockerfile-lambda-template.tmpl:1 use tag-only FROM lines. Either pin those FROM lines with @sha256: digests, or reword the doc (and the `mitigated-by-image-digests+immutable-tags` text in release.yaml's not_covered summary, line ~224 and its 8 copies) to say base-image pulls are an unmitigated residual.

In `.github/workflows/release.yaml`:
- Around lines 132-234 (x9 copies): move the duplicated probe script into a hash-manifested `.sh10/probe.sh` so each change is a single edit.
- Around line 483: pin release-preflight's `.sh10` checkout to the same ref as the other release jobs (`needs.determine-workflows-ref.outputs.ref`), or document why `job.workflow_sha` is required there.

Comment thread docs/release-workflow.md Outdated
chain whose root remains in the host store. The default Buildx
`docker-container` driver uses its own CA store, not host `certs.d`.

The mitigations that actually bind the image path are base-image digests

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion (high confidence): Base images aren't actually pinned by digest. templates/.Dockerfile-template.tmpl:1 uses FROM gcr.io/distroless/static-debian13:nonroot and templates/.Dockerfile-lambda-template.tmpl:1 uses FROM public.ecr.aws/lambda/provided:al2023, both by tag only. So the "content-addressed pulls" control this paragraph (and the probe's not_covered text mitigated-by-image-digests+immutable-tags) relies on doesn't cover base-image pulls through dockerd/BuildKit. Either pin the template FROM lines with @sha256:, or say that base-image pulls are an unmitigated residual.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 1bdffc6b45a2

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base e6432834cb21.
Review mode: incremental since 26a5698
View review run

Review Summary

The new commit removes the Docker daemon certs.d mitigation completely:

  • It deletes .sh10/dockerd-certs.sh and drops its entry from SHA256SUMS.
  • It removes the dockerd-certs.sh call, and the ERR=1 enforce gate on it, from all 9 probe copies.
  • It extends both not_covered summary strings to name dockerd/BuildKit TLS on every platform.
  • It rewrites the Docker section of docs/release-workflow.md to say that daemon/BuildKit TLS is residual.

I scanned the full PR diff for security and correctness. The client-env clean-bundle path (SSL_CERT_FILE/CURL_CA_BUNDLE/GIT_SSL_CAINFO/…) and the enforce logic did not change. No repo-local criteria loaded, so only the base criteria applied. The incremental artifact is not partial: nothing was dropped or truncated.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (high confidence) docs/release-workflow.md:56-59 and the not_covered text at .github/workflows/release.yaml:224 (×9): the stated compensating control is "base-image digests (content-addressed pulls)" / mitigated-by-image-digests+immutable-tags. That control doesn't exist for base images, so dockerd/BuildKit base-image pulls stay unmitigated even though the docs say they're covered.
    • templates/.Dockerfile-template.tmpl:1 (FROM gcr.io/distroless/static-debian13:nonroot) and templates/.Dockerfile-lambda-template.tmpl:1 (FROM public.ecr.aws/lambda/provided:al2023) pull by tag, not by digest.
    • ECR tag immutability is also not configured or verified anywhere in this repo.
  • Prior — still present .github/workflows/release.yaml:132-234: the ~100-line probe is still copied into 9 jobs, and this push made the same edit 9 times again. A hash-manifested .sh10/probe.sh would make each change a single edit.
  • Prior — still present .github/workflows/release.yaml:483: release-preflight pins .sh10 to job.workflow_sha. The later release jobs (L735, 1169, …) use needs.determine-workflows-ref.outputs.ref, so the two pins can disagree.

Resolved prior findings

  • dockerd certs.d leg removes no trust / gates enforce releases on an ineffective mitigation (blocking; threads prior-0, prior-1, review reports 5604214436 and 5604336664): fixed.
    • .sh10/dockerd-certs.sh is deleted, and its SHA256SUMS line is gone.
    • The call and its ERR=1 path are removed from all 9 probe copies (e.g. release.yaml:207-210).
    • docs/release-workflow.md:50-54 now states that certs.d is additive and that BuildKit uses its own store.
  • not_covered omits Linux dockerd (prior-2): fixed. release.yaml:224 (×9) now lists dockerd-and-buildkit-TLS-on-all-platforms, and docs/release-workflow.md:65 lists dockerd on Linux, macOS, and Windows.
  • SH10_MODE: enforce vs. description (prior-3, L135): fixed. The PR body states the shipped values are enforce + distrust true, and the v3.8 enforce-mode canary run is now linked.
  • "pending the architect's patch ruling" wording in docs: fixed. That text no longer appears in docs/release-workflow.md.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `docs/release-workflow.md`:
- Around line 56-59: The doc claims base-image digests (content-addressed pulls) bind the image path, but templates/.Dockerfile-template.tmpl:1 and templates/.Dockerfile-lambda-template.tmpl:1 use tag-only FROM lines. Either pin those FROM lines with @sha256: digests, or reword the doc (and the `mitigated-by-image-digests+immutable-tags` text in release.yaml's not_covered summary, line ~224 and its 8 copies) to say base-image pulls are an unmitigated residual.

In `.github/workflows/release.yaml`:
- Around lines 132-234 (x9 copies): move the duplicated probe script into a hash-manifested `.sh10/probe.sh` so each change is a single edit.
- Around line 483: pin release-preflight's `.sh10` checkout to the same ref as the other release jobs (`needs.determine-workflows-ref.outputs.ref`), or document why `job.workflow_sha` is required there.

Reviewed commit: 281977cfb1b3

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

@github-actions
github-actions Bot dismissed stale reviews from themself October 21, 2026 18:32

Superseded by a completed review with no blocking issues; current audit evidence persisted in CI.

gontzess added a commit that referenced this pull request Oct 21, 2026
… runner TLS trust for the incident CA chains (#160)

## Why

Following the public disclosure of compromised eMudhra intermediate
certificates, GitHub-hosted runner images may still trust those
intermediates until patched images roll out
(actions/runner-images#15018, open). This PR ships **`ca-trust-guard`**:
a self-contained composite action any job in any repo can run as step 1
(no checkout required) that (a) measures whether the runner's trust
stores still accept the incident chains, (b) **denies the six incident
certificates in the OS trust stores**, and (c) redirects the job's TLS
clients to a committed, hash-verified clean CA bundle — with an enforce
mode that fails closed unless every mitigation is **verified where it
was applied**. This is preventive hardening; it does not respond to any
known compromise of ConductorOne release artifacts.

## What

- **`.github/actions/ca-trust-guard/action.yml`** — five one-line glue
steps (probe before → deny → apply bundle → probe after → summarize);
inputs `mode` (report|enforce, default enforce), `apply-distrust`
(default true), `os-deny` (default true), `os-deny-elevation`
(fail|warn, default fail — non-elevated/self-hosted consumers opt into
`warn` knowingly).
- **`cmd/ca-trust-guard`** — a stdlib-only Go command (built offline on
the runner's own Go via a module-off bootstrap; PATH → toolcache → brew
discovery). OpenSSL is the chain **measurement** instrument by design:
Go ≥1.27.3's `crypto/x509` applies the incident SPKI distrust
*unconditionally*, so a Go-native verify would read every store as
distrusting and could not measure anything (a living-doc test asserts
this; the README records the reasoning). Orchestration, `chains.json`,
the single v3.11-tested classifier, `encoding/json` rows (openssl
path+version logged per row), and summarize/enforce are Go. The positive
control (every chain must verify against the pinned vulnerable roots)
runs first and is binding.
- **`scripts/deny-os.sh` / `deny-os.ps1`** — data-driven from
`fixtures/incident-certs.json`: **4 incident roots** (emSign ECC/TLS/CS
Root CA - G3, AAA Certificate Services) + **2 compromised
intermediates** (EM DV TLS CA - G3B and its AAA cross-signed variant —
the certificates whose keys actually leaked), each pinned by sha1+sha256
with refusal-before-mutation. Linux: `/etc/ca-certificates.conf`
blacklist + `update-ca-certificates` + compiled-bundle verification.
macOS: `security add-trusted-cert -d -r deny` into System.keychain
(roots and intermediates). Windows: import into
`Cert:\LocalMachine\Disallowed` (skipped with an explicit row when not
elevated; `os-deny-elevation: fail` makes that a hard failure).
- **`scripts/apply-clean-bundle.sh`** — the client-env leg
(SSL_CERT_FILE/CURL_CA_BUNDLE/GIT_SSL_CAINFO/REQUESTS_CA_BUNDLE/AWS_CA_BUNDLE/NPM_CONFIG_CAFILE;
Windows native-path git/curl only).
- **Enforce post-condition:** a green job is *proof*, not attempt —
clean-bundle rows VERIFIED-DISTRUST **and** per-OS applied-store
evidence (Linux system bundle; macOS SecTrust; Windows both intermediate
thumbprints in Disallowed). Residuals stay measured and reported (macOS
`/etc/ssl`/brew, dockerd/BuildKit — see #159 for why the daemon class
isn't coverable; the image path is bound by digest pins + immutable
tags).
- Fixtures: 10-payload `SHA256SUMS` (8 original + `chains.json` +
`incident-certs.json`), LF-pinned. Tests: Go table tests (real-OpenSSL
stores, classifier, every mode/flag/elevation combination, chains
loading) + shell suites (deny dry-run/refusal/elevation/idempotency;
bootstrap discovery incl. CRLF regressions), wired into verify.yaml +
make test-scripts.
- **Attribution:** the OS-level deny mechanics, fingerprint-keyed
refusal-before-mutation, Linux verification loop, and the
verify-where-applied enforce principle are adapted from gsilvestrin's
ductone/multipass#951 — thank you. Follow-up (LOW): extend the deny set
to all 16 impacted intermediates once their PEMs are obtained from CT
logs by sha256.

## Verification

- reviewer-claude gate (full review): stdlib-only Go with the v3.11
classifier contract; six-identity data-driven denial with
dual-fingerprint refusal before mutation on all three OSes (all
sha1/sha256 independently recomputed); five one-line glue steps;
fixtures checksum-clean under an autocrlf=true clone; 12 Go tests / 646
subtests + both shell suites pass.
- **Cross-repo canary** (`uses: …ca-trust-guard@<sha>` from
baton-github-test): run 39667466967 surfaced two real bugs (macOS runner
has no Go on PATH → toolcache/brew discovery; Windows native jq CRLF
emission → normalization + CR-stripping + regression tests); fixed and
re-run —
[39669995046](https://github.com/ConductorOne/baton-github-test/actions/runs/39669995046)
**all three OSes green**; re-confirmed at the rebased-on-main tip by
[39672516187](https://github.com/ConductorOne/baton-github-test/actions/runs/39672516187)
(branch now contains #157/#158; repo CI green incl. the image-lock
gate): Windows log shows all 6 identities `DENIED … in Disallowed` with
AFTER rows VERIFIED-DISTRUST via the natural thumbprint evidence; macOS
SecTrust denied (two independent denies); Linux system bundle
blacklisted; hosted Windows elevation confirmed.

---------

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
@gontzess
gontzess force-pushed the steve.gontzes/sh10-probe-report branch from 281977c to 1bdffc6 Compare October 21, 2026 22:43
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 1bdffc6b45a2

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 1 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 99f9b2fc150f.
Review mode: full
View review run

Review Summary

At head 1bdffc6, this PR wires two already-merged composite actions into release.yaml, both pinned at 99f9b2fc:

  • ca-trust-guard runs as step 0 in 9 jobs. notify-release-failure is deliberately exempt.
  • locked-tools runs as step 1 in 6 tool-using jobs. It replaces the per-job install, verify and gon-build steps.

The module gates now call _workflows/.github/actions/locked-tools/verify-locked-go.sh directly. The four scripts/ forwarding wrappers and their .gitattributes lines are deleted. release.yaml is added to the CI path filters, and test-tool-integrity.py now asserts step order, pins and inputs. Docs are updated to match.

I scanned the full diff for security and correctness. I also checked the action internals:

  • locked-tools.sh routes Windows installs through install-tool.ps1 via cygpath and asserts the Go version itself, so dropping the separate version step loses nothing.
  • gon is built from $GITHUB_WORKSPACE/.locked-tools-gon.* with GOFLAGS=-mod=readonly, GOPROXY and GOSUMDB set on the step.
  • No _workflows checkout is sparse, so the new script path resolves.
  • No references to the removed wrappers remain.
  • All jobs run on GitHub-hosted runners, so the guard's os-deny with elevation fail default is appropriate.

No repo-local criteria loaded, so only the base criteria were applied.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (high confidence) .github/workflows/release.yaml:123: the PR title and body don't describe this diff. They describe an inline .sh10/ probe, SH10_MODE env, sparse .sh10/ checkouts and a .sh10/** -text gitattributes entry. None of these exist at head (.sh10/ is absent and release.yaml has zero SH10 matches). What ships is adoption of the pinned actions plus removal of the wrappers.

Resolved prior findings

All four prior findings are obsolete. Each one targeted the inline .sh10 probe, and that probe has been replaced by the pinned ca-trust-guard action call (e.g. release.yaml:123-124). Specifically:

  • Enforce-mode vs. description mismatch (prior-0): the SH10_MODE env is gone.
  • dockerd certs.d leg removes no trust (prior-1, prior-2): .sh10/dockerd-certs.sh and its invocation no longer exist.
  • not_covered omits Linux dockerd (prior-3): the summary line no longer exists in release.yaml.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 123: The PR title and description still describe an inline `.sh10/` probe, SH10_MODE env, sparse `.sh10/` checkouts and a `.sh10/** -text` gitattributes entry, none of which exist in the current diff. Rewrite the PR title and body to describe what ships: SHA-pinned `ca-trust-guard` as step 0 in 9 release jobs (notify-release-failure exempt), pinned `locked-tools` in 6 tool-using jobs replacing the per-job install steps, module gates calling the action-local verify-locked-go.sh, and removal of the four scripts/ forwarding wrappers.

@gontzess gontzess changed the title Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle Route release jobs through the ca-trust-guard + locked-tools composite actions Oct 21, 2026
runs-on: ubuntu-latest

steps:
- name: Enforce runner CA trust

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The PR title and body don't match this diff. They describe an inline .sh10/ probe copied into 9 jobs, SH10_MODE/SH10_APPLY_DISTRUST env, sparse .sh10/ checkouts and a .sh10/** -text gitattributes entry, but none of that exists at head. The diff instead adopts the already-merged ca-trust-guard and locked-tools actions pinned at 99f9b2fc and deletes the scripts/ wrappers. Please update the title and body so reviewers and the merge history describe what actually ships. (Confidence: high.)

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 7d2f6b8d433e

General PR Review: Probe runner TLS trust stores and redirect release jobs to a verified clean CA bundle

Blocking Issues: 0 | Suggestions: 1 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 99f9b2fc150f.
Review mode: full
View review run

Review Summary

At head 1bdffc6, this PR wires two already-merged composite actions into release.yaml, both pinned at 99f9b2fc:

  • ca-trust-guard runs as step 0 in 9 jobs. notify-release-failure is deliberately exempt.
  • locked-tools runs as step 1 in 6 tool-using jobs. It replaces the per-job install, verify and gon-build steps.

The module gates now call _workflows/.github/actions/locked-tools/verify-locked-go.sh directly. The four scripts/ forwarding wrappers and their .gitattributes lines are deleted. release.yaml is added to the CI path filters, and test-tool-integrity.py now asserts step order, pins and inputs. Docs are updated to match.

I scanned the full diff for security and correctness. I also checked the action internals:

  • locked-tools.sh routes Windows installs through install-tool.ps1 via cygpath and asserts the Go version itself, so dropping the separate version step loses nothing.
  • gon is built from $GITHUB_WORKSPACE/.locked-tools-gon.* with GOFLAGS=-mod=readonly, GOPROXY and GOSUMDB set on the step.
  • No _workflows checkout is sparse, so the new script path resolves.
  • No references to the removed wrappers remain.
  • All jobs run on GitHub-hosted runners, so the guard's os-deny with elevation fail default is appropriate.

No repo-local criteria loaded, so only the base criteria were applied.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New (high confidence) .github/workflows/release.yaml:123: the PR title and body don't describe this diff. They describe an inline .sh10/ probe, SH10_MODE env, sparse .sh10/ checkouts and a .sh10/** -text gitattributes entry. None of these exist at head (.sh10/ is absent and release.yaml has zero SH10 matches). What ships is adoption of the pinned actions plus removal of the wrappers.

Resolved prior findings

All four prior findings are obsolete. Each one targeted the inline .sh10 probe, and that probe has been replaced by the pinned ca-trust-guard action call (e.g. release.yaml:123-124). Specifically:

  • Enforce-mode vs. description mismatch (prior-0): the SH10_MODE env is gone.
  • dockerd certs.d leg removes no trust (prior-1, prior-2): .sh10/dockerd-certs.sh and its invocation no longer exist.
  • not_covered omits Linux dockerd (prior-3): the summary line no longer exists in release.yaml.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 123: The PR title and description still describe an inline `.sh10/` probe, SH10_MODE env, sparse `.sh10/` checkouts and a `.sh10/** -text` gitattributes entry, none of which exist in the current diff. Rewrite the PR title and body to describe what ships: SHA-pinned `ca-trust-guard` as step 0 in 9 release jobs (notify-release-failure exempt), pinned `locked-tools` in 6 tool-using jobs replacing the per-job install steps, module gates calling the action-local verify-locked-go.sh, and removal of the four scripts/ forwarding wrappers.

Reviewed commit: 1bdffc6b45a2

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

@gontzess
gontzess marked this pull request as ready for review October 21, 2026 22:57
@gontzess
gontzess requested a review from a team October 21, 2026 22:57
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 7d2f6b8d433e

General PR Review: Route release jobs through the ca-trust-guard + locked-tools composite actions

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 99f9b2fc150f.
Review mode: incremental since 1bdffc6
View review run

Review Summary

The PR makes 9 release jobs start with the SHA-pinned ca-trust-guard action (notify-release-failure is exempt). Six tool-using jobs then run the pinned locked-tools action, which replaces the per-job install steps. The go.mod module gates now call the action-local verify-locked-go.sh, and the four scripts/ wrappers are deleted.

The new commit (7d2f6b8) moves the pins:

It applies the new pins to all 9 guard steps and all 6 tools steps. It also updates docs/release-workflow.md and the exact-pin constants in scripts/test-tool-integrity.py. Through the GitHub compare API I confirmed both SHAs are on main: 562a1ea6 is main HEAD and 4d06ff31 is the commit just before it. That rules out unmerged or fork ("imposter") commits.

I scanned the full PR diff (10 files) for security and correctness issues. No repo-local criteria loaded, so only the base criteria were applied.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

Resolved prior findings

  • SH10_MODE: enforce vs. description (prior-0): obsolete. SH10_MODE no longer exists in release.yaml; the inline probe was replaced by the ca-trust-guard action step (e.g. release.yaml:123-124).
  • dockerd certs.d leg removes no trust (prior-1, prior-2): obsolete. .sh10/dockerd-certs.sh and its invocations are gone. The PR body now openly lists Docker daemon/BuildKit TLS as a coverage limit instead of claiming a fix.
  • not_covered omits Linux dockerd (prior-3): obsolete. The inline summary line was removed along with the probe.
  • PR title/body describe the .sh10/ probe (prior-4): fixed. The title and body now describe adopting the actions and deleting the wrappers. Only the pin SHAs in the body are stale, which is tracked as a new suggestion above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 124: The PR description still says both composite actions are pinned at 99f9b2fc and cites #160/#161 canaries. Update it to the shipped pins (ca-trust-guard@4d06ff31da09d2012770879c2c43c54dec24fe76, locked-tools@562a1ea6fa6abd0460950dfc95c7f845aa5f1448). Link canary evidence covering #163/#164 and the promised full release canary.
- Around line 304 (and lines 439, 758, 1037, 1307, 1568): The module gates read tool-locks.txt from the _workflows checkout at job.workflow_sha, while Go is installed by locked-tools pinned at 562a1ea6. Add a check in scripts/test-tool-integrity.py, or a doc note, so the local lock's Go version and the pinned action's Go version cannot silently diverge when one of them is bumped.

Comment thread .github/workflows/release.yaml Outdated

steps:
- name: Enforce runner CA trust
uses: ConductorOne/github-workflows/.github/actions/ca-trust-guard@4d06ff31da09d2012770879c2c43c54dec24fe76

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: This commit moves the pins to ca-trust-guard@4d06ff31 (#164) and locked-tools@562a1ea6 (#163), and I confirmed both commits are on main. The PR body still says both actions are at @99f9b2fc and points to the #160/#161 canaries as evidence. Please update the body to the new pins and link canary evidence for the #163/#164 code that now ships.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit a096b3eb6e20

General PR Review: Route release jobs through the ca-trust-guard + locked-tools composite actions

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 99f9b2fc150f.
Review mode: incremental since 1bdffc6
View review run

Review Summary

The PR makes 9 release jobs start with the SHA-pinned ca-trust-guard action (notify-release-failure is exempt). Six tool-using jobs then run the pinned locked-tools action, which replaces the per-job install steps. The go.mod module gates now call the action-local verify-locked-go.sh, and the four scripts/ wrappers are deleted.

The new commit (7d2f6b8) moves the pins:

It applies the new pins to all 9 guard steps and all 6 tools steps. It also updates docs/release-workflow.md and the exact-pin constants in scripts/test-tool-integrity.py. Through the GitHub compare API I confirmed both SHAs are on main: 562a1ea6 is main HEAD and 4d06ff31 is the commit just before it. That rules out unmerged or fork ("imposter") commits.

I scanned the full PR diff (10 files) for security and correctness issues. No repo-local criteria loaded, so only the base criteria were applied.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

Resolved prior findings

  • SH10_MODE: enforce vs. description (prior-0): obsolete. SH10_MODE no longer exists in release.yaml; the inline probe was replaced by the ca-trust-guard action step (e.g. release.yaml:123-124).
  • dockerd certs.d leg removes no trust (prior-1, prior-2): obsolete. .sh10/dockerd-certs.sh and its invocations are gone. The PR body now openly lists Docker daemon/BuildKit TLS as a coverage limit instead of claiming a fix.
  • not_covered omits Linux dockerd (prior-3): obsolete. The inline summary line was removed along with the probe.
  • PR title/body describe the .sh10/ probe (prior-4): fixed. The title and body now describe adopting the actions and deleting the wrappers. Only the pin SHAs in the body are stale, which is tracked as a new suggestion above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `.github/workflows/release.yaml`:
- Around line 124: The PR description still says both composite actions are pinned at 99f9b2fc and cites #160/#161 canaries. Update it to the shipped pins (ca-trust-guard@4d06ff31da09d2012770879c2c43c54dec24fe76, locked-tools@562a1ea6fa6abd0460950dfc95c7f845aa5f1448). Link canary evidence covering #163/#164 and the promised full release canary.
- Around line 304 (and lines 439, 758, 1037, 1307, 1568): The module gates read tool-locks.txt from the _workflows checkout at job.workflow_sha, while Go is installed by locked-tools pinned at 562a1ea6. Add a check in scripts/test-tool-integrity.py, or a doc note, so the local lock's Go version and the pinned action's Go version cannot silently diverge when one of them is bumped.

Reviewed commit: 7d2f6b8d433e

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

gontzess added a commit that referenced this pull request Oct 22, 2026
)

## Why

Caller Go gates must use the version and lock identity returned by the
locked-tools action, not rediscover expectations from a separate
workflow checkout. The action remains the single owner of lock metadata
parsing.

## What

- Add `lock_path`: the absolute path of the exact lock used
(action-local canonical file by default, resolved reviewed override when
supplied). Preserve per-tool outputs, `versions`, and `lock_sha256`.
- Wire expected Go version, path, and hash through
prepare/install/source-build/result phases. Keep cross-platform
single-stable-Go-version (`sort -u`) sanity in prepare.
- Make `verify-locked-go.sh` consume `EXPECTED_GO_VERSION`,
`EXPECTED_LOCK_SHA256`, and `LOCK_PATH`. It hashes bytes to check
identity but never parses lock versions. Missing/partial expectations,
drift, nonlocal toolchain mode, and version mismatch fail closed.
- Restore runtime/module assertions: directive checks first, runtime
version equality, then readonly/offline `GOTOOLCHAIN=local go list -m`
with workspace discovery disabled.
- Remove the repository Go-gate wrapper, positional lockfile mode, gon
adapter and their compatibility fixtures. Go gates are strictly
environment-only; positional arguments cannot supply missing
expectations.

**Intentional staged rollout (verifiable):** main-tip release.yaml's 12
old wrapper calls are unresolved until the coordinated caller amendment
lands in #159 (branch steve.gontzes/sh10-probe-report). No live release
path is affected: the v4 tag still points at e643283 (pre-dates these
actions), every sampled connector consumes @v4, and code search finds
zero @main/@sha callers; the failure mode in the window is fail-closed
(file-not-found / missing env), never a silent pass. Do not promote v4
between this merge and #159 landing.

## Verification

- `make test-scripts`: pass, including 27 integrity fixtures (one
native-Windows-only skip locally), 23 image/update tests, workflow
contracts, and both guard Bash suites.
- `go vet ./...` and `go test -count=1 ./...`: pass with local/offline
settings.
- Real local Go smoke: output-derived env contract checks directives
1.13, 1.27, and 1.27.3 using actual offline `go list -m`.
- Fixtures cover absolute/existing `lock_path`, preserved version/hash
outputs, metadata-reader ownership, missing env, hash drift, runtime
mismatch, go-list failure/disagreement, and rejection of positional
lockfile fallback.
- Shell syntax, image-lock gate, and `git diff --check`: pass.
`.github/workflows/release.yaml` is byte-unchanged.

---------

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
gontzess and others added 3 commits October 22, 2026 01:48
Bootstrap guarded jobs before checkouts, retain the failure-notification exemption and conditional preflight tooling, and preserve module gates through action-local helpers. Retire forwarding wrappers and keep ordering regressions enabled for release-only changes.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Use distinct immutable guard and locked-tools refs from main, and align the expected-pin assertions and bootstrap documentation without changing job behavior.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Load local trust and tool actions from job.workflow_sha and bind module gates to installed version and lock-identity outputs. Keep optional preflight output parsing skip-safe without a version fallback, and preserve caller verification before release credentials.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
@gontzess
gontzess force-pushed the steve.gontzes/sh10-probe-report branch from 7d2f6b8 to a096b3e Compare October 22, 2026 02:25
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit a096b3eb6e20

General PR Review: Route release jobs through the ca-trust-guard + locked-tools composite actions

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 83c8f948447e.
Review mode: full
View review run

Review Summary

Nine release.yaml jobs now start by checking out _workflows at job.workflow_sha with a SHA-pinned actions/checkout and persist-credentials: false. Each then runs the local ./_workflows/.github/actions/ca-trust-guard, and six of them also run ./_workflows/.github/actions/locked-tools (id: tools). Steps 2 and 3 run before caller checkout and credentials.

  • The old per-job Go/gon/syft/GoReleaser install steps and the three scripts/ forwarders are gone.
  • The module gates now call the action-local verify-locked-go.sh with the steps.tools outputs.
  • ci.yaml now triggers on release.yaml, and test-tool-integrity.py enforces the step order, tool lists, the notify-release-failure exemption, and contents: read.

I scanned the full PR diff for security and correctness. I also checked that:

  • the guard's GUARD_ROOT (action_path/../../..) resolves to the _workflows checkout;
  • .gitattributes keeps LF line endings for the guard and locked-tools scripts on Windows;
  • every job already has contents: read;
  • no references to the deleted wrappers remain.

No repo-local criteria loaded. I applied the base criteria only.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present (reworded), .github/workflows/release.yaml:134 (high confidence): the PR body still says the actions are pinned @99f9b2fc and that the guard is "step 1 … before any checkout". The latest commit (a096b3e) removed every remote action pin. The guard now runs as step 2, from a local _workflows checkout. The ca-trust-guard: composite action that measures, denies, and redirects runner TLS trust for the incident CA chains #160/locked-tools: composite action for hash-verified release toolchain installs from a single canonical lock #161 canaries tested the remote-pinned form, and the promised full release canary for this form is still unlinked. I posted a fresh inline comment because the earlier threads are outdated.
  • New, docs/release-workflow.md:238-241 (medium confidence): the bootstrap checkout runs before the guard, and actions/checkout's token input defaults to github.token. So a read-scoped GITHUB_TOKEN is sent over TLS that the guard hasn't checked yet. This contradicts the claims of "no token input" and "before … credentials". Content integrity is still bound by the commit SHA, and this isn't a regression. Document the residual, or use token: '' for the public repo. The test's credential check also misses the implicit default.

Resolved prior findings

  • prior-0 (SH10_MODE: enforce vs. body), prior-1 / prior-2 (dockerd certs.d adds no distrust), prior-3 (not_covered omits Linux dockerd): obsolete. The inline .sh10 probe and dockerd-certs.sh are gone, replaced by the ca-trust-guard step (e.g. release.yaml:132-134). The PR body now lists Docker daemon/BuildKit TLS as a coverage limit.
  • prior-5 (title/body describe the .sh10/ probe): fixed. The title and body now describe adopting the composite actions. The new mismatch about the remote pins is tracked under prior-4 above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In the PR description (relates to `.github/workflows/release.yaml` around lines 120-134 and the matching bootstrap steps in the other 8 jobs):
- The body says ca-trust-guard and locked-tools are pinned `@99f9b2fc` and that the guard is step 1, before any checkout. The workflow now runs the local `./_workflows/.github/actions/*` actions after a `_workflows` checkout at `job.workflow_sha`, so the guard is step 2. Update the What/Evidence sections to describe this, and link a release canary that exercises this local-checkout form.

In `docs/release-workflow.md`:
- Around lines 238-241: "no token input" suggests the bootstrap checkout carries no credential. In fact `actions/checkout` defaults `token` to `github.token` and sends it during the pre-guard fetch. Either document this residual exposure (read-scoped token, content bound by the commit SHA), or set `token: ''` on the public `ConductorOne/github-workflows` bootstrap checkout. If you add `token: ''`, update the `bootstrap["with"]` assertion in `scripts/test-tool-integrity.py`.

persist-credentials: false

- name: Enforce runner CA trust
uses: ./_workflows/.github/actions/ca-trust-guard

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The PR body says both actions are pinned at @99f9b2fc and that the guard is "step 1 … before any checkout or credential". After a096b3e the diff has no remote action pins. Each job now runs ./_workflows/.github/actions/* from a _workflows checkout at job.workflow_sha, so the guard is step 2. The #160/#161 canaries cited as evidence tested the remote-pinned form. Please update the body, and link the release canary for this local-checkout form before merge. (High confidence.)

Comment thread docs/release-workflow.md Outdated
Comment on lines +238 to +241
Nine release jobs first check out `_workflows` at `${{ job.workflow_sha }}`
with a SHA-pinned checkout action, `persist-credentials: false`, and no token
input. This read-only infrastructure checkout provides the workflow's own
action implementations and canonical lock; it does not execute caller code.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: "no token input" doesn't mean no credential. actions/checkout's token input defaults to ${{ github.token }}, and it is sent as a git auth header when fetching _workflows. That fetch runs before ca-trust-guard, under the unguarded trust store. The fetch is bound to the commit SHA, so content integrity holds. But the caller's read-scoped GITHUB_TOKEN still goes over a pre-guard TLS connection. The test's "github.token" in str(step) check can't see that implicit default. This isn't a regression, since the old checkouts were also unguarded. Either document this residual, or verify the commit with an unauthenticated fetch, e.g. token: '' where the repo is public. (Medium confidence.)

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 5b145dbbba57

General PR Review: Route release jobs through the ca-trust-guard + locked-tools composite actions

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 83c8f948447e.
Review mode: full
View review run

Review Summary

Nine release.yaml jobs now start by checking out _workflows at job.workflow_sha with a SHA-pinned actions/checkout and persist-credentials: false. Each then runs the local ./_workflows/.github/actions/ca-trust-guard, and six of them also run ./_workflows/.github/actions/locked-tools (id: tools). Steps 2 and 3 run before caller checkout and credentials.

  • The old per-job Go/gon/syft/GoReleaser install steps and the three scripts/ forwarders are gone.
  • The module gates now call the action-local verify-locked-go.sh with the steps.tools outputs.
  • ci.yaml now triggers on release.yaml, and test-tool-integrity.py enforces the step order, tool lists, the notify-release-failure exemption, and contents: read.

I scanned the full PR diff for security and correctness. I also checked that:

  • the guard's GUARD_ROOT (action_path/../../..) resolves to the _workflows checkout;
  • .gitattributes keeps LF line endings for the guard and locked-tools scripts on Windows;
  • every job already has contents: read;
  • no references to the deleted wrappers remain.

No repo-local criteria loaded. I applied the base criteria only.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present (reworded), .github/workflows/release.yaml:134 (high confidence): the PR body still says the actions are pinned @99f9b2fc and that the guard is "step 1 … before any checkout". The latest commit (a096b3e) removed every remote action pin. The guard now runs as step 2, from a local _workflows checkout. The ca-trust-guard: composite action that measures, denies, and redirects runner TLS trust for the incident CA chains #160/locked-tools: composite action for hash-verified release toolchain installs from a single canonical lock #161 canaries tested the remote-pinned form, and the promised full release canary for this form is still unlinked. I posted a fresh inline comment because the earlier threads are outdated.
  • New, docs/release-workflow.md:238-241 (medium confidence): the bootstrap checkout runs before the guard, and actions/checkout's token input defaults to github.token. So a read-scoped GITHUB_TOKEN is sent over TLS that the guard hasn't checked yet. This contradicts the claims of "no token input" and "before … credentials". Content integrity is still bound by the commit SHA, and this isn't a regression. Document the residual, or use token: '' for the public repo. The test's credential check also misses the implicit default.

Resolved prior findings

  • prior-0 (SH10_MODE: enforce vs. body), prior-1 / prior-2 (dockerd certs.d adds no distrust), prior-3 (not_covered omits Linux dockerd): obsolete. The inline .sh10 probe and dockerd-certs.sh are gone, replaced by the ca-trust-guard step (e.g. release.yaml:132-134). The PR body now lists Docker daemon/BuildKit TLS as a coverage limit.
  • prior-5 (title/body describe the .sh10/ probe): fixed. The title and body now describe adopting the composite actions. The new mismatch about the remote pins is tracked under prior-4 above.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In the PR description (relates to `.github/workflows/release.yaml` around lines 120-134 and the matching bootstrap steps in the other 8 jobs):
- The body says ca-trust-guard and locked-tools are pinned `@99f9b2fc` and that the guard is step 1, before any checkout. The workflow now runs the local `./_workflows/.github/actions/*` actions after a `_workflows` checkout at `job.workflow_sha`, so the guard is step 2. Update the What/Evidence sections to describe this, and link a release canary that exercises this local-checkout form.

In `docs/release-workflow.md`:
- Around lines 238-241: "no token input" suggests the bootstrap checkout carries no credential. In fact `actions/checkout` defaults `token` to `github.token` and sends it during the pre-guard fetch. Either document this residual exposure (read-scoped token, content bound by the commit SHA), or set `token: ''` on the public `ConductorOne/github-workflows` bootstrap checkout. If you add `token: ''`, update the `bootstrap["with"]` assertion in `scripts/test-tool-integrity.py`.

Reviewed commit: a096b3eb6e20

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

Explain the read-scoped GitHub token, non-persistence, pre-guard fetch, and workflow-commit integrity binding without changing checkout inputs or tests.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Superseded — see the current review report for commit 5b145dbbba57

General PR Review: Route release jobs through the ca-trust-guard + locked-tools composite actions

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 83c8f948447e.
Review mode: incremental since a096b3e
View review run

Review Summary

New commit: 5b145db changes only docs/release-workflow.md:236-246. The "Release Job Bootstrap" paragraph now says the _workflows checkout authenticates with the job's read-scoped GITHUB_TOKEN (not persisted, content bound to job.workflow_sha), replacing the "no token input" claim.

Whole PR: Nine release.yaml jobs now start the same way:

  1. A SHA-pinned _workflows checkout at job.workflow_sha with persist-credentials: false.
  2. The local ca-trust-guard action.
  3. In 6 of those jobs, the local locked-tools action (id: tools).

The 6 Go module gates take their version, lock hash, and lock path from the locked-tools outputs, and the outputs they use (versions, lock_sha256, lock_path) exist in .github/actions/locked-tools/action.yml:35-41. The transitional wrappers under scripts/ are deleted. ci.yaml now runs on release.yaml changes, and test-tool-integrity.py asserts the step order and wiring.

Coverage: I scanned the full PR diff for security and correctness. Every guarded job declares contents: read, and notify-release-failure stays exempt with if: failure(). No repo-local criteria loaded, so only the base criteria applied. The incremental diff is not partial, and I found no coverage gaps.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

Resolved prior findings

  • prior-0 (SH10_MODE: enforce vs. PR body), prior-1 / prior-2 (dockerd certs.d adds roots and removes no trust), prior-3 (not_covered omits Linux dockerd): obsolete. No .sh10, SH10_MODE, or certs.d code is left in the tree. The ca-trust-guard step replaces it, e.g. release.yaml:132-134.
  • prior-4 (remote pins ca-trust-guard@4d06ff31 / locked-tools@562a1ea6 vs. PR body): obsolete. There are no remote self-action refs any more. All jobs use ./_workflows/.github/actions/..., and test-tool-integrity.py (test_release_workflow_has_no_remote_self_actions_or_duplicate_bootstrap) enforces it.
  • prior-5 / prior-6 (title and body describe the .sh10 probe, @99f9b2fc pins, and a guard that runs before any checkout): fixed. The PR body now describes local-path actions and the checkout → guard → locked-tools order, which matches the diff.
  • prior-7 ("no token input" doesn't mean no credential): fixed by docs/release-workflow.md:236-246, which now says the bootstrap checkout uses the job's read-scoped GITHUB_TOKEN and does not persist it.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

General PR Review: Route release jobs through the ca-trust-guard + locked-tools composite actions

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: none loaded - .claude/skills/ci-review.md was not found at trusted base 83c8f948447e.
Review mode: incremental since a096b3e
View review run

Review Summary

New commit: 5b145db changes only docs/release-workflow.md:236-246. The "Release Job Bootstrap" paragraph now says the _workflows checkout authenticates with the job's read-scoped GITHUB_TOKEN (not persisted, content bound to job.workflow_sha), replacing the "no token input" claim.

Whole PR: Nine release.yaml jobs now start the same way:

  1. A SHA-pinned _workflows checkout at job.workflow_sha with persist-credentials: false.
  2. The local ca-trust-guard action.
  3. In 6 of those jobs, the local locked-tools action (id: tools).

The 6 Go module gates take their version, lock hash, and lock path from the locked-tools outputs, and the outputs they use (versions, lock_sha256, lock_path) exist in .github/actions/locked-tools/action.yml:35-41. The transitional wrappers under scripts/ are deleted. ci.yaml now runs on release.yaml changes, and test-tool-integrity.py asserts the step order and wiring.

Coverage: I scanned the full PR diff for security and correctness. Every guarded job declares contents: read, and notify-release-failure stays exempt with if: failure(). No repo-local criteria loaded, so only the base criteria applied. The incremental diff is not partial, and I found no coverage gaps.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

Resolved prior findings

  • prior-0 (SH10_MODE: enforce vs. PR body), prior-1 / prior-2 (dockerd certs.d adds roots and removes no trust), prior-3 (not_covered omits Linux dockerd): obsolete. No .sh10, SH10_MODE, or certs.d code is left in the tree. The ca-trust-guard step replaces it, e.g. release.yaml:132-134.
  • prior-4 (remote pins ca-trust-guard@4d06ff31 / locked-tools@562a1ea6 vs. PR body): obsolete. There are no remote self-action refs any more. All jobs use ./_workflows/.github/actions/..., and test-tool-integrity.py (test_release_workflow_has_no_remote_self_actions_or_duplicate_bootstrap) enforces it.
  • prior-5 / prior-6 (title and body describe the .sh10 probe, @99f9b2fc pins, and a guard that runs before any checkout): fixed. The PR body now describes local-path actions and the checkout → guard → locked-tools order, which matches the diff.
  • prior-7 ("no token input" doesn't mean no credential): fixed by docs/release-workflow.md:236-246, which now says the bootstrap checkout uses the job's read-scoped GITHUB_TOKEN and does not persist it.

Reviewed commit: 5b145dbbba57

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found — see the full review report

@gontzess
gontzess merged commit ad85b5b into main Oct 22, 2026
7 checks passed
@gontzess
gontzess deleted the steve.gontzes/sh10-probe-report branch October 22, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant