Skip to content

v0.7.0

Choose a tag to compare

@DragonStuff DragonStuff released this 13 May 00:58
· 9 commits to main since this release

New: cas cooldown

Fails when any installed (name, version) was published more recently than --min-age days (default 14). Defends against rapid-install supply-chain attacks where a malicious version is live for hours before any scanner sees it. Inspired by StepSecurity's npm-package-cooldown-check, kevinslin/safe-npm, and pnpm's minimumReleaseAge setting.

Three deployment scenarios supported:

Setup Recommended flags
Public npm only default --registry registry.npmjs.org
CodeArtifact + npm --ca-domain + --ca-repository (falls back to CA on 404)
CodeArtifact-only private --ca-first + --ca-domain + --ca-repository

Performance: parallel fetch via ThreadPoolExecutor (--max-workers 20 default). On a 2521-package lockfile: ~16s first run, ~0.5s cached. Down from 2–5 minutes serial.

Disk cache (--cache PATH): publish times are immutable so cached entries are always valid. Aggressively populated from every fetched metadata response. Corrupt cache silently falls back to fresh fetch.

Per-version endpoint fallthrough: when an endpoint returns metadata but the specific version isn't in time[], cas falls through to the next endpoint. Closes the false-positive class observed against real lockfiles where the public npm registry returns a placeholder for org scopes without serving the private versions.

Secure-by-default (breaking)

A (name, version) that no configured endpoint can resolve is now HIGH cooldown_private_unresolvable (was silent INFO in earlier prototypes). Catches typo'd deps, lockfile tampering, and configuration gaps. Opt-out: --allow-private <name>.

Matching change for cas audit --probe-private: packages OSV doesn't know AND public npm doesn't know are now HIGH unaudited_private (was INFO). Opt-out: --allow-private <name>.

Aliased package names

Lockfile entries like node_modules/string-width-cjs with name: "string-width" are now queried against the canonical name. Shared extract_package_name(key, entry) helper applies the same fix across cas cooldown, cas audit, and cas scripts.

195 tests pass (was 164). Lint + mypy strict clean.