From 59e7442a634cad4a4367c475fc326f99dd7ffc0f Mon Sep 17 00:00:00 2001 From: gmanal Date: Tue, 27 Oct 2026 13:06:29 +0530 Subject: [PATCH 1/8] ci: enable the Pulse vulnerability and malware scans in the Security Suite Turns on `enable-vuln-scan` and `enable-malware-scan` and repins the suite to NVIDIA/security-workflows test/vuln-malware-onboarding, the branch carrying the 0.5.0 release notes for both scans. The vulnerability scan starts report-only so a finding baseline can be built before it gates merges; scanner and transport errors still fail the job, and inventory writeback stays off. The malware scan keeps the upstream default of strict, where SUSPICIOUS blocks as well as MALICIOUS. Both scans report to the same nSpect registration, because an nSpect ID identifies the repository rather than one scan. `nspect-id` reads the `NSPECT_ID` Actions variable and carries no literal fallback, so another repository opting in through CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED cannot report against this one's registration. It must be a variable rather than a secret: a reusable workflow's inputs cannot read the secrets context, and an absent value degrades to an unregistered rapid scan that records nothing. No permission change: the suite's union is contents/actions read plus id-token and security-events write, all of which this caller already grants. Both scans cross a Charon tunnel that authorizes per repository and per ref. charon!242 brings this repository's tenant to parity with the one the upstream workflows are tested against and grants `main` plus the `pull-request/*` mirrors; the prerequisites are summarised in ci/README.md. --- .github/workflows/security-suite.yml | 19 +++++++++++++++++-- ci/README.md | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index 64eb4846483..21ef3856788 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -2,10 +2,12 @@ # # SPDX-License-Identifier: Apache-2.0 # -# CI security scanning via the NVIDIA/security-workflows suite: Pulse secret scan + CodeQL SAST. +# CI security scanning via the NVIDIA/security-workflows suite: Pulse secret scan, +# Pulse OSS vulnerability scan (SCA), Pulse malware scan, and CodeQL SAST. # Pulse runs on Linux nv-gha-runners (Docker image + OIDC/Vault) — Linux-only by design. # The local secret-scan-trufflehog pre-commit hook is cross-platform (Linux/macOS/Windows). # Pinned to a reviewed commit SHA. +# The vulnerability and malware scans cross a Charon tunnel; see ci/README.md. name: Security Suite (Pulse + CodeQL) @@ -36,9 +38,11 @@ jobs: if: >- github.repository == 'NVIDIA/cuda-python' || vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@c736f0454dc99764a66af6b906adfcdfbf621985 # v0.4.0 + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@2194c521256bb3a7bf6fa36add89d9ce3db17c9a # test/vuln-malware-onboarding with: enable-secret-scan: true + enable-vuln-scan: true + enable-malware-scan: true enable-sast-scan: true secret-runs-on: linux-amd64-cpu4 # Set failure_policy explicitly so enforcement can't drift with upstream defaults. @@ -48,3 +52,14 @@ jobs: secret-failure-policy: unverified # Same analysis the retired codeql.yml performed: python, build-mode none, security-extended. sast-languages: '["python"]' + # Must be a repository Actions variable, not a secret — a reusable workflow's inputs cannot + # read the secrets context. Empty degrades to an unregistered rapid scan: findings are still + # reported, but nothing is recorded against the nSpect program. + nspect-id: ${{ vars.NSPECT_ID }} + vuln-runs-on: linux-amd64-cpu4 + # report-only (default) — findings warn; fail-on-vulnerability — any finding fails. Errors always fail. + vuln-failure-policy: report-only + vuln-upload-report: true + malware-runs-on: linux-amd64-cpu4 + # strict (default) — SUSPICIOUS fails too; malicious-only — it only warns. MALICIOUS always fails. + malware-failure-policy: strict diff --git a/ci/README.md b/ci/README.md index 2fcd5b4ab1d..aa635a43614 100644 --- a/ci/README.md +++ b/ci/README.md @@ -232,3 +232,18 @@ The canonical `NVIDIA/cuda-python` repository does not need this variable because its standard workflow behavior is enabled directly. Before enabling a customization elsewhere, document the repository-specific prerequisites and verification procedure in that repository's own documentation. + +### Security Suite scan prerequisites + +The secret scan and CodeQL SAST need only the Vault variables already +provisioned for this repository. The Pulse OSS vulnerability scan and the Pulse +malware scan additionally reach NVIDIA-internal services through a Charon +tunnel, which authorizes **per repository and per ref**, and both read the +repository's `NSPECT_ID` Actions variable. + +The Charon tenant must list every ref the suite scans — `main`, `ctk-next`, and +the `pull-request/*` mirrors — and grant the routes each scan calls, including +`POST /v1/sourceCode/scan`, which is not granted to tenants by default. An +unlisted ref or route surfaces as an opaque `403` from inside the scanner, so +confirm the tenant before debugging anything else. The secret scan and SAST are +unaffected; neither crosses the tunnel. From bb070866871fd147b042bdbc5a5e1716997e78ae Mon Sep 17 00:00:00 2001 From: gmanal Date: Wed, 28 Oct 2026 10:27:11 +0530 Subject: [PATCH 2/8] ci: restore a scoped nSpect ID fallback for the Security Suite Run 40634302555 resolved `vars.NSPECT_ID` to empty, so the suite preflight failed and the malware scan was skipped: the ID was provisioned as an Actions secret, and a reusable workflow's inputs cannot read the secrets context. Restore the literal fallback so the pilot can keep running, but scope it with `github.repository` this time, so a repository opting in through CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED gets an empty ID instead of reporting against cuda-python's registration. Remove it once NSPECT_ID exists under Settings -> Secrets and variables -> Actions -> Variables. --- .github/workflows/security-suite.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index 21ef3856788..f6c2d18ce81 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -52,10 +52,9 @@ jobs: secret-failure-policy: unverified # Same analysis the retired codeql.yml performed: python, build-mode none, security-extended. sast-languages: '["python"]' - # Must be a repository Actions variable, not a secret — a reusable workflow's inputs cannot - # read the secrets context. Empty degrades to an unregistered rapid scan: findings are still - # reported, but nothing is recorded against the nSpect program. - nspect-id: ${{ vars.NSPECT_ID }} + # NSPECT_ID must be an Actions *variable*: a reusable workflow's inputs cannot read secrets. + # Literal fallback until it is provisioned, scoped so no other caller inherits this registration. + nspect-id: ${{ vars.NSPECT_ID || (github.repository == 'NVIDIA/cuda-python' && 'NSPECT-ZY2K-Y1V8' || '') }} vuln-runs-on: linux-amd64-cpu4 # report-only (default) — findings warn; fail-on-vulnerability — any finding fails. Errors always fail. vuln-failure-policy: report-only From 5d8f919ba8a2a20936d5b5d7fc24b90e2c6e8580 Mon Sep 17 00:00:00 2001 From: gmanal Date: Wed, 28 Oct 2026 23:53:14 +0530 Subject: [PATCH 3/8] ci: pin the Security Suite to security-workflows main 01c3188 pins the Pulse OSS scanner to 0.5.3-charon.11, which fixes the rapid-scan UnboundLocalError on rapid_scan_url. --- .github/workflows/security-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index f6c2d18ce81..b3dd27886d5 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -38,7 +38,7 @@ jobs: if: >- github.repository == 'NVIDIA/cuda-python' || vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@2194c521256bb3a7bf6fa36add89d9ce3db17c9a # test/vuln-malware-onboarding + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@01c3188ab2fa212e8a2af0251dd9038dbae1439e # main with: enable-secret-scan: true enable-vuln-scan: true From 9a2dd683919fa83e120150372dbea493fb307a91 Mon Sep 17 00:00:00 2001 From: gmanal Date: Thu, 29 Oct 2026 00:10:23 +0530 Subject: [PATCH 4/8] ci: pin the Security Suite to security-workflows malware-vuln-onboarding --- .github/workflows/security-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index b3dd27886d5..01d39fc930a 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -38,7 +38,7 @@ jobs: if: >- github.repository == 'NVIDIA/cuda-python' || vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@01c3188ab2fa212e8a2af0251dd9038dbae1439e # main + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@fd1f966240bf29723679039892dc863ca6d3adb9 # malware-vuln-onboarding with: enable-secret-scan: true enable-vuln-scan: true From 17328486fc85ec2ffe87d0731ba440b6759aa90d Mon Sep 17 00:00:00 2001 From: gmanal Date: Fri, 30 Oct 2026 17:31:49 +0530 Subject: [PATCH 5/8] ci: scan installed wheels in the Security Suite vulnerability scan Detect cannot resolve cuda_core's CUDA-dependent build or cuda_python's dynamic setup.py from source. --- .github/workflows/security-suite.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index 01d39fc930a..5398041929d 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -31,14 +31,35 @@ permissions: actions: read jobs: + # The vulnerability scan inspects installed wheels: Detect cannot resolve cuda_core's + # CUDA-dependent build or cuda_python's dynamic setup.py from source. Python 3.12 matches + # the scanner image's interpreter. + build-wheels: + name: Build wheels for the vulnerability scan + if: >- + github.repository == 'NVIDIA/cuda-python' || + vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' + permissions: + actions: read + contents: read + secrets: inherit + uses: ./.github/workflows/build-wheel.yml + with: + host-platform: linux-64 + cuda-version: "13.4.2" + prev-cuda-version: "12.9.1" + single-cuda-major: true + python-versions: '["3.12"]' + security-suite: name: Security Suite + needs: build-wheels # Repository-specific workflow opt-ins use CI_CUSTOMIZATIONS_* Actions variables; # see ci/README.md. Enable this only after the security-suite prerequisites exist. if: >- github.repository == 'NVIDIA/cuda-python' || vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@fd1f966240bf29723679039892dc863ca6d3adb9 # malware-vuln-onboarding + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@598dce94d43e0145d22679669b637e1a5c766dc7 # test/malware-vuln-onboarding with: enable-secret-scan: true enable-vuln-scan: true @@ -56,6 +77,9 @@ jobs: # Literal fallback until it is provisioned, scoped so no other caller inherits this registration. nspect-id: ${{ vars.NSPECT_ID || (github.repository == 'NVIDIA/cuda-python' && 'NSPECT-ZY2K-Y1V8' || '') }} vuln-runs-on: linux-amd64-cpu4 + vuln-scan-path: cuda_python + vuln-python-wheels-artifact: cuda-* + vuln-python-project-name: cuda-python # report-only (default) — findings warn; fail-on-vulnerability — any finding fails. Errors always fail. vuln-failure-policy: report-only vuln-upload-report: true From a3d6ace8d0c5b321930452f2d45e6dd4fc73fa2f Mon Sep 17 00:00:00 2001 From: gmanal Date: Fri, 30 Oct 2026 17:39:26 +0530 Subject: [PATCH 6/8] ci: use the prepared-runtime vulnerability scan on main Pull-request mirrors scan source without cuda_core and cuda_python, which Detect cannot resolve from it. --- .github/workflows/security-suite.yml | 59 ++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index 5398041929d..53ba880521b 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -31,14 +31,15 @@ permissions: actions: read jobs: - # The vulnerability scan inspects installed wheels: Detect cannot resolve cuda_core's - # CUDA-dependent build or cuda_python's dynamic setup.py from source. Python 3.12 matches - # the scanner image's interpreter. + # On main the vulnerability scan inspects installed wheels: Detect cannot resolve + # cuda_core's CUDA-dependent build or cuda_python's dynamic setup.py from source. + # Wheel mode is refused on pull-request/* mirrors. Python 3.12 matches the scanner image. build-wheels: name: Build wheels for the vulnerability scan if: >- - github.repository == 'NVIDIA/cuda-python' || - vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' + github.ref == 'refs/heads/main' && + (github.repository == 'NVIDIA/cuda-python' || + vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true') permissions: actions: read contents: read @@ -51,15 +52,46 @@ jobs: single-cuda-major: true python-versions: '["3.12"]' + # The scan installs offline, so the artifact carries every runtime dependency wheel too. + python-wheels: + name: Collect runtime wheels for the vulnerability scan + needs: build-wheels + runs-on: linux-amd64-cpu8 + permissions: + contents: read + steps: + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + pattern: cuda-* + path: built + merge-multiple: true + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.12" + - name: Add runtime dependency wheels + run: | + set -euo pipefail + mkdir wheelhouse + cp built/*.whl wheelhouse/ + python -m pip download --only-binary=:all: --dest wheelhouse wheelhouse/*.whl + ls wheelhouse + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: python-wheels + path: wheelhouse/*.whl + if-no-files-found: error + security-suite: name: Security Suite - needs: build-wheels + needs: python-wheels # Repository-specific workflow opt-ins use CI_CUSTOMIZATIONS_* Actions variables; # see ci/README.md. Enable this only after the security-suite prerequisites exist. if: >- - github.repository == 'NVIDIA/cuda-python' || - vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true' - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@598dce94d43e0145d22679669b637e1a5c766dc7 # test/malware-vuln-onboarding + !cancelled() && + (needs.python-wheels.result == 'success' || github.ref != 'refs/heads/main') && + (github.repository == 'NVIDIA/cuda-python' || + vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true') + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@5a45d2625c1b120cc5e5303f523971f7ad5a0018 # test/malware-vuln-onboarding with: enable-secret-scan: true enable-vuln-scan: true @@ -77,9 +109,12 @@ jobs: # Literal fallback until it is provisioned, scoped so no other caller inherits this registration. nspect-id: ${{ vars.NSPECT_ID || (github.repository == 'NVIDIA/cuda-python' && 'NSPECT-ZY2K-Y1V8' || '') }} vuln-runs-on: linux-amd64-cpu4 - vuln-scan-path: cuda_python - vuln-python-wheels-artifact: cuda-* - vuln-python-project-name: cuda-python + vuln-python-wheels-artifact: ${{ github.ref == 'refs/heads/main' && 'python-wheels' || '' }} + vuln-python-project: ${{ github.ref == 'refs/heads/main' && 'cuda-python' || '' }} + # Pull-request mirrors scan source, minus the two packages Detect cannot resolve from it. + vuln-detect-properties: >- + ${{ github.ref == 'refs/heads/main' && '{}' || + '{"detect.excluded.directories": "cuda_core,cuda_python"}' }} # report-only (default) — findings warn; fail-on-vulnerability — any finding fails. Errors always fail. vuln-failure-policy: report-only vuln-upload-report: true From 5964011e94b445534b8e6e473825a3295b89213b Mon Sep 17 00:00:00 2001 From: gmanal Date: Fri, 30 Oct 2026 18:07:56 +0530 Subject: [PATCH 7/8] ci: pin the Security Suite to security-workflows 0c1ff79 --- .github/workflows/security-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index 53ba880521b..e117096c73a 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -91,7 +91,7 @@ jobs: (needs.python-wheels.result == 'success' || github.ref != 'refs/heads/main') && (github.repository == 'NVIDIA/cuda-python' || vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true') - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@5a45d2625c1b120cc5e5303f523971f7ad5a0018 # test/malware-vuln-onboarding + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@0c1ff79b858f7a6037cb34a8d798ced83ad323df # test/malware-vuln-onboarding with: enable-secret-scan: true enable-vuln-scan: true From 6b57543e22bc2203a5504e3b8e15a5a83ac0a369 Mon Sep 17 00:00:00 2001 From: gmanal Date: Fri, 30 Oct 2026 18:20:12 +0530 Subject: [PATCH 8/8] ci: name the security-workflows pilot branch in the Security Suite pin --- .github/workflows/security-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security-suite.yml b/.github/workflows/security-suite.yml index e117096c73a..48bd9dbce06 100644 --- a/.github/workflows/security-suite.yml +++ b/.github/workflows/security-suite.yml @@ -91,7 +91,7 @@ jobs: (needs.python-wheels.result == 'success' || github.ref != 'refs/heads/main') && (github.repository == 'NVIDIA/cuda-python' || vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true') - uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@0c1ff79b858f7a6037cb34a8d798ced83ad323df # test/malware-vuln-onboarding + uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@0c1ff79b858f7a6037cb34a8d798ced83ad323df # integration/cuda-python-pilot with: enable-secret-scan: true enable-vuln-scan: true