Skip to content

CI: add eMudhra/emSign CA stopgap for GitHub-hosted Windows runners - #3270

Merged
rwgk merged 3 commits into
NVIDIA:mainfrom
juenglin:ci/emudhra-stopgap-windows
Oct 29, 2026
Merged

rwgk merged 3 commits into
NVIDIA:mainfrom
juenglin:ci/emudhra-stopgap-windows

Conversation

@juenglin

@juenglin juenglin commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

The runner trust probe (#3268, run) shows that the GitHub-hosted Windows images (windows-2022, windows-latest, windows-11-arm) still trust the compromised eMudhra intermediates (CVE-2026-111943), so schannel-based clients (git, gh, PowerShell/.NET) accept certificates issued with the compromised keys. Microsoft blocks these certificates through Windows' automatic trust-list updates, but the hosted images do not have that update.

This change adds a composite action (.github/actions/upgrade-ca-certificates) that applies the OS-appropriate fix as the first step of each affected job, before actions/checkout sends any token over HTTPS:

  • Windows (GitHub-hosted): adds the eight compromised intermediates and their eight Sectigo cross-signs to Cert:\LocalMachine\Disallowed, then fails the job unless Windows chain building reports every one of them as explicitly distrusted. This matches the disclosure's own Windows workaround. Distrusting only emSign ECC Root CA - G3 is not enough, because the cross-signs chain to AAA Certificate Services, which Windows trusts (thanks @rwgk).
  • Linux (GitHub-hosted): upgrades ca-certificates via apt-get, which removes emSign ECC Root CA - G3 from /etc/ssl/certs/ca-certificates.crt. Ubuntu's bundle does not contain AAA Certificate Services, so the cross-signs are not trusted there; verified offline against the old and fixed ca-certificates packages for 24.04. Wiring this into the remaining Linux jobs is a follow-up (security/emudhra-plan2.md).

The action is a no-op on self-hosted runners (runner.environment != 'github-hosted'), whose trust stores are managed by the runner team separately.

The 16 certificates come from the disclosure's impacted-intermediates.json, committed unmodified (SHA-256 f67b3abe9b4879f4e91874ed041beccd71257f1db41c588c724ccf12aa90c59e, excluded from end-of-file-fixer to keep it byte-identical), so nothing is downloaded at run time. Every certificate's fingerprint and key hash was recomputed locally, and crt.sh lists exactly these two certificates for each of the eight keys. The set is closed: new certificates for these keys would have to be issued by another CA, and all existing ones are revoked.

Probe changes

The probe now tests the same thing the fix does, so a green probe means the cross-sign path is closed too:

  • Windows: gates on all 16 certificates being explicitly distrusted (shared helper with the action). Root presence in LocalMachine\Root is now informational, because Microsoft's fix leaves the root in place.
  • Linux: verifies the disclosure's 14 served chains (ci/tools/runner_trust_probe_chains/, from its chains.zip) offline against the CA bundle with openssl verify. Only an issuer-lookup error counts as rejected; any other error fails the check.
  • Both: the live endpoint check now covers one host per path (via emSign ECC Root CA - G3 and via the AAA Certificate Services cross-sign).

What the fix does and does not cover

  • Fixed: git (schannel backend, which GitHub-hosted Windows runners use by default), gh, Invoke-WebRequest, .NET HttpClient, curl with WinSSL.
  • Not fixed: the Node.js store compiled into the runner agent (JS actions: actions/checkout's own API calls, artifact actions, etc.). For GitHub-hosted runners this requires GitHub to roll out agent v2.338.2 or later to their hosted fleet; for self-hosted runners it is tracked separately.

Jobs wired

  • build-wheel.yml: win-64 (windows-2022) and win-arm64 (windows-11-arm) builds.
  • pre-commit.yml: Linux (ubuntu-latest) and Windows (windows-latest) rows.
  • test-sdist-windows.yml: windows-2022.
  • coverage.yml (build-wheel-windows): standalone inline job on windows-2022, not a call to the reusable build-wheel.yml.

Removal

Remove the Windows step from this action (or the entire action if the Linux wiring is also done and removed) once the probe's "Compromised intermediates distrusted" check passes on all three hosted Windows images across at least 14 consecutive daily runs. Link the probe run evidence in the removal PR. Tracked by #3257.

Checklist

  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@juenglin juenglin added this to the cuda.bindings next milestone Oct 28, 2026
@juenglin juenglin added the CI/CD CI/CD infrastructure label Oct 28, 2026
@copy-pr-bot

copy-pr-bot Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@juenglin juenglin self-assigned this Oct 28, 2026
@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 43e36ad

@juenglin
juenglin requested review from jpascucci-nv and rwgk October 28, 2026 22:20
@juenglin
juenglin marked this pull request as ready for review October 28, 2026 22:27
@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor
Doc Preview CI
Preview removed because the pull request was closed or merged.

Three review fixes:
- Wire upgrade-ca-certificates into coverage.yml's build-wheel-windows job,
  which is a standalone inline job (not a call to build-wheel.yml) running
  on windows-2022 with actions/checkout.
- Linux path: fail closed when openssl is absent or the CA bundle cannot be
  parsed (cert_count == 0), mirroring the probe script's guard.
- Windows path: use -ErrorAction Stop when reading LocalMachine\Root (an
  unreadable store is not a clean state) and keep SilentlyContinue only for
  Disallowed; replace the manual SHA256::Create()/BitConverter block with
  GetCertHashString('SHA256'), which is available in PS7 (shell: pwsh).
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

📝 Summary

Summary by CodeRabbit

  • Chores
    • Updated automated build and validation checks to address specified certificate trust issues on hosted Windows and Linux runners.
    • Expanded trust checks across certificate-chain variants and added verification of expected trust-store behavior.
    • Adjusted workflow linting and file-processing rules to accommodate the new certificate data.
  • Documentation
    • Added guidance for reviewing captured certificate chains and interpreting trust-check results.

The pull request adds a composite action that checks and updates certificate trust on hosted Windows and Linux runners. It adds impacted intermediate-certificate data and expands Windows and Linux runner probes. Four workflows invoke the action.

Changes: Hosted runner certificate trust

Layer / File(s) Summary
Impacted certificate data and validation
.github/actions/upgrade-ca-certificates/impacted-intermediates.json, .github/actions/upgrade-ca-certificates/emudhra_intermediates.ps1, .pre-commit-config.yaml
Adds 16 impacted intermediate-certificate records. PowerShell functions parse the records, check their SHA-256 hashes, and test for explicit distrust. The pre-commit exclusion includes the JSON file.
Platform-specific certificate trust checks
.github/actions/upgrade-ca-certificates/action.yml
On hosted Windows, the action adds the impacted certificates to LocalMachine\Disallowed and verifies explicit distrust. On hosted Linux, it checks the CA bundle for the emSign root fingerprint and, when present, retries the ca-certificates upgrade up to three times before verifying the bundle.
Runner trust probes and chain fixtures
ci/tools/runner_trust_probe.ps1, ci/tools/runner_trust_probe.sh, ci/tools/runner_trust_probe_chains/README.txt, .spdx-ignore
The probes test impacted-certificate distrust and both endpoint paths. The shell probe also checks offline chains at a fixed verification time. The README describes the captured chains and OpenSSL checks; .spdx-ignore excludes the chain data.
Workflow invocation and lint configuration
.github/workflows/build-wheel.yml, .github/workflows/pre-commit.yml, .github/workflows/test-sdist-windows.yml, .github/workflows/coverage.yml, .github/actionlint.yaml
Four workflows run the local action. Actionlint ignores missing-reference diagnostics for these action references.

Possibly related PRs

Priority: High

Change: Bug fix

Merge Risk: Low · up to 46a5b

All documented chains are currently present, but the probe could pass with an incomplete set. This can be addressed as a follow-up.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between d649075 and 43e36ad.

Files selected for processing: 5
  • .github/actionlint.yaml
  • .github/actions/upgrade-ca-certificates/action.yml
  • .github/workflows/build-wheel.yml
  • .github/workflows/pre-commit.yml
  • .github/workflows/test-sdist-windows.yml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 1b4da6d

Blocking only emSign ECC Root CA - G3 on Windows leaves the eight
compromised intermediates trusted through their Sectigo cross-signs, which
chain to AAA Certificate Services. The Windows step now adds all 16
certificates from the disclosure's impacted-intermediates.json (vendored
unmodified) to LocalMachine\Disallowed and verifies that chain building
reports each one as explicitly distrusted.

The probe now gates on the same explicit-distrust check on Windows (the
root stays in LocalMachine\Root under Microsoft's own fix, so root presence
is informational), verifies the disclosure's 14 served chains offline
against the CA bundle on Linux, and tests one live host per path.
@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 46a5bfc

@coderabbitai coderabbitai 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.

Nitpick comments: 1
ci/tools/runner_trust_probe.sh: 1

106-106: Trivial · Functional Correctness · Quick win

suggestion: Check the complete offline fixture set.

If one documented PEM file is omitted, the non-empty glob still passes the empty-directory check. The loop then verifies only the remaining files and can report PASS. Compare the discovered filenames with the documented fixture set before reporting success.


Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 1b4da6d and 46a5bfc.

Files ignored due to path filters: 14
  • ci/tools/runner_trust_probe_chains/dv-g3b-aaa-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/dv-g3b-aaa-noct-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/dv-g3b-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/dv-g3b-noct-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/dv-g3c-aaa-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/dv-g3c-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ev-g3b-aaa-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ev-g3b-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ev-g3c-aaa-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ev-g3c-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ov-g3b-aaa-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ov-g3b-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ov-g3c-aaa-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
  • ci/tools/runner_trust_probe_chains/ov-g3c-emudhra.we-have-a-problem.com.pem is excluded by !**/*.pem
Files selected for processing: 8
  • .github/actions/upgrade-ca-certificates/action.yml
  • .github/actions/upgrade-ca-certificates/emudhra_intermediates.ps1
  • .github/actions/upgrade-ca-certificates/impacted-intermediates.json
  • .pre-commit-config.yaml
  • .spdx-ignore
  • ci/tools/runner_trust_probe.ps1
  • ci/tools/runner_trust_probe.sh
  • ci/tools/runner_trust_probe_chains/README.txt

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

@rwgk rwgk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

codex GPT-6.1-Sol ultra:

No new findings at 46a5bfc.

My original P1 is resolved. The revised action imports all 16 intermediates and cross-signs from vendored data, then verifies explicit distrust. The offline approach also avoids runtime downloads.

Validation confirms:

  • The distrust check passes on windows-latest, windows-2022, and Windows ARM.
  • Linux probe checks correctly distinguish vulnerable, fixed, and malformed inputs.
  • Both pre-commit jobs pass; broader CI is still running without observed failures.

@rwgk
rwgk merged commit 1869326 into NVIDIA:main Oct 29, 2026
116 checks passed
github-actions Bot pushed a commit that referenced this pull request Oct 29, 2026
Removed preview folders for the following PRs:
- PR #3103
- PR #3170
- PR #3224
- PR #3241
- PR #3250
- PR #3263
- PR #3264
- PR #3270
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD CI/CD infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants