Skip to content

feat(ci): audit every dependency tree for known vulnerabilities - #1593

Merged
HuiJun merged 11 commits into
developfrom
feature/sca-gates
Oct 28, 2026
Merged

HuiJun merged 11 commits into
developfrom
feature/sca-gates

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Nothing in CI scanned dependencies, so develop carried 12 reachable Go vulnerabilities, 4 npm advisories, 6 RustSec advisories and 11 OSV findings against the Java client, and v0.11.0 shipped them. This adds a failing dependency audit to every ecosystem's job, a weekly Dependabot schedule, and a pre-branch and pre-tag audit step to the release procedure. #1589 (merged) moved the vulnerable Go, npm and cargo pins; this PR only adds the gates.

  • Audits, one per ecosystem, in the existing jobs. Makefile gains vulncheck (govulncheck v1.9.0 via go run, both Go modules, fails on reachable vulnerabilities), audit-npm (npm audit --omit=dev --audit-level=moderate in all six package-lock.json directories; NPM_LOCK_DIRS= narrows), audit-python (pip-audit --strict over client/python, client/jupyter-kernel, packaging/pypi-pysysml), audit-rust (cargo audit over client/rust/Cargo.lock), audit-java (a CycloneDX SBOM of each Maven tree — client/java, editors/syson, editors/mdk — scanned by osv-scanner, test scope excluded; JAVA_PROJECT_DIRS= narrows), and audit for all five. audit-python also audits docs-requirements.txt. scripts/download-sca-tools.sh provisions cargo-audit 0.22.2, osv-scanner 2.7.0 and pip-audit 2.10.1 under build/sca/, pinned and SHA-256 verified like the other downloads (Linux/macOS, x86_64/arm64).
  • Pull-request workflow. make vulncheck in Go static and integrity checks (runs in the quick tier too, so a draft shows it); make audit-npm in Node client tests (client/node), VS Code extension, JupyterLab extension, SysON plugin (its frontend) and the Go static job (packaging/npm/sysml-mcp, scripts/asciidoc, where Node is already set up for the npm runner); make audit-python in Python client tests; make audit-rust in Rust client tests; make audit-java in Java client tests (client/java), SysON plugin (editors/syson) and OpenSysML MDK for Cameo plugin (editors/mdk). Each step is gated by the Changed areas output its job already uses.
  • CircleCI. The same steps in go-static, python-test, rust-test, java-test and node-test, which run on develop, main and every v* tag, so the release pipeline audits before it publishes (the editors are not released by it; syson-test and mdk-test audit their trees on develop/main). node-test audits all six lockfiles because editors-node-test does not run on tags.
  • Nightly. A new audit job in nightly.yml checks out develop and runs the five audits unconditionally (each step runs even after an earlier failure), so an advisory published against an unchanged develop fails the next night's run, and publish needs it, so a night whose audit fails publishes no snapshot. It installs the Java client locally first, since the editors depend on it at the tree's version.
  • Java decision. OWASP dependency-check needs an NVD API key to update its database in reasonable time and OSS Index now answers anonymous requests with 401, so neither fits the ~5 minute budget without a secret. osv-scanner scans a CycloneDX SBOM (cyclonedx-maven-plugin:2.9.1:makeAggregateBom, 4–15 s per tree with a warm cache) against OSV with no credential, so Java is audited in the Java, SysON and MDK jobs and nightly, not nightly only. The SBOM rather than osv-scanner's own pom.xml resolver because the latter cannot follow reactor modules (editors/mdk/plugin → opensysml-mdk-openapi-stubs: "not found", exit 127 even with no finding) and scans every manifest under a directory, dev dependencies included.
  • npm level. moderate: with fix(deps): remove every known-vulnerable dependency (Go 1.27.3, x/net, x/text, grpc, npm, cargo) #1589 merged every lockfile is clean at moderate, with and without development dependencies (editors/jupyterlab's 9 moderate findings on develop are gone), so the stricter level costs nothing. low is not used because npm reports it for advisories without a fix.
  • Dependabot. .github/dependabot.yml: gomod (/, /tools), npm (the six lockfile directories), pip (the three packages), cargo, maven (client/java, editors/syson, editors/mdk), github-actions; weekly on Monday, target develop, one group per ecosystem for minor+patch, chore(deps): … titles. Labels are Dependabot's defaults (dependencies plus the ecosystem), which it creates itself. Its PRs open ready for review, so the full tier runs with Changed areas scoping it to the lockfile touched; In scripts/ci-changed-areas.sh, .github/dependabot.yml and packaging/npm/ are now service paths (the npm runner's lockfile is audited in the Go static job) and packaging/pypi-pysysml/ turns the Python area on, so a pull request touching only one of those manifests still runs its audit; cases added to scripts/ci-changed-areas-test.sh.
  • Docs. CONTRIBUTING § CI/CD describes the audits and a new § Dependabot pull requests describes the flow (still draft/ready → green → maintainer merge); docs/project/releasing.md requires make sca-tools audit clean before cutting release/x.y.z and again before the tag, with every unfixable finding checked against the CISA Known Exploited Vulnerabilities catalogue and the decision recorded in the release PR; docs/project/nightly.md documents the nightly job. Changelog fragment changes/unreleased/dependency-audits.added.md.

How it was verified

Each gate fails on a vulnerable tree (develop 82cd1c2 in a scratch worktree, or a pin injected into it):

make vulncheck            → "Your code is affected by 12 vulnerabilities from 3 modules." exit status 3 → make: Error 1 (exit 2)
make audit-npm NPM_LOCK_DIRS=client/node → "3 vulnerabilities (1 moderate, 2 high)" → make: Error 1 (exit 2)
make audit-python PYTHON_PROJECT_DIRS=client/python with "urllib3==1.26.0" added to its dependencies → "Found 22 known vulnerabilities in 1 package" (exit 2)
make audit-rust           → "error: 6 vulnerabilities found!" (exit 2)
make audit-java           → client/java: 6 known vulnerabilities in 4 packages (grpc-netty-shaded 1.70.0, bcprov 1.80.2, bcpkix 1.80, guava 33.3.1-android), exit 2
make audit-java JAVA_PROJECT_DIRS=editors/mdk → 6 (guava 32.0.1-jre, grpc-netty-shaded, bouncycastle), exit 2
osv-scanner on an aggregator pom alone → exit 128 (no packages); on a reactor module it cannot resolve → exit 127: both fail the step too

On this branch (develop with #1589 and #1587 merged in, plus this change):

make vulncheck    → "No vulnerabilities found." for both modules, exit 0
make audit-npm    → "found 0 vulnerabilities" in all six directories at moderate (also 0 with dev dependencies), exit 0
make audit-python → "No known vulnerabilities found" ×4 (three packages + docs-requirements.txt), exit 0
make audit-rust   → "Scanning client/rust/Cargo.lock for vulnerabilities (80 crate dependencies)", exit 0
make audit-java   → still red: client/java 6, editors/syson 14, editors/mdk 6 OSV findings, exit 2 (see below)

Config and tree gates: circleci config validate .circleci/config.yml valid; actionlint on pr.yml and nightly.yml (the two pre-existing shellcheck notes only); .github/dependabot.yml valid against schemastore's dependabot-2.0.json (jsonschema); bash scripts/ci-changed-areas-test.sh all cases pass; go test ./tests/hygiene ok (nightly, node-install, release-config suites parse the changed configs); go build ./..., go vet ./..., gofmt -l . empty; python3 scripts/changelog.py check; python3 scripts/check-doc-links.py 0 broken. scripts/download-sca-tools.sh provisions all three tools in 8 s and is idempotent.

Maintainer follow-ups

  • Java is red until its pins move, which fix(deps): remove every known-vulnerable dependency (Go 1.27.3, x/net, x/text, grpc, npm, cargo) #1589 did not cover. client/java: io.grpc:grpc-netty-shaded 1.70.0 → ≥1.75.0, org.bouncycastle:bcprov-jdk18on 1.80.2 → ≥1.85 and bcpkix-jdk18on 1.80 → ≥1.84 (transitive via sigstore-java), com.google.guava:guava 33.3.1-android → ≥33.7.2. editors/syson adds tools.jackson.core:jackson-core/jackson-databind 3.1.4 → ≥3.1.7 and guava 33.5.0-android. editors/mdk adds guava 32.0.1-jre. The Java, SysON and MDK jobs on this PR fail on them by design.
  • client/julia/OpenSysML/Project.toml has no audit tool or Dependabot ecosystem; it is the one manifest left unscanned.
  • Dependabot alerts and security updates are repository settings (Settings → Advanced Security), off by the organisation default; the configuration file only schedules version updates. Switch them on for Dependabot to open out-of-cycle security PRs.

Checklist

  • make test and make lint pass locally (no Go code changed: go build, go vet, gofmt -l, the hygiene suite and the changed-areas tests run; the full suite runs before un-drafting)
  • Tests added or updated for the change (scripts/ci-changed-areas-test.sh case)
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (none moved)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/8f1dd5882ec9462c9f3e7e7ab5183df3
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/8f1dd5882ec9462c9f3e7e7ab5183df3?variant=devin
Requested by: @HuiJun

devin-ai-integration Bot and others added 2 commits October 27, 2026 16:44
govulncheck over both Go modules, npm audit over every lockfile, pip-audit
over the Python packages, cargo audit over the Rust client and osv-scanner
over the Java client each fail their ecosystem's job in the pull-request
workflow (both tiers, gated by Changed areas like the job), in the CircleCI
jobs that gate develop, main and release tags, and nightly over develop.
The tools are pinned and SHA-256 verified by scripts/download-sca-tools.sh;
make audit runs all five. Dependabot opens weekly grouped updates against
develop, and the release procedure requires a clean audit before the
release branch and before the tag, with a CISA KEV check for findings that
cannot be fixed.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration Bot and others added 3 commits October 27, 2026 17:23
…pins

make audit-java now scans a CycloneDX SBOM of each Maven tree (client/java,
editors/syson, editors/mdk) with osv-scanner, since osv-scanner's own pom
resolver cannot follow reactor modules; the SysON and MDK jobs and the
nightly audit run it, and Dependabot watches the two editor trees.
make audit-python also audits docs-requirements.txt.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Every lockfile is clean at moderate once the vulnerable pins moved, so the
stricter level costs nothing.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 4 commits October 27, 2026 17:33
…ly packaging changes

The nightly publish job needs the audit job, so a night whose audit fails
ships nothing. packaging/npm/ is a service path and packaging/pypi-pysysml/
turns the Python area on, so a pull request changing only one of those
manifests still runs its audit.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	Makefile
@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 27, 2026 21:03
Base automatically changed from fix/dependency-vulnerabilities to develop October 27, 2026 22:18
Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	CONTRIBUTING.md
@HuiJun
HuiJun merged commit 12d5695 into develop Oct 28, 2026
30 checks passed
@HuiJun
HuiJun deleted the feature/sca-gates branch October 28, 2026 17:06
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