Skip to content

feat: multi-language supply-chain coverage for the audit rig#10

Open
jp-cruz wants to merge 2 commits into
mainfrom
feat/multi-language-supply-chain
Open

feat: multi-language supply-chain coverage for the audit rig#10
jp-cruz wants to merge 2 commits into
mainfrom
feat/multi-language-supply-chain

Conversation

@jp-cruz

@jp-cruz jp-cruz commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What

Extends the dev-rig audit harness beyond Python to cover Python, JS/TS, and Rust dependency scanning plus shell and risky-exec pattern analysis — motivated by the recent wave of npm/PyPI supply-chain attacks (compromised-maintainer version pushes, typosquats, malicious install hooks).

Changes

  • semgrep/legionforge-risky-exec.yml (new) — 7 custom Semgrep rules targeting patterns ecosystem scanners miss: curl|bash installers, PowerShell download-cradles, decode-and-exec / -enc, eval "$(curl)", TLS-verification bypass, VCS-URL installs, npm install-scripts re-enabled. Validated 8/8 on fixtures, 0 false positives on clean input.
  • .github/workflows/supply-chain.yml (new) — reusable CI: osv-scanner (pinned container, multi-ecosystem deps + malicious-package feed), risky-exec (custom ruleset), and an optional socket job that self-skips unless SOCKET_SECURITY_API_KEY is provided.
  • scripts/audit.sh + audit.ps1 — osv-scanner / shellcheck / risky-exec sections; each self-skips when its language or tool isn't present; summary reflects actual run order.
  • .pre-commit-config.yaml — shellcheck hook + lockfile-triggered osv-scanner local hook.
  • README.md — inventory, CI wiring example, multi-language note, tool-versions table.

Coverage

Python JS/TS Rust Shell PowerShell
Deps + malicious-pkg pip-audit + osv osv osv
Risky patterns bandit/semgrep semgrep shellcheck + risky-exec risky-exec

Validation

  • osv-scanner + shellcheck installed from homebrew-core; both run as the harness invokes them
  • Custom ruleset, all YAML, and bash -n validated; audit.sh is shellcheck-clean
  • audit.ps1 parse + Docker-semgrep legs to be confirmed on an interactive host (CI keychain blocks Docker pulls in the sandbox)

Next pass

cargo-deny (Rust license/ban/advisory policy) and PSScriptAnalyzer (PowerShell SAST).

🤖 Generated with Claude Code

Adds osv-scanner (multi-ecosystem dependency vuln + malicious-package
scan covering Python/npm/Cargo), shellcheck, and a custom Semgrep
ruleset for risky-exec / supply-chain patterns (curl|bash installers,
PowerShell download-cradles, decode-and-exec, TLS-verification bypass,
VCS-URL installs, npm install-scripts re-enabled).

- semgrep/legionforge-risky-exec.yml: 7 custom rules (validated 8/8 on
  fixtures, 0 false positives on clean input)
- .github/workflows/supply-chain.yml: reusable CI (osv-scanner +
  risky-exec + optional token-gated Socket.dev job)
- scripts/audit.sh + audit.ps1: osv-scanner/shellcheck/risky-exec
  sections, each self-skipping when language/tool absent
- .pre-commit-config.yaml: shellcheck + lockfile-triggered osv-scanner
- README: inventory, CI wiring, multi-language note, tool versions

cargo-deny (Rust policy) and PSScriptAnalyzer (PowerShell SAST) are the
documented next pass.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
…11)

* chore: validate + harden the rig (self-CI, fixture fix, rule tuning)

Validation pass over the multi-language rig. Adds end-to-end self-testing
and fixes three real issues that validation surfaced.

Self-test CI:
- .github/workflows/ci.yml: on push/PR, invokes all 7 reusable workflows
  (lint/test/sast/audit/supply-chain/secrets/sbom) against the rig itself
  via LOCAL refs, so a PR validates its own workflow versions. The
  reusable workflows had never been exercised end-to-end before this.

Bug fixes found by validation:
- fixtures/http.py: mock_http_client passed the respx MockRouter as an
  httpx transport, which is not a valid transport (AttributeError:
  handle_async_request) on httpx 0.28 / respx 0.23 — the fixture was
  broken for any consumer. Now returns a plain AsyncClient intercepted by
  the active respx.mock(). Also drops an unused import (F401).
- tests/: add the rig's first real test suite for the shipped fixtures
  (100% coverage of the fixtures module), which doubles as test.yml's
  self-test target.

Rule tuning:
- risky-exec: exclude full-line #-comments via pattern-not-regex so
  documented "curl … | bash" usage notes don't false-positive (the
  generic_comment_style option does not apply to pattern-regex). Add
  --exclude semgrep so the ruleset file doesn't self-match its own
  patterns; add --exclude .claude so worktree copies aren't double-scanned.
- pyproject: per-file-ignore S101 (assert) for tests/ and examples/.

Validated locally: ruff/mypy/bandit clean, pytest 6/6 (100% cov),
risky-exec regression 10/10 on fixtures with 0 comment false positives,
rig self-scan clean, all YAML parses, audit.sh shellcheck-clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* ci: run self-test on all PRs, not just those targeting main

Stacked PRs (and this one) target a feature branch, so the
branches:[main] filter would skip self-CI entirely.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(ci): add [dev] extra so lint.yml/test.yml install lint tooling

lint.yml runs 'pip install -e .[dev]' but the rig defined its tools only
under the [analysis] extra — so ruff/bandit/mypy were never installed and
self-CI lint failed with 'No module named ruff'. The rig now provides the
[dev] extra its own reusable workflows expect.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

---------

Co-authored-by: jp-cruz <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
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