Changelog¶
All notable changes to this project are documented here. The format follows Keep a Changelog and the project uses Semantic Versioning.
[Unreleased]¶
[1.1.2] - 2026-10-03¶
Changed¶
- Repository renamed to
rakshit-737/tracegate-cicd-security-gate; docs moved to https://rakshit-737.github.io/tracegate-cicd-security-gate/ and the image is nowghcr.io/rakshit-737/tracegate-cicd-security-gate. Older entries below keep the old names; links to the old repository redirect, the old Pages URL does not.
[1.1.1] - 2026-10-03¶
Security¶
- Scanner findings that match no SBOM node now reach the verdict: rule
unattributed_findingblocks on HIGH/CRITICAL and warns on the rest (Python DSL and Rego, parity-checked). Before, a CRITICAL CVE on a package missing from the SBOM, or with a differently spelled version, gave PASS. Trivy rows without a PURL are matched by the ecosystem of their result type instead of defaulting to PyPI. - With
TRACEGATE_API_TOKENset, every/v1route requires the token (constant-time comparison); before,/v1/runs/{rid}/graph,backtrack,blastandcypherwere open, and unauthenticated demo calls could evict gate runs. Demo runs now have their own store; the explorer UI sends the token. - Envelopes with wrongly typed fields (non-string or non-hex
sig, objectkeyid) are rejected instead of crashing the API (500) or the CLI (exit 2 with no verdict); the CLI gate blocks with the reason. - SECURITY.md: release verification pinned to
release.yml@refs/tags/vX.Y.Z(cosign blob and image,gh attestation verify).
Changed (published numbers; several worse)¶
- Backtracking now reads every version of a package name and pins the repositories to the committed run's commits: agreement with blame 92.4% of 3,969 pairs (old readers on the same data 88.5%; v1.1.0 88.8%).
- The exact-pin pickaxe baseline is now package-specific: it ties TRACEGATE on Cargo and Go, is ahead (on agreement) on pip, and behind on npm with a clustered interval that includes 0. The v1.1.0 Cargo lead (95.0% vs 54.7%) was an artefact of a version-line token; that arm is kept and labelled
version line. - The bot-bump oracle is replaced by a commit-message oracle with five strata and checked labels: at later snapshots TRACEGATE 436/436, blame 419/436; at the labelled commit both are right on every case (TRACEGATE by construction). Two v1.1.0 labels were wrong and blame was right on both.
- Reachability: the audit found every downgraded pin loaded, and static downgrades now need recorded dependency edges, so the reduction on the benchmark repositories is 0% (was -5.7%, unaudited).
- Real images re-run in CI with Syft and Trivy on Linux: Trivy finds 511 rows (was 507); Syft's Linux image scan matches Trivy's SBOM more closely (Jaccard 0.94-1.00).
- Synthetic scale latency re-run on the CI runner.
Added¶
- Lock-file readers keep every version of a package name (yarn, pnpm, package-lock, Cargo, poetry, uv);
manifest_historydiffs (name, version) pairs;--single-versionreproduces the old readers. - Commit-message oracle with five strata (single package, multi-version, grouped, revert, re-bump), a label check with the multi-version reader, two ablations (old readers, no recency rule), exact one-sided bounds and recorded sampling rule.
- Package-specific
git log -Sbaseline; exact McNemar tests and paired clustered bootstraps; Wilson and Clopper-Pearson intervals in every results file. - Adjudication of TRACEGATE-vs-blame disagreements from the diffs (
benchmarks/adjudicate.py) and an audit of every reachability downgrade (benchmarks/reach_audit.py). scripts/render_results.pyrenders every result table in README.md and docs/ fromresults/*.json; CI checks the tables and that every run link points at a run a results file carries. Images and scale benchmarks run in CI; the benchmarks workflow runs its legs in parallel and pins the repositories to the committed run's commits (download_data.py repos --pin-from).- How it works: version diff vs line blame, with the mastodon Yarn-4 and bat ansi_term cases.
Fixed¶
- Static reachability read only the newer pip-compile
# vialayout, and downgraded pins in manifests without any dependency edges; both produced falseunreached(all 17 audited pins were loaded). Pins without recorded edges are nowunknownand never downgraded. - Binomial tails no longer underflow to p = 0; typosquat bootstrap p-values use (k+1)/(B+1) (the committed typosquat files of run 37003433022 still hold the old values; none is quoted).
rekor_evidence.py --help,opa_parity.pyfails in CI whenopais missing, CONTRIBUTING runs the demo builder once, Windows venv activation and workingserve/composecommands in the docs.
[1.1.0] - 2026-10-02¶
Supersedes v1.0.0, whose wheel and image trust the demo key implicitly (fail-open).
Added¶
- Independent backtracking oracle from single-package Dependabot/Renovate bumps (
results/lineage_bot_bump_oracle.json): TRACEGATE 231/231 at later snapshots,git blame219/231, exact-pin pickaxe 197/231; repo-clustered bootstrap intervals for all lineage figures. - The original TypoGard script and the original typomania binary run on the same typosquat splits in the benchmarks workflow (
results/typosquat_originals.json); our typomania port agrees on 99.97-100% of names. - kind admission demo adds a cosign-valid image with incomplete signed provenance, denied by the TRACEGATE gate itself.
- Sigstore CI builds use a
.post0.devN+g<sha>version; the benchmark result JSONs written by the benchmarks, kind-admission and sigstore workflows record the Actions run that produced them (data_manifest.json,images_real.jsonandscale_synthetic.jsondid not; corrected after the release). - Lock-file lineage for yarn.lock, pnpm-lock.yaml, go.mod/go.sum and Cargo.lock.
- CI: Sigstore keyless signing with Rekor checks, a kind cluster admission job, signed-pipeline e2e, wheel/sdist/Docker jobs, Python 3.10-3.14 plus Windows.
- Typosquat comparison with re-implementations of typomania/TypoGard and pypi-scan, a time split, more ecosystems and precision at realistic prevalence.
- Exact-pin pickaxe baseline and Wilson intervals in the lineage benchmark.
Security¶
- The gate fails closed when no trust root is configured (CLI exit 2, API 503); the public demo key needs
--demo/TRACEGATE_DEMO=1. - The API verifies Ed25519 envelopes (
TRACEGATE_PUBKEY), caps request bodies and envelope counts, and supports an optional bearer token. - Keyless trust: an Ed25519 key is trusted only through a verified Sigstore bundle bound to a workflow identity.
- ReDoS-free pin regexes;
materialize()refuses path-traversal tree entries; MAL range matching fails closed and uses SemVer outside PyPI.
Changed (published numbers, several worse)¶
- Backtracking evaluated on 11 repos and 4 ecosystems: 88.8% agreement with blame (was 97.5% on 3 pip repos). A new exact-pin
git log -Sbaseline reaches 100% on pip and Go, so the old 17.3% "best baseline" understated the competition; TRACEGATE leads only on Cargo and npm lock files. - Reachability reduction after the false-unreached audit: -10.3% (HEAD sources) and -5.7% (own sources), down from -15.1% / -25.8%.
- Typosquat tables now include typomania/TypoGard and pypi-scan re-implementations, five ecosystems, a time split and precision at 1% prevalence.
Fixed¶
- Release notes extraction, duplicate
latesttag, sdist missing test fixtures. - Audited false-
unreachedreachability cases (pycrypto, paramiko/ncclient/readme_renderer/alembic dependencies, Django ImageField -> Pillow).
[1.0.0] - 2026-09-26¶
Added¶
- SARIF 2.1.0 adapter (
tracegate ingest --sarif) for Semgrep, Bandit, CodeQL and other SAST tools; severity fromsecurity-severityor the SARIF level. - Lock-file lineage:
tracegate lineagenow walkspackage-lock.json(v1-v3),poetry.lockanduv.lockhistory, with the npm ecosystem set on commit events. - Per-snapshot reachability in the lineage benchmark (
--materialize): each historical snapshot is analysed against its own sources and config/CI entrypoints. - Bootstrap confidence intervals (seeded, stratified, 1,000 resamples) and paired F1 differences in the typosquat benchmark.
- Docs site (MkDocs Material) on GitHub Pages with a static, server-free lineage-explorer demo.
- Release workflow: tagged builds push
ghcr.io/rakshit-737/tracegateand attach wheel/sdist.
Changed¶
- Reachability headline now reports both runs: -15.1% actionable with HEAD sources, -25.8% with per-snapshot sources. Typosquat point estimates re-ran unchanged; CIs added.
[0.2.0] - 2026-09-26¶
Real-data release: TRACEGATE now ingests unmodified output from real Syft/Trivy runs, walks real git history, and is benchmarked on public datasets instead of synthetic events.
Added¶
- Ingest adapters for raw Syft JSON, CycloneDX JSON and Trivy JSON (
tracegate ingest). - Canonical purl identities: Syft, Trivy and manifest pins for the same package converge on one graph node (qualifiers dropped, names normalised per ecosystem, memoised).
- Git lineage collector (
tracegate lineage): emits signedcommitevents from the first-parent history of a pinned manifest, following renames, with PR numbers parsed from commit subjects. - Offline OSV index over the official bulk dumps (PyPI, npm, Alpine) with ECOSYSTEM/SEMVER range matching and CVSS v3 base-score computation.
- Multi-technique typosquat detector (edit distance via deletion index, Damerau
transpositions, separator/homoglyph/suffix/combosquat/brandjack checks) and a
HeuristicWardenthat combines it with OSVMAL-*records;MultiWardenroutes by ecosystem. - Static reachability fallback: app imports (AST), dotted/bare string references,
entrypoints (Dockerfile, Procfile, CI/config), implied framework dependencies, and pip-compile
# viapropagation. Unreached findings are downgraded block -> warn with evidence. - Ed25519 DSSE signing, standard DSSE JSON envelopes and in-toto v1 / SLSA provenance
statements (
tracegate keygen,tracegate export --format intoto). - Neo4j Cypher export and an OPA/Rego port of the gate policy with a CI parity job.
- FastAPI service (
tracegate serve) with a dependency-free lineage explorer UI. - Dockerfile + docker-compose demo stack (API + Neo4j).
- Data and benchmark scripts: checksum-verified downloads, a daemon-free registry puller, a real Syft/Trivy scan driver, and four benchmarks (typosquat, lineage, images, scale).
- Docs: ADRs 0001-0005, CONTRIBUTING, this changelog.
Fixed¶
- OSV malicious-package lookups are now version-aware. Account-takeover advisories such as the
Sept-2025 npm
chalk/debughijack list only the trojanised releases; matching on the name alone flagged 13 clean packages in the realnode:14image. - Lineage benchmark blames the manifest path each snapshot actually had after a rename.
- Windows scans keep long
node_modulespaths (extended-length prefix), so Syft sees npm packages in image layers; layer symlinks are materialised and apk purls rebuilt.
[0.1.0] - 2026-09-20¶
Added¶
- MVP: typed stage events, content-addressed IDs, HMAC-signed envelopes with fail-closed collector, in-memory provenance DAG, Python policy DSL, backtracker and blast radius, synthetic event generator, six demo scenarios, CLI and CI workflow.