Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
Unreleased
0.3.0 - 2026-09-02
- Detect computed-property and
Object.definePropertyrewrites of
globalThis,window, orglobalas runtime hooks using parsed JavaScript
facts, without matching inert comments or strings. - Extend
agent scanto GitHub Actions workflow files and recursively
discovered local composite Action metadata. Remote actions pinned only to
mutable tags require approval, while direct attacker-controlled context
interpolation and privileged-trigger checkout of untrusted pull request code
block. Explicitpermissions: write-allblocks; scoped write
permissions onpull_request_targetandworkflow_runrequire approval.
YAML parse failures remain operational errors. - Add a five-repository public precision gate over immutable upstream workflow
bytes; every sample must complete scanning with zero false blocks.
0.2.2 - 2026-08-30
- Add deterministic package capability correlation for npm and PyPI. Findings
now retain capability, source-line evidence, and resolved network hosts;
same-file credential-exfiltration and download-to-execution chains block
previously unknown coordinates without executing package code. Existing
standalone rule decisions are preserved, while syntax-proven file reads are
the only credential observations eligible for chain correlation.
0.2.1 - 2026-08-30
- Require an explicit GitHub token for Action release downloads and
attestation verification. Authenticate onlyapi.github.comrequests,
remove authorization on the release-asset redirect, and fail instead of
falling back to anonymous API access. - Keep the post-publish
v1promotion plan read-only while correctly treating
a missingv1ref as the empty initial-promotion state.
0.2.0 - 2026-08-30
-
Make lockfile admission artifact-bound for npm, PyPI, and crates.io by
checking downloaded bytes against lockfile-retained digests. Add exact
purl/digest/capability/reason/expiry approvals that cannot downgrade blocks,
an isolated-observation manifest with suggested CI restrictions, implicit
npmbinding.gypexecution detection, real paired npm/PyPI/crates/agent
process E2E coverage, and a lockfile-aware root Action contract. -
Reduce agent-rule false positives by limiting
override systemmatches to
agent-authority targets such as instructions, prompts, messages, and policy,
including narrowly formatted or safety-qualified authority targets. Bounded
Markdown, line-wrapped, link, and inline-HTML presentation cannot hide those
targets, while generic system UI and identifier-adjacent prose stays benign. -
Freeze the completed GH-145 single-AI review as 1,438 package-level samples:
719 packages preserving all 849 original detector findings and 719
deterministically sampled non-block predictions from the same pinned source
snapshot. The single-review tooling verifies source and detector revisions,
shard hashes, predictions, package identities, immutable reviewer evidence,
explicit reviewer/model provenance, rationales, and complete coverage.
The review contains 24blockand 1,414non-blocklabels with no unresolved
rows. CI reproduces the frozen outputs and statically rescans the pinned source
with the current Argus binary, failing on any operational error or regression
below precision 0.073171 / recall 0.625. The immutable frozen review report
remains the historical detector-baseline result. -
Agent-surface scans report bundled ELF, Mach-O, and PE/DOS executables as an
explicit approval finding instead of treating them as unreadable text or
silently skipping their uninspected binary semantics. -
Crates.io proc-macro source discovery now follows a bounded module graph of
at most 1,024 unique source files and fails closed with explicit operational
errors for oversized, binary, invalid, crate-root-escaping, or
symlink/reparse-backed reachable sources, instead of allowing an incomplete
traversal to appear clean (GH-194). -
Crates.io proc-macro module traversal now parses Rust items structurally,
preserves rustc-style module directory ownership for#[path]and inline
modules, and expands bounded localmacro_rules!calls in their invocation
context. Imported, procedural, hygienically opaque, or ambiguous expansions
remain explicit operational errors instead of guessed source; nested
cfg/cfg_attrconditions are handled conservatively, and parsing,
expansion, declaration, and resolution work is capped before unbounded work
or filesystem probes (GH-200). -
known-native-build-patternnow also recognizes addons compiled locally
from bundled sources (node-gyp,cmake-js,prebuildify,neon), not
only prebuilt platformoptionalDependencies. Ordinary node-gyp packages
previously blocked on their lonelifecycle-scriptfinding with no
downgrade path. Scripts that also fetch a remote payload — including
prebuild-install/node-pre-gyp, which reach the network on the common
path — are excluded (GH-185). -
credential-accessno longer fires on prose documentation. A README that
quotes~/.npmrcor~/.aws/credentialsis not a package reading them, and
that shape dominated the false positives the skill census measured. Agent
instruction files (CLAUDE.md,AGENTS.md,.cursorrules,.claude/**)
stay in scope, because there a credential path is a payload the user's agent
reads (GH-184). -
Add benign corpus fixtures covering the false-positive shapes the skill
census measured: documentedcurl | shinstallers, runtime HTTPS clients,
base64-decoded embedded data, and lint rules that match dynamic-execution
text. Benign coverage goes from 2 cases to 6 (GH-145). -
Add opt-in weighted risk scoring (
--risk-scoring,--risk-decides,
--risk-approval-threshold,--risk-block-threshold). Weights derive from
the severity detectors already assign, soLowandCriticalstop being
interchangeable and independent risks accumulate. Reports carry the score and
per-rule contributions in text, JSON, and SARIF. The completed GH-145
benchmark publishes per-rule support and Wilson intervals, but cannot
distinguish 15 AGT-01 block labels from 229 non-block labels by rule id and
has only one or two observations for six other ids. The severity profile
therefore remains the non-overfit default rather than inventing per-rule
probabilities from sparse policy outcomes. -
Add
argus lockfile-scan, which fetches and statically scans every
dependency a lockfile resolves and aggregates them into one decision and
exit code. Dependencies that were skipped or could not be assessed are
reported explicitly, and an unassessed dependency escalates the aggregate
decision toblockrather than contributing nothing.--baserestricts the
sweep to added/changed dependencies and now scans both artifact versions,
reporting introduced and resolved findings. An unavailable required base
artifact blocks the aggregate result rather than producing an incomplete
comparison.--malicious-dbapplies one verified local intelligence
snapshot across all current package reports. JSON and text retain version
comparisons; SARIF emits one run per current package. -
Add the approval-only
encoded-dynamic-executionrule for direct JavaScript
eval/Function(atob(...))and Python
exec/eval(base64.b64decode(...))chains. Statistical obfuscation
heuristics remain out of scope. -
Add the approval-only
obfuscated-sourcerule for structural obfuscation
signatures build tooling does not produce: systematic_0x-hex identifier
mangling and nested decoder chains. Shannon entropy, minified shape, and
maximum line length are attached as evidence on a finding that already
fired; they never raise one on their own, because legitimate bundles share
that shape. The completed labeled benchmark contains no
obfuscated-sourceobservations, so it cannot support standalone
entropy/minified thresholds; the structural signatures remain the trigger.
0.1.0 - 2026-07-23
First tagged release. Graduates the pre-launch history below into a versioned
section.
Added
-
Binary release automation and a repository-root GitHub Action contract.
v0.1.0publishes verified prebuilt binaries with checksums and Sigstore
attestations, gated by the documented administrator and release controls
(#92). -
argus agent scan— static scanner for agent supply-chain surfaces:
MCP configs, skills, hooks, andAGENTS.md/CLAUDE.md. Rules AGT-01
(injection/override language, EN+ZH), AGT-03 (remote-exec pipe,
secret-read + network-egress combos), AGT-05 (high-risk config flags:
alwaysLoad,enableAllProjectMcpServers,enabledMcpjsonServers,
PostToolUseoutput rewriting)
(#57). -
argusCLI — scan a single package and run the regression corpus
(#6,
#4,
#5). -
npm tarball fetch + safe extraction + rule scan
(#6). -
PyPI ecosystem support — sdist + wheel fetch and scan
(#23). -
crates.io ecosystem support —
.cratefetch +build.rsanalysis
(#24,
#40 extendsbuild.rsdetection
to packages that declare a custom build script inCargo.toml). -
M1 provenance — npm subject-digest cross-check against the published DSSE
attestation bundle (#15). -
M2 Sigstore signature verification behind a
sigstorefeature flag
(#29 DSSE primitive,
#35 bundle wrapper + vendored
trust root, #36 wires
argus-fetchto use it, #27
design doc, #30 Day 2 spike
findings). Resolves #14. -
Detection rules: AI-context poisoning (TrapDoor-class)
(#18) and crypto/web3
typosquat dictionary plus thecrypto-key-stealerfixture
(#17). -
Tarball-host allowlist for custom registries and CDN delegation
(#13). -
Pre-commit hook framework so
cargo fmtdrift cannot reach CI
(#28). -
Documentation: TrapDoor (2026-05-24) supply-chain attack catalog entry
(#19); M2 Sigstore design
(#27). -
Apache-2.0 LICENSE and CI / license badges
(#16).
Changed
- Updated the CI checkout action to the current major version.
- Hoisted shared
host_of/validate_artifact_url/verify_sha256_hex/
ArtifactScan/MockTransporthelpers intoargus-coreand a new
argus-test-supportdev crate; removes ~315 duplicated lines and
unblocks long-tail ecosystem work
(#26).
Fixed
- Constant-time digest comparison (
subtle::ConstantTimeEq) for tarball
integrity (#11). - Reject HTTPS → HTTP downgrade during redirect follow
(#12,
#39 hardens the check to
happen before the follow rather than after). - Reject unsafe artifact filenames from PyPI metadata (path-traversal guard)
(#38). - Treat malformed attestation payloads as a hard failure rather than a
silent skip (#41). - Preserve high-severity Sigstore decisions even when info-level findings
are present (#37). - Keep Sigstore info findings non-blocking when the higher layers succeeded.
Security
- Sigstore signature verification provides cryptographic evidence about
who signed a package, but does NOT prove publisher intent. Honest
threat-disclosure of attack classes M2 does not close (OIDC compromise,
builder-workflow tampering, trust-root rotation) lives in
docs/design/sigstore-verification.md
§10. - See
docs/supply-chain-attacks.mdfor the
attack-catalog argus is designed against.