Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 80 additions & 6 deletions .github/workflows/security-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
#
# 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.
# Pinned by commit SHA to the security-workflows v0.5.0 release.
# The vulnerability and malware scans cross a Charon tunnel; see ci/README.md.

name: Security Suite (Pulse + CodeQL)
name: Security Suite (Secret, Vulnerability, Malware, SAST)

on:
push:
Expand All @@ -29,16 +31,72 @@ permissions:
actions: read

jobs:
# 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.ref == 'refs/heads/main' &&
(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"]'

# 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Major · Stability & Availability · Quick win

important: Resolve dependencies against the built wheels.

pip download does not search wheelhouse for dependencies without --find-links. On a prerelease build, cuda-python requires the matching cuda-bindings version. If that version is not published, wheel collection fails despite having built it. Add --find-links wheelhouse so resolution can use the local wheels. (raw.githubusercontent.com)

As per path instructions, review “status and check behavior” for GitHub workflows.

Source: Path instructions

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: 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@c736f0454dc99764a66af6b906adfcdfbf621985 # v0.4.0
!cancelled() &&
(needs.python-wheels.result == 'success' || github.ref != 'refs/heads/main') &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Major · Stability & Availability · Heavy lift

important: Keep independent scans running when wheel preparation fails.

On main, a failed python-wheels job makes this condition false. The entire reusable suite then skips, including the secret and SAST scans that do not use the wheels. Run those scans independently of wheel preparation, and gate only the wheel-dependent vulnerability scan on its success. (raw.githubusercontent.com)

As per path instructions, review “status and check behavior” for GitHub workflows.

Source: Path instructions

(github.repository == 'NVIDIA/cuda-python' ||
vars.CI_CUSTOMIZATIONS_SECURITY_SUITE_ENABLED == 'true')
uses: NVIDIA/security-workflows/.github/workflows/security-suite.yml@0659a2e36defdf66209a135d216f40a63b7aec94 # v0.5.0
with:
enable-secret-scan: true
# The vulnerability and malware scans use a Charon tenant that authorizes only these refs.
enable-vuln-scan: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/pull-request/') }}
enable-malware-scan: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/pull-request/') }}
enable-sast-scan: true
secret-runs-on: linux-amd64-cpu4
# Set failure_policy explicitly so enforcement can't drift with upstream defaults.
Expand All @@ -48,3 +106,19 @@ jobs:
secret-failure-policy: unverified
# Same analysis the retired codeql.yml performed: python, build-mode none, security-extended.
sast-languages: '["python"]'
# NSPECT_ID must be an Actions *variable*: a reusable workflow's inputs cannot read secrets.
# Empty fails the suite preflight rather than reporting to the wrong nSpect program.
nspect-id: ${{ vars.NSPECT_ID }}
vuln-runs-on: linux-amd64-cpu4
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
malware-runs-on: linux-amd64-cpu4
# strict (default) — SUSPICIOUS fails too; malicious-only — it only warns. MALICIOUS always fails.
malware-failure-policy: strict
6 changes: 4 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ci:
autoupdate_branch: ''
autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate'
autoupdate_schedule: quarterly
skip: [lychee, check-precommit-installed, secret-scan-trufflehog]
skip: [lychee, check-precommit-installed, secret-scan-trufflehog, guardwords-scan-code-scanning]
submodules: false

# Please update the rev: SHAs below with this command:
Expand All @@ -18,10 +18,12 @@ repos:
# Runs first so a leaked credential blocks the commit before any formatter runs.
# Self-installing: the hook downloads a pinned, checksum-verified trufflehog on
# first use (no manual install). Skipped on pre-commit.ci; Pulse CI enforces server-side.
# GuardWords needs NVIDIA's internal client and network; it skips with a notice elsewhere.
- repo: https://github.com/NVIDIA/security-workflows
rev: c736f0454dc99764a66af6b906adfcdfbf621985 # frozen: v0.4.0
rev: 0659a2e36defdf66209a135d216f40a63b7aec94 # frozen: v0.5.0
hooks:
- id: secret-scan-trufflehog
- id: guardwords-scan-code-scanning

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: f368fb366ff7f2f808dd324b83a6d32267799e19 # frozen: v0.17.2
Expand Down
15 changes: 15 additions & 0 deletions ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Loading