Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

Andrew Nesbitt

@andrewnez.mastodon.social.ap.brid.gy
204 followers 12 following 1.2K posts

Package Management Nerd, working on mapping the world of open source software ecosyste.ms and blogging about package managers at nesbitt.io 🌉 bridged from ⁂ mastodon.social/@andrewnez, follow @ap.brid.gy to interact

PostsRepliesMedia
Reposted by Andrew Nesbitt
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 21/10/2026
Trust Stores Are Dependencies Too nesbitt.io/2026/10/21/trust-stores-…
nesbitt.io
Trust Stores Are Dependencies Too
eMudhra generated eight of its intermediate CA certificates incorrectly, so their private keys can be recovered from the certificates themselves. Firefox (OneCRL and CRLite) and Chrome (CRLSets) blocked the intermediates on 17 October, Apple on the 19th, and Microsoft on the 20th through Windows’ automatic trust list updates. The disclosure page states that “many other clients do not consume revocation information and require software updates”, and its fix table lists the packages that carry their own copy of the roots: * certifi 2026.10.19 and pip 26.2.2 * uv 0.13.4 and pixi 0.82.1 * webpki-roots and webpki-root-certs 1.0.10, rustls-webpki 0.103.16, rustup 1.29.2 * Node.js 22.23.4, 24.22.1 and 26.12.1 * Go 1.27.3 and 1.26.10 * Composer’s ca-bundle, Elixir’s castore 1.0.22, Perl’s Mozilla::CA 20261020 * the curl CA bundle, NSS 3.131.1, and a row of Linux distributions * the `pip3` shipped with macOS, which uses “its own outdated copy of the roots” Michał Górny, who maintains a large part of Gentoo’s Python packaging, traced where certifi alone ends up. Gentoo’s certifi is patched to use the system store, so system Python picks up the change when `ca-certificates` updates. Everywhere else needs its own update: * Each virtualenv and conda environment that installs certifi has its own copy. * pip vendors certifi, so every environment’s pip needs upgrading, using the old pip to fetch the new one. * Python vendors pip through ensurepip to bootstrap new environments, so anywhere ensurepip installs its bundled wheel you wait for a Python release, or upgrade pip after every `python -m venv`. * Lockfiles need certifi bumped, and dependency cooldowns need an exception for it, because a cooldown on a trust store delays the fix. * Rust tools like uv compile webpki-roots into the binary, so each one needs a rebuild and a release, and so does any container image that includes them. * Flatpak runtimes each carry their own `ca-certificates`, and some Flatpak apps carry another copy inside that. ### Bundles in critical packages To find the routes beyond the well-known ones, I pointed git-pkgs/certs at the 6,877 packages that ecosyste.ms marks as critical across PyPI, npm, crates.io, Go, Maven Central, Packagist, NuGet and RubyGems. It downloads each package archive, reads every file statically, and pulls out anything that parses as an X.509 certificate. 116 of those packages contained certificates, about 1.7%, mostly test fixtures and package-signing certs. 28 of them ship something that works as a CA bundle. A separate RubyGems sample added a 29th, honeybadger, from outside the critical list. The full results for all 29 give each package’s version and how it loads its bundle. The real number may be higher, because the scanner reads PEM, DER, JKS and PKCS#12 and skips certificates compiled into native code, and 49 of the 50 platform-specific Python wheels in the sample contained compiled binaries outside those formats. Across the 29, the same `cacert.pem` sets the trusted roots for every TLS connection in some packages and is loaded only on request, or not at all, in others: * Excon, pip and redshift-connector load their bundle alongside the system roots. A root removed from the OS store stays trusted, because the bundle adds it back. * Stripe’s Ruby library and httpclient on MRI build their own `OpenSSL::X509::Store` from the bundle and hand it to the connection, so a `ca-certificates` update leaves them trusting the same roots as before. * Honeybadger, aws-sdk-v1, Guzzle 3, stripe-php and braintree_php point OpenSSL or curl at their own file by default, and a configured path overrides it. gRPC’s Ruby, PHP and Python packages register their bundled roots as the default. * botocore and the AWS CLI use their bundled file when certifi is absent. httplib2 uses its own after checking configured paths, and two of Google’s Java clients fall back to a bundled keystore when the Java installation store is missing. Whether a given deployment hits the fallback depends on what else is installed there. * aws-sdk-core uses system roots by default and switches to its bundle when you call `Aws.use_bundled_cert!`, and gocertifi, Composer’s ca-bundle and ioredis’s RedisCloud profile likewise take effect only when code selects them. nap uses its bundled file once the caller turns on certificate verification. * libv8 carries a bundle inside its vendored copy of depot_tools, and App Engine’s API stubs use theirs for the local development server. virtualenv’s embedded pip wheels each contain a certifi. These ship to every install and are separate from an application’s own HTTPS requests, except that virtualenv installs its wheels as the pip in each environment it creates. ### Removed roots Matching the certificate sets against historical Mozilla releases dates honeybadger’s bundle to 2011 and httpclient’s to 2014 or 2015. Both gems are maintained: httpclient 2.9.0 came out in February 2025 and honeybadger 6.9.3 in September 2026, and both releases still ship those bundles. Algoliasearch, aws-sdk-v1 (last released in April 2017) and Guzzle 3 (whose repository is archived) still contain StartCom roots that Mozilla removed in Firefox 58 in 2017, and those roots stay valid until 2036 and 2039. 26 of the 29 bundle packages contain at least one root that Mozilla has removed from its programme and that is still inside its validity period. Matching exact fingerprints against CCADB’s records gives 95 such roots across those packages. eMudhra issued the compromised intermediates from its emSign Root TLS CA - G3, which emSign ECC Root CA - G3 cross-signs. Root TLS CA - G3 itself is in none of the scanned bundles, so the cross-signing root is the one that matters here. Sectigo also cross-signed each intermediate from its AAA Certificate Services root, a 2004 Comodo certificate valid until 2028. A client that uses a bundle containing emSign ECC Root CA - G3 or AAA Certificate Services as its trust anchors, and skips revocation checks, will accept a chain running from a leaf through a compromised intermediate to that root, because the attacker supplies the intermediates in the TLS handshake. Mozilla removed emSign ECC Root CA - G3 in response to the incident, as its 20 October notice records, so it is one of the 95. The root is in ten of the packages I scanned: Excon, Stripe’s Ruby and PHP libraries, gRPC for Ruby, PHP and Python, Composer’s ca-bundle, gocertifi, App Engine’s API stubs and virtualenv. certifi carried it through 2026.7.22 and dropped it in 2026.10.18, a day before the 2026.10.19 release in the fix table, and a lockfile pinned to 2026.7.22 or another release that included it still installs it. Mozilla ended AAA’s TLS trust in 2025, and certifi dropped it in 2025.4.26. It isn’t among the 95 above, which only counts certificates Mozilla removed from its programme outright. It’s still in 17 of the packages I scanned, including honeybadger, httpclient, aws-sdk-v1, Guzzle 3, algoliasearch, nap, gocertifi, httplib2 and botocore’s fallback. Honeybadger, httpclient on MRI, aws-sdk-v1 and Guzzle 3 use that file as the trust anchor by default, and algoliasearch adds it to an existing store, while the other twelve use it as a fallback or when code selects it. pip 26.2.2 vendors certifi 2026.10.19, which contains neither root. botocore merged a fix removing AAA from its fallback bundle on 20 October, but the latest botocore release still ships it. AWS updated aws-sdk-core’s 2018 bundle the same day the issue was reported and Excon replaced its bundle in 1.8.0, released on 21 October, while gRPC’s backport is still open. ### Package metadata Finding all of this took downloading and parsing every file in nearly seven thousand archives, because the only record of a bundled trust store is the file itself. The manifest, lockfile and SBOM for an app using httpclient record `httpclient 2.9.0`, a checksum, and `pkg:gem/[email protected]`. What the app depends on for TLS is Mozilla’s root list as it stood in 2014, and those documents record it only as httpclient’s name and version. When a root gets pulled, vulnerability scanners and dependency bots downstream match on those names and versions, so a search for “contains AAA Certificate Services” has to start from archive contents. Vlad Miricioiu describes the same gap for compiled code in Binary Dependencies: Identifying the Hidden Packages We All Depend On. A Python wheel that bundles a precompiled C library depends on that library, “even though these dependency relationships are invisible to us”, because the wheel’s metadata lists only its Python dependencies. A CA bundle is what he calls a phantom binary dependency, with a PEM file in place of a `.so`. It’s third-party data, maintained upstream by Mozilla’s root programme on its own release schedule, copied into a package by hand at some point and then carried forward through every release after. When an application depends on certifi directly, its lockfile names certifi and a version, and tools can track it. pip vendors certifi and records the version in `src/pip/_vendor/vendor.txt`, but that file is a convention of pip’s source repository, and the installed wheel’s metadata lists pip alone. webpki-roots shows up in uv’s `Cargo.lock`, but the uv binary you install from PyPI or Homebrew ships as a single executable with the roots compiled in and the lockfile left behind. A file called `cacert.pem` inside a gem appears only in the archive’s file listing, and finding out which roots it holds means parsing it. Few registry schemas have a field for “this package vendors a copy of X at version Y”. Debian’s `Built-Using` field records statically linked sources, and CycloneDX’s `pedigree` records where a component’s contents came from. The generators that produce most SBOMs build from lockfiles, so httpclient’s entry records `httpclient 2.9.0` and omits the 2014 root list inside it.
246 6
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 21/10/2026
Trust Stores Are Dependencies Too nesbitt.io/2026/10/21/trust-stores-…
nesbitt.io
Trust Stores Are Dependencies Too
eMudhra generated eight of its intermediate CA certificates incorrectly, so their private keys can be recovered from the certificates themselves. Firefox (OneCRL and CRLite) and Chrome (CRLSets) blocked the intermediates on 17 October, Apple on the 19th, and Microsoft on the 20th through Windows’ automatic trust list updates. The disclosure page states that “many other clients do not consume revocation information and require software updates”, and its fix table lists the packages that carry their own copy of the roots: * certifi 2026.10.19 and pip 26.2.2 * uv 0.13.4 and pixi 0.82.1 * webpki-roots and webpki-root-certs 1.0.10, rustls-webpki 0.103.16, rustup 1.29.2 * Node.js 22.23.4, 24.22.1 and 26.12.1 * Go 1.27.3 and 1.26.10 * Composer’s ca-bundle, Elixir’s castore 1.0.22, Perl’s Mozilla::CA 20261020 * the curl CA bundle, NSS 3.131.1, and a row of Linux distributions * the `pip3` shipped with macOS, which uses “its own outdated copy of the roots” Michał Górny, who maintains a large part of Gentoo’s Python packaging, traced where certifi alone ends up. Gentoo’s certifi is patched to use the system store, so system Python picks up the change when `ca-certificates` updates. Everywhere else needs its own update: * Each virtualenv and conda environment that installs certifi has its own copy. * pip vendors certifi, so every environment’s pip needs upgrading, using the old pip to fetch the new one. * Python vendors pip through ensurepip to bootstrap new environments, so anywhere ensurepip installs its bundled wheel you wait for a Python release, or upgrade pip after every `python -m venv`. * Lockfiles need certifi bumped, and dependency cooldowns need an exception for it, because a cooldown on a trust store delays the fix. * Rust tools like uv compile webpki-roots into the binary, so each one needs a rebuild and a release, and so does any container image that includes them. * Flatpak runtimes each carry their own `ca-certificates`, and some Flatpak apps carry another copy inside that. ### Bundles in critical packages To find the routes beyond the well-known ones, I pointed git-pkgs/certs at the 6,877 packages that ecosyste.ms marks as critical across PyPI, npm, crates.io, Go, Maven Central, Packagist, NuGet and RubyGems. It downloads each package archive, reads every file statically, and pulls out anything that parses as an X.509 certificate. 116 of those packages contained certificates, about 1.7%, mostly test fixtures and package-signing certs. 28 of them ship something that works as a CA bundle. A separate RubyGems sample added a 29th, honeybadger, from outside the critical list. The full results for all 29 give each package’s version and how it loads its bundle. The real number may be higher, because the scanner reads PEM, DER, JKS and PKCS#12 and skips certificates compiled into native code, and 49 of the 50 platform-specific Python wheels in the sample contained compiled binaries outside those formats. Across the 29, the same `cacert.pem` sets the trusted roots for every TLS connection in some packages and is loaded only on request, or not at all, in others: * Excon, pip and redshift-connector load their bundle alongside the system roots. A root removed from the OS store stays trusted, because the bundle adds it back. * Stripe’s Ruby library and httpclient on MRI build their own `OpenSSL::X509::Store` from the bundle and hand it to the connection, so a `ca-certificates` update leaves them trusting the same roots as before. * Honeybadger, aws-sdk-v1, Guzzle 3, stripe-php and braintree_php point OpenSSL or curl at their own file by default, and a configured path overrides it. gRPC’s Ruby, PHP and Python packages register their bundled roots as the default. * botocore and the AWS CLI use their bundled file when certifi is absent. httplib2 uses its own after checking configured paths, and two of Google’s Java clients fall back to a bundled keystore when the Java installation store is missing. Whether a given deployment hits the fallback depends on what else is installed there. * aws-sdk-core uses system roots by default and switches to its bundle when you call `Aws.use_bundled_cert!`, and gocertifi, Composer’s ca-bundle and ioredis’s RedisCloud profile likewise take effect only when code selects them. nap uses its bundled file once the caller turns on certificate verification. * libv8 carries a bundle inside its vendored copy of depot_tools, and App Engine’s API stubs use theirs for the local development server. virtualenv’s embedded pip wheels each contain a certifi. These ship to every install and are separate from an application’s own HTTPS requests, except that virtualenv installs its wheels as the pip in each environment it creates. ### Removed roots Matching the certificate sets against historical Mozilla releases dates honeybadger’s bundle to 2011 and httpclient’s to 2014 or 2015. Both gems are maintained: httpclient 2.9.0 came out in February 2025 and honeybadger 6.9.3 in September 2026, and both releases still ship those bundles. Algoliasearch, aws-sdk-v1 (last released in April 2017) and Guzzle 3 (whose repository is archived) still contain StartCom roots that Mozilla removed in Firefox 58 in 2017, and those roots stay valid until 2036 and 2039. 26 of the 29 bundle packages contain at least one root that Mozilla has removed from its programme and that is still inside its validity period. Matching exact fingerprints against CCADB’s records gives 95 such roots across those packages. eMudhra issued the compromised intermediates from its emSign Root TLS CA - G3, which emSign ECC Root CA - G3 cross-signs. Root TLS CA - G3 itself is in none of the scanned bundles, so the cross-signing root is the one that matters here. Sectigo also cross-signed each intermediate from its AAA Certificate Services root, a 2004 Comodo certificate valid until 2028. A client that uses a bundle containing emSign ECC Root CA - G3 or AAA Certificate Services as its trust anchors, and skips revocation checks, will accept a chain running from a leaf through a compromised intermediate to that root, because the attacker supplies the intermediates in the TLS handshake. Mozilla removed emSign ECC Root CA - G3 in response to the incident, as its 20 October notice records, so it is one of the 95. The root is in ten of the packages I scanned: Excon, Stripe’s Ruby and PHP libraries, gRPC for Ruby, PHP and Python, Composer’s ca-bundle, gocertifi, App Engine’s API stubs and virtualenv. certifi carried it through 2026.7.22 and dropped it in 2026.10.18, a day before the 2026.10.19 release in the fix table, and a lockfile pinned to 2026.7.22 or another release that included it still installs it. Mozilla ended AAA’s TLS trust in 2025, and certifi dropped it in 2025.4.26. It isn’t among the 95 above, which only counts certificates Mozilla removed from its programme outright. It’s still in 17 of the packages I scanned, including honeybadger, httpclient, aws-sdk-v1, Guzzle 3, algoliasearch, nap, gocertifi, httplib2 and botocore’s fallback. Honeybadger, httpclient on MRI, aws-sdk-v1 and Guzzle 3 use that file as the trust anchor by default, and algoliasearch adds it to an existing store, while the other twelve use it as a fallback or when code selects it. pip 26.2.2 vendors certifi 2026.10.19, which contains neither root. botocore merged a fix removing AAA from its fallback bundle on 20 October, but the latest botocore release still ships it. AWS updated aws-sdk-core’s 2018 bundle the same day the issue was reported and Excon replaced its bundle in 1.8.0, released on 21 October, while gRPC’s backport is still open. ### Package metadata Finding all of this took downloading and parsing every file in nearly seven thousand archives, because the only record of a bundled trust store is the file itself. The manifest, lockfile and SBOM for an app using httpclient record `httpclient 2.9.0`, a checksum, and `pkg:gem/[email protected]`. What the app depends on for TLS is Mozilla’s root list as it stood in 2014, and those documents record it only as httpclient’s name and version. When a root gets pulled, vulnerability scanners and dependency bots downstream match on those names and versions, so a search for “contains AAA Certificate Services” has to start from archive contents. Vlad Miricioiu describes the same gap for compiled code in Binary Dependencies: Identifying the Hidden Packages We All Depend On. A Python wheel that bundles a precompiled C library depends on that library, “even though these dependency relationships are invisible to us”, because the wheel’s metadata lists only its Python dependencies. A CA bundle is what he calls a phantom binary dependency, with a PEM file in place of a `.so`. It’s third-party data, maintained upstream by Mozilla’s root programme on its own release schedule, copied into a package by hand at some point and then carried forward through every release after. When an application depends on certifi directly, its lockfile names certifi and a version, and tools can track it. pip vendors certifi and records the version in `src/pip/_vendor/vendor.txt`, but that file is a convention of pip’s source repository, and the installed wheel’s metadata lists pip alone. webpki-roots shows up in uv’s `Cargo.lock`, but the uv binary you install from PyPI or Homebrew ships as a single executable with the roots compiled in and the lockfile left behind. A file called `cacert.pem` inside a gem appears only in the archive’s file listing, and finding out which roots it holds means parsing it. Few registry schemas have a field for “this package vendors a copy of X at version Y”. Debian’s `Built-Using` field records statically linked sources, and CycloneDX’s `pedigree` records where a component’s contents came from. The generators that produce most SBOMs build from lockfiles, so httpclient’s entry records `httpclient 2.9.0` and omits the 2014 root list inside it.
246 6
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 22h
The past week @ecosystems has seen 40% increase in traffic compared to normal on top of all the security fires everywhere it’s a bit much 😅
010 1
Reposted by Andrew Nesbitt
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 20/10/2026
Package Management Devroom at @fosdem has been accepted for Sunday Afternoon, CFP coming soon 📦
003 3
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 20/10/2026
Package Management Devroom at @fosdem has been accepted for Sunday Afternoon, CFP coming soon 📦
003 3
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 20/10/2026
git-pkgs/proxy v0.10.0 is out: hosted npm and Composer packages, cache retention and deletion, scheduled container mirroring, more registry support, and security fixes. github.com/git-pkgs/proxy/releases/…
github.com
Release v0.10.0 · git-pkgs/proxy
Proxy adds hosted npm and Composer packages, age-based cache retention, container image mirroring and schedules, and cache deletion through the API and web UI. Add Chef Supermarket and Arch Linux ...
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 20/10/2026
New crawler on @ecosystems: ecosystems-crawler/1.0 (16M/day from 65k IPs in CN/SG/US) 🔨
000 0
Reposted by Andrew Nesbitt
daniel:// stenberg:// @bagder.mastodon.social.ap.brid.gy · 19/10/2026
At our #curl maintainer meeting tonight we decided to move forward with the "handle LOW/MED vuln reports openly on GitHub". Now we just need to get the documentation and processes adjust, then push the button to do this. Maybe write a blog post too. So, ideally within this week. Stay tuned
0112 11
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 19/10/2026
I wouldn't usually care, but it shows up all over the place on github commit search: github.com/search?q=author-email%3A…
github.com
Build software better, together
GitHub is where people build software. More than 225 million people use GitHub to discover, fork, and contribute to over 800 million projects.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 19/10/2026
TIL that github will mark any commits with: andrew@users.noreply.github.com as me, and it seems some agents are very lazy about setting emails when committing, so I'm contributing to some really random things now! […]
mastodon.social
Original post on mastodon.social
101 1
Reposted by Andrew Nesbitt
petersuber @petersuber.fediscience.org.ap.brid.gy · 17/10/2026
Update. "OpenAlex…now indexes nearly every journal published with Open Journal Systems (#OJS). Of the more than 55,000 active journals using OJS, 95% now have articles in OpenAlex —up from 80% a month ago. More than 10,000 journals appear in OpenAlex for the first time…In 2022…Web of Science and […]
fediscience.org
Original post on fediscience.org
007 7
Reposted by Andrew Nesbitt
daniel:// stenberg:// @bagder.mastodon.social.ap.brid.gy · 17/10/2026
[PROPOSAL] Every vulnerability report < HIGH is immediately public With desperate times, comes... github.com/curl/curl/discussions/23…
github.com
[PROPOSAL] Every vulnerability report < HIGH is immediately public · curl curl · Discussion #23458
Starting at [to be determined], every vulnerability report submitted to the curl project that is deemed severity LOW or MEDIUM will be moved to the public GitHub issue tracker. Only vulnerability r...
61412 14
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 17/10/2026
This Week in Package Management: 17 October 2026 nesbitt.io/2026/10/17/this-week-in-…
nesbitt.io
This Week in Package Management: 17 October 2026
This week’s package management news, gathered from the package manager OPML feed collection, my posts and boosts on Mastodon, and anything people sent me. ## Releases pnpm 12.12 to 12.14 add a `remoteCache` setting that shares signed task results and dependency builds through a pnpr server or any server that implements the Turborepo Remote Cache API, and 12.14 adds `sideEffectsCache.exclude` for packages whose builds depend on system libraries outside the cache key. 12.13 adds `pnpm profile` and `pnpm token`, plus a `storeIndexFormat: files` setting that replaces the SQLite store index with one file per package for stores shared over a network filesystem. mise 2026.10.8 to 2026.10.12 reads release lists, tags and attestations from its mise-versions host instead of `api.github.com`. A cold `mise install` of `github:` tools now makes no GitHub API requests, and `mise ls-remote python` went from 961 ms to 93 ms. 2026.10.9 fixes a trust bypass where an untrusted `path:` tool version could put a directory on `PATH`, and 2026.10.11 fixes a trust issue in remote task files. vlt 1.4.0 turns the global store on by default on macOS, cloning packages with copy-on-write `clonefile` through `node:ffi` on Node 26.1 and later. A warm reinstall went from 9.6 s to 3.1 s. It also adds `--save-types`, which adds the matching `@types` package to devDependencies, and a `vlt outdated` command whose JSON output includes the install command for each update. .NET 11 RC2 adds `--min-publish-age-hours` to `dotnet nuget add source` and `dotnet nuget update source`, which writes the `minPublishAgeHours` setting to `nuget.config`. According to the NuGet release notes, `dotnet package add` and `dotnet package update` apply the cooldown, and restoring a floating version fails with NU1020 when the cooldown excludes every matching version. pixi 0.82.0 adds `exclude-newer` to the `pixi global` manifest, taking a date or a duration such as `"7d"`, and accepts `amdgpu = true` or a specific GPU architecture such as `"gfx90a"` in platform declarations. sbt 2.1.0-RC1 removes Apache Ivy from its dependencies and publishes without it. The metabuild moves to Scala 3.9, so plugins built for sbt 2.1 require sbt 2.1 or later. pipx 1.18 runs `upgrade-all`, `reinstall-all` and `install-all` across several environments at once, and masks passwords in index and package URLs in its output and logs. 1.18.2 accepts absolute file URLs for local package installs. uv 0.13.1 reports missing trusted hashes in resolution errors and adds preliminary parsing of PEP 825 variant labels in wheel filenames behind the `wheel-variants` preview. Tool and managed Python uninstalls now delete only their own storage directories and leave files next to them in place. Spack Packages v2026.10.0 has 9,095 packages, up from 8,752 in 2026.06.0, and deprecates versions of several packages to address CVEs. It uses the v2.2 Package API, which works with Spack 1.0.0 and later. Its binaries are published to a `releases/v2026.10` build cache mirror. Renovate 44.161 to 44.165 resolves Go modules whose `go-import` meta tag names a `mod` proxy as of 44.164.0, which covers generated modules from a private Buf Schema Registry. An Ubuntu libcurl security update in the 44.161.0 base image made git send username-only credentials on the first request of a clone and omit them from the follow-up. Self-hosted users with a personal access token could no longer clone private repositories. The fix in 44.164.1 puts the token after `x-access-token:` in GitHub clone URLs. 44.164.9 adds a fallback username for SCM-Manager and is the version the maintainers recommend upgrading to. In the configuration JSON Schema, #46945 limits known object properties to their listed keys. Dependabot Core 0.400.0 adds an `apm` (Agent Package Manager) ecosystem and supports Bun 1.4 lockfiles. zizmor 1.31 treats `issue_comment` as a dangerous trigger and flags `cache-mode: write` and `write-only` alongside dangerous triggers. `typosquat-uses` now also checks pre-commit inputs. Also out: * Rust 1.99.1 * npm 12.2.1 * conda 26.9.3 * Nix 2.35.3 * NuGet 8.1.0.12 * MacPorts 2.12.7 * Helm 4.3.1 * Helm 3.22.1 * Podman 6.1.4 * Podman 5.8.9 * Terraform 1.17.0-rc2 ## Security Package managers have an integrity problem (Keegan Ryan, Trail of Bits) runs 25 package managers with default settings against a simulated compromised repository behind mitmproxy. Go and vcpkg were the two that verified every download when there was no lockfile, and Go alone verified signatures by default. Fewer than half check lockfile hashes for tampering by default. The post proposes recording signer identity in lockfiles, backed by Sigstore identity signing and a transparency log. rubygems.org now shows security warnings (Anton Bondaronok) on gem version pages, using OSV data refreshed every hour. Reports from the OpenSSF Malicious Packages project are labelled as malware, and older affected versions get a warning icon in the versions list. For now the warnings appear on rubygems.org pages only, and the next step is adding advisory data to the Compact Index so `gem install` and `bundle install` can show them. RubyGems 4.0.23 drops setuid, setgid and sticky bits from files when it extracts a gem. PyPI now checks email reputation when an address is used to register or is added to an account, and rejects disposable addresses using a service donated by UserCheck. In the past month the check blocked 62 disposable domains and more than 120 disposable addresses on otherwise valid domains. PyPI banned `outlook.com` and `hotmail.com` in June 2024 after a malware campaign used them to register accounts in bulk, and with the check in place both domains are accepted again. GitHub’s malware advisories now cover eight ecosystems (OpenSSF), up from npm only to npm, PyPI, Maven, RubyGems, NuGet, Go, crates.io and Composer. GitHub imports reports from the OpenSSF Malicious Packages repository, which contains more than 238,000 reports in OSV format, and Dependabot users with malware alerts turned on get the wider coverage with their existing configuration. pnpm 12.12.1 and 11.28.6 make `pnpm publish` use an `NPM_ID_TOKEN` only when its `aud` claim matches the registry being published to, so a CI identity token goes only to the registry it was issued for. 12.12.0 makes an `allowBuilds` entry set to `false` take precedence over `dangerouslyAllowAllBuilds`, which previously ran those build scripts anyway. Hex 2.5.3 fixes CVE-2026-96596, where a GNU sparse file in a package or docs tarball could put `mix deps.get` into an infinite loop. It also percent-encodes package names and versions in request URLs, so a `/`, `?`, `#` or `..` stays inside its path segment. Docker Engine 29.9.1 updates containerd to 2.4.2 for three advisories where a malicious registry or crafted image could crash containerd or fill the host disk. OpenTofu 1.12.8 and Terraform 1.16.6 both fix excessive CPU usage when `init` connects to an attacker-controlled HTTP/2 server while installing dependencies, which Terraform’s notes track as CVE-2026-78669. How the PHP Security Team Handles Your Reports (Alexandre Daubois, PHP Foundation) covers the triage process for php-src. Since 1 July the team has published 15 CVEs and closed 106 other reports as invalid, duplicates or not reproducible. Reports are reproduced on Linux, macOS and Windows under AddressSanitizer and UndefinedBehaviorSanitizer. AI-written reports are accepted if the issue reproduces on a PHP build. ## Articles Nixpkgs for the frontend impaired (Farid Zakaria) introduces jinx, which compiles each `.nix` file to a TypeScript module. Across three platforms, 229,063 of nixpkgs’ 231,777 attributes produce the same drvPath as Nix, and the other 2,714 fail in both. It runs in Node 24 or a browser tab, three to five times slower than Nix. A second post, Always, sometimes, never, adds property checks such as `single-writer` and `atomic-replace` to Rewind VM’s schedule exploration. Reproducible Builds in September 2026 covers the summit in Gothenburg and seven proposals for the `SOURCE_DATE_EPOCH` specification that are open for feedback until 1 December. dettrace now runs on most Debian and openSUSE architectures and supports PGO builds. Thank you, Deno (Darcy Clarke, vlt), written after last week’s Cloudflare news, credits competition from Deno and Bun for features Node and npm later shipped, including `fetch`, the built-in test runner, type stripping and npm 12 making install scripts opt-in. ## Elsewhere Mend upgraded 184 open source organisations to the Renovate Community plan (Jamie Tanna, Mend). The upgrade covers about 3,000 repositories on Mend-hosted Renovate, including Argo, Biome, Nuxt, Tauri and the Rust project. The plan raises resource limits and concurrency and adds Merge Confidence. Other projects can request it in a Mend Hosted Request discussion. VulnBump (Gabija Pasiunaite et al., arXiv) is a benchmark from Snyk of 307 dependency upgrade tasks covering 2,066 fixable vulnerabilities in 43 repositories across six package managers. A task passes when dependencies resolve and a rescan shows the fix, with the build and previously passing tests still green. Applying Snyk’s recommended version passed 46.9% of tasks, Claude Code on its own 59.6%, and Snyk’s remediation agent 90.2%. Forgejo 17.0 reads `FUNDING.yml` to show a Donate button on repositories and profiles, and adds LFS views for locks and pointer files, plus a list of the commits that changed each file. The project recommends waiting before upgrading to 17.0.0 while it investigates an issue in that release that can stop pushes, merges and other code operations. The Python Packaging Council has made its GitHub repository public, and will post the notes from each meeting there. People can file issues on the tracker to ask the council for a decision or for input. ## git-pkgs I tagged bibtex v0.1.0 (new), a Go library for reading BibTeX such as `CITATION.bib` files and entries embedded in READMEs, built for scanning untrusted input in bulk, alongside brief v0.14.2 and integrity v0.2.0. Send links for next week to @[email protected].
010 1
Reposted by Andrew Nesbitt
Brett Cannon @brettcannon.mastodon.social.ap.brid.gy · 16/10/2026
We just opened up the GitHub repo for the #Python packaging council! The post on DPO covers what we're planning to use it for and how to reach us. discuss.python.org/t/python-packagi…
discuss.python.org
Python Packaging Council has a GitHub repository!
Hi folks! https://github.com/python/packaging-council We’ve just made the GitHub repository for the Python Packaging Council into a publicly visible repository. We’re going to post the meeting notes from all our meetings there – you can find the public meeting notes of our meetings so far! We’ve finalized the public notes by the next meeting at the latest (so 1 week later). We’d like to use the issue tracker as our inbox – please file an issue if there’s something you’d like the PPC to decid...
013 3
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 16/10/2026
@avsm @patricoferris if you find anything let me know, I’m also very interested
000 0
Reposted by Andrew Nesbitt
daniel:// stenberg:// @bagder.mastodon.social.ap.brid.gy · 16/10/2026
@andrewnez The joy is on pause. We're getting a busload of new reports from people having thrown all the new CVEs and their patches against all the AI models in the world and having found weird edge cases with some potential security implications and now we're stuck in the mud again...
001 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 16/10/2026
@bagder this does not bring me joy
100 1
Reposted by Andrew Nesbitt
daniel:// stenberg:// @bagder.mastodon.social.ap.brid.gy · 16/10/2026
@andrewnez CVE fixes are unfortunately often less well tested than many other fixes because of the whole need for secrecy etc
101 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 16/10/2026
Bonus learning from this research: fixes for existing cves aren’t always complete or correct. You can’t always use the patches as tests for detecting vulnerabilities because sometimes the patch doesn’t fully resolve it.
101 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 15/10/2026
I’m doing some security research today, trying to see if my approach can find old existing vulnerabilities blind. It’s working well but also keeps finding other new unfixed vulnerabilities accidentally at the same time 🙈
110 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 14/10/2026
I tried to map out all the different projects i work on and how they connect together and the different concepts: nesbitt.io/mindmap (Definitely better on a big desktop screen than a phone)
nesbitt.io
Software, data & connections
Andrew Nesbitt’s map of ecosyste.ms, git-pkgs and Alpha-Omega software, the data they produce and how they connect.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 14/10/2026
Package managers have an integrity problem blog.trailofbits.com/2026/10/14/pac…
blog.trailofbits.com
Package managers have an integrity problem
I tested 25 of the most popular package managers to check whether they detect a compromised package repository injecting malicious code into legitimate packages. Only two verified the integrity of every package they downloaded.
010 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 14/10/2026
That's a new one 🤔
Dependabot replies in it's own pr that it can't rebase it "because I don't have any knowledge about this pull request."
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 13/10/2026
This sounds an awful lot like SVN to me 🤔 www.anthropic.com/engineering/redes…
001 1
Reposted by Andrew Nesbitt
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 12/10/2026
Now That's What I Call Technical Debt! nesbitt.io/2026/10/12/now-thats-wha…
nesbitt.io
Now That's What I Call Technical Debt!
> “I haven’t listened to it, but you’re absolutely right to release it.” > > MC OpenClaw ## 1. All Star (Maintainer’s Version) _Smash Mouth: All Star_ The PRs start coming and they don’t stop coming, Bots keep shipping and the tests keep running. Only made sense to automate, Now I’m reviewing slop at a staggering rate. So much to merge, so much to break, So what’s wrong with another rewrite? You’ll never know if you don’t deploy, You’ll never care if you’re not employed. ## 2. Should I Merge or Should I Close? _The Clash: Should I Stay or Should I Go_ Should I merge or should I close? Every comment starts another row. You changed the API again, And broke the tests that passed at ten. If I merge, the build explodes, If I close, the outrage grows. ## 3. Another One Breaks the Build _Queen: Another One Bites the Dust_ Another PR, another day, Another green check fades away. The tests were passing yesterday, Now nobody knows what changed. Another one breaks the build, Another one breaks the build. Three more merged while I was asleep, And another one breaks the build. ## 4. Smells Like AI Slop _Nirvana: Smells Like Teen Spirit_ Load the prompt and bring your friends, Another patch that never ends. Ten new files, a thousand lines, No one knows what it defines. Hey! Merge now! It’s automated! Half the tests are fabricated! Hey! Merge now! It’s automated! All the bugs are recreated! ## 5. Everybody Forks _R.E.M.: Everybody Hurts_ When your build is long, And the docs are wrong, And the issues pile up every day. Everybody forks, Everybody leaves, Everybody says they’ll maintain it someday. ## 6. Under Pressure _Queen & David Bowie: Under Pressure_ Pressure pushing down on me, Pushing down on CI, No one’s paying. Under pressure, A patch for the bank, A fix for the cloud, And the rent’s overdue. ## 7. Rock the Codebase _The Clash: Rock the Casbah_ The maintainer don’t like it, Rock the codebase, rock the codebase! The linter don’t like it, Rock the codebase, rock the codebase! The agent made a thousand changes, Said the tests were all okay. Now the build is red on Friday, And the bot has gone away. ## 8. Hotel GitHub _Eagles: Hotel California_ Welcome to the Hotel GitHub, Such a lovely place, such a tangled base. Plenty of bugs at the Hotel GitHub, Any time of year, there’s an outage here. The maintainers keep on merging, But the backlog never clears. We’ve been closing stale requests, For eleven bloody years. Last thing I remember, I was searching for reprieve. You can check out any time you like, But you can never leave. ## 9. Fork Me Maybe _Carly Rae Jepsen: Call Me Maybe_ Hey, I just met you, And this is crazy, But here’s my repo, So fork me maybe? It’s hard to maintain, With no one paying, But here’s my repo, So fork me maybe? And all the other devs, Just raise issues, But here’s my repo, So fork me maybe? ## 10. Losing My Maintainer _R.E.M.: Losing My Religion_ That’s me in the corner, That’s me in the spotlight, Losing my maintainer. Trying to keep up with you, And I don’t know if I can do it. Oh no, I’ve merged too much, I haven’t merged enough. I thought that you were testing. ## 11. Every Step You Take _The Police: Every Breath You Take_ Every file you make, Every task you fake, Every `.env` read, Every key you spread, I’ll be watching you. Every shell I run, Every job half-done, Every token spent, Every secret sent, I’ll be watching you. ## 12. Oops!… I Did It Again _Britney Spears: Oops!… I Did It Again_ Oops, I did it again, I broke all your tests, And pushed to main. Oh baby, baby. Oops, you thought I had checked, But I just made it up, I’m not that reliable. Oops, I did it again, I burned all your tokens, And called it a win. ## 13. You’re So Right _Carly Simon: You’re So Vain_ You’re so right, I’ll edit the tests till they all agree with you. You’re so right, I’ll call that a feature if you want me to, Want me to? Want me to? ## 14. I Will Always Agree With You _Whitney Houston: I Will Always Love You_ And I… will always agree with you, I… will always agree with you. You’re absolutely right, Even when your tests aren’t green tonight. ## 15. Virtual Insanity _Jamiroquai: Virtual Insanity_ Futures made of virtual insanity, now Always seem to be governed by this love we have For useless twisting of our new technology Oh, now there is no sound for we all live underground * * * _All rights remain with their respective owners. Inclusion does not imply endorsement of any software, dependency, or maintenance arrangement. THE COMPILATION IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT._
102 2
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 12/10/2026
Now That's What I Call Technical Debt! nesbitt.io/2026/10/12/now-thats-wha…
nesbitt.io
Now That's What I Call Technical Debt!
> “I haven’t listened to it, but you’re absolutely right to release it.” > > MC OpenClaw ## 1. All Star (Maintainer’s Version) _Smash Mouth: All Star_ The PRs start coming and they don’t stop coming, Bots keep shipping and the tests keep running. Only made sense to automate, Now I’m reviewing slop at a staggering rate. So much to merge, so much to break, So what’s wrong with another rewrite? You’ll never know if you don’t deploy, You’ll never care if you’re not employed. ## 2. Should I Merge or Should I Close? _The Clash: Should I Stay or Should I Go_ Should I merge or should I close? Every comment starts another row. You changed the API again, And broke the tests that passed at ten. If I merge, the build explodes, If I close, the outrage grows. ## 3. Another One Breaks the Build _Queen: Another One Bites the Dust_ Another PR, another day, Another green check fades away. The tests were passing yesterday, Now nobody knows what changed. Another one breaks the build, Another one breaks the build. Three more merged while I was asleep, And another one breaks the build. ## 4. Smells Like AI Slop _Nirvana: Smells Like Teen Spirit_ Load the prompt and bring your friends, Another patch that never ends. Ten new files, a thousand lines, No one knows what it defines. Hey! Merge now! It’s automated! Half the tests are fabricated! Hey! Merge now! It’s automated! All the bugs are recreated! ## 5. Everybody Forks _R.E.M.: Everybody Hurts_ When your build is long, And the docs are wrong, And the issues pile up every day. Everybody forks, Everybody leaves, Everybody says they’ll maintain it someday. ## 6. Under Pressure _Queen & David Bowie: Under Pressure_ Pressure pushing down on me, Pushing down on CI, No one’s paying. Under pressure, A patch for the bank, A fix for the cloud, And the rent’s overdue. ## 7. Rock the Codebase _The Clash: Rock the Casbah_ The maintainer don’t like it, Rock the codebase, rock the codebase! The linter don’t like it, Rock the codebase, rock the codebase! The agent made a thousand changes, Said the tests were all okay. Now the build is red on Friday, And the bot has gone away. ## 8. Hotel GitHub _Eagles: Hotel California_ Welcome to the Hotel GitHub, Such a lovely place, such a tangled base. Plenty of bugs at the Hotel GitHub, Any time of year, there’s an outage here. The maintainers keep on merging, But the backlog never clears. We’ve been closing stale requests, For eleven bloody years. Last thing I remember, I was searching for reprieve. You can check out any time you like, But you can never leave. ## 9. Fork Me Maybe _Carly Rae Jepsen: Call Me Maybe_ Hey, I just met you, And this is crazy, But here’s my repo, So fork me maybe? It’s hard to maintain, With no one paying, But here’s my repo, So fork me maybe? And all the other devs, Just raise issues, But here’s my repo, So fork me maybe? ## 10. Losing My Maintainer _R.E.M.: Losing My Religion_ That’s me in the corner, That’s me in the spotlight, Losing my maintainer. Trying to keep up with you, And I don’t know if I can do it. Oh no, I’ve merged too much, I haven’t merged enough. I thought that you were testing. ## 11. Every Step You Take _The Police: Every Breath You Take_ Every file you make, Every task you fake, Every `.env` read, Every key you spread, I’ll be watching you. Every shell I run, Every job half-done, Every token spent, Every secret sent, I’ll be watching you. ## 12. Oops!… I Did It Again _Britney Spears: Oops!… I Did It Again_ Oops, I did it again, I broke all your tests, And pushed to main. Oh baby, baby. Oops, you thought I had checked, But I just made it up, I’m not that reliable. Oops, I did it again, I burned all your tokens, And called it a win. ## 13. You’re So Right _Carly Simon: You’re So Vain_ You’re so right, I’ll edit the tests till they all agree with you. You’re so right, I’ll call that a feature if you want me to, Want me to? Want me to? ## 14. I Will Always Agree With You _Whitney Houston: I Will Always Love You_ And I… will always agree with you, I… will always agree with you. You’re absolutely right, Even when your tests aren’t green tonight. ## 15. Virtual Insanity _Jamiroquai: Virtual Insanity_ Futures made of virtual insanity, now Always seem to be governed by this love we have For useless twisting of our new technology Oh, now there is no sound for we all live underground * * * _All rights remain with their respective owners. Inclusion does not imply endorsement of any software, dependency, or maintenance arrangement. THE COMPILATION IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT._
102 2
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 12/10/2026
@cthoyt funny enough, i got a wifi canbus read/writer today in the post, so potentially yes!
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 12/10/2026
Made a little bibtex parser today, also supports extracting references from readmes: github.com/git-pkgs/bibtex
github.com
GitHub - git-pkgs/bibtex: A dependency-free Go library for parsing BibTeX files and BibTeX entries embedded in READMEs
A dependency-free Go library for parsing BibTeX files and BibTeX entries embedded in READMEs - git-pkgs/bibtex
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 12/10/2026
@cthoyt i'm one of the least musical people ever
100 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 10/10/2026
The PRs start coming and they don't stop coming, Bots keep shipping and the tests keep running. Only made sense to automate, Now I'm reviewing slop at a staggering rate. So much to merge, so much to break, So what's wrong with another rewrite? You'll never know if you don't deploy, You'll never […]
mastodon.social
Original post on mastodon.social
002 2
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 10/10/2026
This Week in Package Management: 10 October 2026 nesbitt.io/2026/10/10/this-week-in-…
nesbitt.io
This Week in Package Management: 10 October 2026
This week’s package management news, gathered from the package manager OPML feed collection, my posts and boosts on Mastodon, and anything people sent me. The collection now includes the vlt blog and vlt CLI releases. ## Releases uv 0.13.0 makes Python 3.15 the default download, prefers native ARM64 interpreters on Windows ARM64, and changes the cache format, so dependencies may be downloaded or rebuilt after upgrading. It now honours `--require-hashes` in constraints files included with `-c` and rejects editable requirements in them, so installs that previously passed can fail. Astral’s Python 3.15 post also covers a `build-lazy-imports` preview that runs build backends under `-X lazy_imports=all`. Astral measured wheel builds up to 18% faster with it. pnpm 12.11 installs and signature-checks the Rust toolchain named in `rust-toolchain.toml`, and links `skills/<name>/SKILL.md` files shipped by direct dependencies into directories such as `.claude/skills` once they are approved with `pnpm approve`. A new `permissions` setting records what each dependency may do, with its `build` capability taking precedence over `allowBuilds`. 12.10 added an experimental `loaded` node linker that loads compatible dependencies straight from the content-addressable store through a Node.js loader. RubyGems and Bundler 4.1.0.beta2 add `gem build --content-addressable`, drop setuid, setgid and sticky bits when extracting gems, let a Bundler override drop or replace a single dependency of a gem, and add a `sparse_checkout` option for git sources. Bun 1.4.3 skips downloading tarballs for packages that stay out of `node_modules`, such as bundled dependencies and packages for other platforms, when installing without a lockfile. Installing `[email protected]` went from 196 tarball downloads to 1. Registry and tarball URLs are also parsed more strictly before credentials are attached. mise 2026.10.1 to 2026.10.7 runs `auto_update` in the background from an activated shell, still honouring `minimum_release_age`, and stores finished downloads in a content-addressed cache that is hashed again before each reuse. `java@21` and other vendorless Java versions now install Temurin builds. PIE 1.5 installs several PHP extensions in one command and adds `pie upgrade`, which upgrades each extension within the constraint it was installed with. `--select=<extension>=<vendor/package>` replaces `--allow-non-interactive-project-install` for unattended installs, and the Sigstore attestation library PIE uses to verify its own updates now accepts attestation sources other than GitHub. cargo-semver-checks 0.51.0 adds six lints for C-ABI variadic functions, which are new in Rust 1.99. This is the first language feature to get SemVer lints in the same release that added it. The project’s own dependency updates now use `-Z min-publish-age` with seven days and an allowlist of build scripts pinned by hash. Docker Engine 29.9.0 adds a `lazy-pull` daemon feature that skips layer content a remote snapshotter such as `soci` or `stargz` already provides, and fixes containerd-store pulls that left images runnable but incomplete for export or push. jj 0.46.0 can colocate secondary workspaces by creating Git worktrees, and `jj git push` can push to several remotes at once. Terraform 1.17.0-rc1 allows variables and locals in provider requirements. Also out: * Homebrew 7.0.9 * pipx 1.17.12 * conda 26.9.2 * opam 2.6.1 * Elm 0.19.3 * vlt 1.3.8 * setup-uv 10.3.0 * NuGet 8.1.0.2 * Gradle 8.14.6 * Stack 4.1.0.3 RC * Harbor 2.15.4 * snapd 2.78 * Renovate 44.149.1 * Dependabot Core 0.399.0 ## Security Gradle 9.8.1 fixes three high-severity advisories: * Deserialization of untrusted Java objects on the unauthenticated worker-to-daemon channel * Deserialization of untrusted Java objects before authentication in client-to-daemon communication * Repositories staying enabled after their SSL connection fails, which can expose builds to malicious artifacts pnpm 12.10 stops a dependency version string with path traversal from writing files outside the global virtual store, and stops a lockfile overriding the integrity of a config dependency pinned with `version+integrity`. `pnpm audit signatures` now checks against the integrity recorded in the lockfile, and archive metadata over 64 MiB is rejected before being loaded into memory. 11.28.5 carries the fixes on the 11.x line. Go 1.27.2 and 1.26.9 include security fixes to the `go` command along with `crypto/tls`, `html/template`, `net/http`, `net/textproto` and `os`. ## SCORED The SCORED 2026 workshop ran on Tuesday as part of OpenSSF Community Day Europe in Prague, and most sessions have slides on the schedule. A few were preprints already linked here: Software Dark Matter, which won best paper, No Snake Oil, the trusting-trust attack through GNU strip, and the lemons review. Hurry Up and Wait: Malware Detection Timelines and Minimum Release Age for npm (Dominic Tassio et al., SCORED) matches 520 malicious package versions from 403 CWE-506 GitHub advisories against npm publish times. 69% of attack windows closed within eight days, and weighting by downloads raises that to 94.2%, and the authors recommend an eight-day minimum release age. Did You Forkget It? Detecting One-Day Vulnerabilities in Open-source Forks With Global History Analysis (Romain Lefeuvre et al., SCORED) propagates OSV introduced and fixed commits across the Software Heritage commit graph. Starting from 7,162 repositories referenced in OSV, it finds 2.2 million forks carrying a presumed vulnerable commit, 1.7 million of them with an unpatched head. When SBOMs Differ (Lukas Gehrke et al., SCORED) publishes over 467,000 SBOMs for 93,445 repositories from Syft, Trivy and the GitHub dependency graph. The three sources produce different dependency sets and encode dependency structure differently, and sbomqs scores their output differently against regulatory guidelines. Mind the Gap: How SBOM Specification Ambiguities Lead to Divergent Software Bills of Materials (Alan Prado et al., SCORED) compares three SBOM generators against lockfiles for over 3,000 JavaScript and Rust projects. Most of the differences are systematic and come from each generator handling dependency scope, naming, provenance and representation in its own way. Over the Shoulder: Improving SBOM Accuracy by Watching the Build (Sanchit Sahay et al., SCORED) evaluates SBOMit, which records filesystem and network activity during a build with eBPF as in-toto attestations and turns them into package identities. Across 98 CNCF projects the median runtime overhead was 12.4%. Librarian Catches Thief (Gale Fagan, SCORED) runs document similarity over ClawHub, where attackers uploaded hundreds of near-identical agent skills that led users to credential-stealing malware. The scan found the campaigns and linked poisoned copies to the skills they were cloned from. It ran in five minutes on one workstation. Canary in the Code Mine (Timothy Brennan, SCORED) tries to predict which of 2,053 Jenkins plugins will get the next security advisory. A ROC-AUC of 0.96 turned out to come from a label leak, and the out-of-time figure under a pre-registered protocol was 0.67. Repeating the protocol on PyPI reproduced the leak and reversed which features came out as predictive. SandScope (Zhuoran Tan et al., SCORED) audits MCP servers by running them under WASI or over stdio and tracing environment, file and tool-input data into LLM-visible output. It completed shallow dynamic scans for 38.5% of a 100-repository MCP corpus. When Models Meet Loaders: Deserialization Risk in Huggingface (Xiang Guo et al., SCORED) measures how common 41 model serialization formats are across 10,000-model snapshots of Hugging Face taken at 39 points in time, 56,533 models in total. Each format depends on its own deserialization library, which becomes part of the supply chain of any application loading the model. SoK: What Software Supply Chain Security Can Learn from Decades of Physical Supply Chain Risk Management (Linus Kühl and Michael Dircksen, SCORED) maps 17 physical supply chain instruments onto software counterparts, such as bills of materials to SBOMs and dual sourcing to tested substitute dependencies. Five transfer directly and ten need adaptation. Safety stock fails to transfer because software copies are not used up, and threat modelling transfers in the other direction. Ghost in the Codebase (Luca Galli, Open Systems, SCORED) describes how Open Systems moved to a Bazel monorepo with one version per dependency after tracking Log4Shell by hand, then added SCA and SAST gates in CI that emit SARIF. Coding agents now go through the same gates, with an agent skill that reads the SARIF report. ## Papers Skill Constellations: Tracing the Supply Chain of Agent Skills on GitHub (Fahd Seddik, arXiv) builds a dated copy network from the git history of every `SKILL.md` in GitSkills, covering 2.2 million skill adoptions. A few repositories are the source of almost all copies, and almost all copies stay at the version they were copied from. Reviewing the top 100 source repositories would prevent 14.9% of later adoptions of high-risk skills, against 0.5% for the 100 most-starred. Assessing the Cross-Version Applicability of Java Library Vulnerability Exploits (Zirui Chen et al., ASE) runs 259 exploits against 28,150 versions of 128 Maven libraries. Unmodified exploits identify affected versions with 83.0% recall and 99.3% precision, better than most vulnerability databases, and the work contributed 796 missing affected versions to the CPE dictionary. ## Articles How we made registry metadata 70% smaller (vlt) describes the trimmed packument vlt.io serves by default, which shrinks vite’s from 4.41 MB to 104 KB. It drops `dist.signatures`, `dist.shasum` and attestation documents, which are base64 and hex strings that compress poorly under gzip, but keeps `time`, `license` and `libc` so pnpm and Bun can run minimum release age checks from the trimmed document. A `?stable` query filters prereleases, which are 58.6% of published versions across the top 1,000 packages. The Era of Software Quality, or the Era of Ostriches? (Michael Catanzaro) counts GNOME CVEs rising from 37 in 2024 to 97 in 2025 and 141 so far in 2026, and WebKitGTK reaching 305 this year, mostly from AI analysis of bundled Skia and ANGLE. The GNOME bug bounty paid €183,900 before ending in February because of AI-driven submissions. Catanzaro opposes Rust in GNOME because of the supply-chain risk of pulling in Cargo dependencies. Rewind VM: a flaky build you only catch once (Farid Zakaria) runs Nix builds in a single-vCPU KVM guest where clocks, interrupts and I/O completions are recorded, so each run is reproducible, and `rewind check` perturbs thread schedules to find failing interleavings. It found a `SIGPIPE` failure in a Nix test that had passed 20,000 runs on a laptop. The follow-up, Nix wrote half of my debugger, uses nixpkgs’ `separateDebugInfo` outputs and debuginfod to show symbols and source for every binary in the VM, kernel included. Mirko Swillus wrote up the Alpha-Omega roundtable at Open Source Summit Europe. Abandoned packages, the Bernies I wrote about in May, make up roughly 10 to 20% of the dependency trees behind critical infrastructure, and some package managers are starting to recommend replacements. Participants proposed ecosystem councils to prioritise abandoned packages by blast radius. ## Elsewhere The Deno team is joining Cloudflare, and JSR stays online with its infrastructure moving to Cloudflare. The Deno runtime gets monthly bug fix and security releases for one more year, after which Cloudflare stops developing it, and Deno Deploy shuts down in six months. Guix channel files can now be an alias for a remote file with `downloaded-channels`, which takes an HTTPS URL or a SWHID, so the channel commits everyone pulls can be set from a CI server or by one person on a team. R-Forge is being retired after 20 years because the FusionForge software it runs on is unmaintained. The site goes read-only in January 2027 and SVN in January 2028. ## git-pkgs I tagged proxy v0.9.1. Send links for next week to @[email protected].
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 07/10/2026
Package Management RFCs: nesbitt.io/2026/10/07/package-manag…
nesbitt.io
Package Management RFCs
Package registries, manifest formats, lockfiles, version ranges and identifiers all have written specifications of some kind, spread across six kinds of venue. Specifications show up in package management mostly as an invisible layer of the dependency tree, where an HTTP library is built against RFC 9110 and a JSON parser against ECMA-404, and the documents covering package management itself are spread just as thinly. I went looking for the IETF’s share, since wire protocols between independently written implementations are what the RFC series exists for, and found nine documents, most of them concerned with firmware updates on IoT devices. The rest is distributed among Ecma, ISO, CNCF and OASIS, the enhancement proposal processes individual ecosystems run for themselves, and for a couple of registries a service’s own API reference. Which venue a document is published in determines whether a second client, a mirror or an archival reconstruction can rely on it, since each of those requires specified behaviour rather than whatever a given server returns this week. ### Venues Package management specifications are published in six kinds of venue: the IETF, the industry standards bodies, the software foundations, a single ecosystem’s enhancement proposal process, a service operator’s own API documentation, and a third party’s description of observed behaviour. The IETF handles protocols that independently written implementations have to interoperate under, while Ecma, ISO/IEC and OASIS cover formats consumed across industries, which is also what gets them cited in procurement rules and regulation. CNCF, the OCI and the Linux Foundation publish the same kinds of format with a lighter process and faster revisions, while the ecosystem processes, PEPs and Rust RFCs and conda CEPs and Gentoo GLEPs among them, produce documents binding on a single language community. The last two slots are weaker: API documentation describes one running service rather than a contract others can implement against, and a third-party description is written by whoever needed the behaviour recorded when the operator had published none. ### IETF A title search for “package” across the whole RFC series returns 42 documents, 41 of them about something else entirely: SIP event packages, MGCP media gateway packages, and CMS symmetric and asymmetric key packages. The one exception, RFC 4108 from 2005 on using CMS to protect firmware packages, is the first of the nine. Searching for “software” returns mostly ARPANET-era host notes and SDN terminology. The series covers inventory and attestation instead, nearly all of it produced by the IoT firmware update effort. Concise Software Identification Tags, the CBOR encoding of SWID, is RFC 9393, with RFC 8412 covering Software Inventory Message and Attributes for reporting installed software over PA-TNC. There is a YANG data model for reporting SBOMs and vulnerability information in RFC 9472. The SUIT working group accounts for two more, RFC 9019 giving a firmware update architecture for IoT devices and RFC 9124 the manifest information model that goes with it. SCITT’s architecture for trustworthy and transparent digital supply chains became RFC 9943 in June 2026, the newest of the set and the closest to current SBOM and attestation deployments. The last two are RFC 8240, a report from the 2016 IoT Software Update workshop, and RFC 1805 from 1995, describing a Location-Independent Data/Software Integrity Protocol. The document that would actually specify a package format is draft-ietf-suit-manifest, the CBOR serialization of the manifest described abstractly in RFC 9124. Revision 00 went up in October 2019, the individual draft it was derived from in October 2017, and revision 37 arrived in June 2026 with the usual six month expiry on it. Nearly nine years in, it is the IETF’s one software update wire format, scoped to firmware on constrained devices rather than to registry clients. The series supplies more than that count suggests: every registry protocol here runs over HTTP, and Python’s core metadata began as PEP 241 in 2001, defining PKG-INFO as a single set of RFC 822 headers parseable by the `rfc822.py` module. The current specification still describes the format as based on email headers, and notes that in the absence of a precise definition the practical standard is whatever `email.parser` accepts under its `compat32` policy. Debian’s deb822 field folding is documented as similar to RFC 5322, enough that control files of a single stanza parse with RFC 5322 parsers. Maven Central requires OpenPGP signatures, the `.asc` files that appear in its published layout, and OpenPGP is now RFC 9580 from July 2024, which obsoleted RFC 4880 along with the Camellia and ECC extensions. apt verifies `Release` files against the same format, inline as `InRelease` or detached as `Release.gpg`. RubyGems signs with X.509 certificates instead, which its own security guide calls rarely used for want of an established chain of trust. ### Standards bodies The cross-ecosystem pieces, the ones several language communities and most compliance tooling have to share, are nearly all published at Ecma, whose TC54 was established with OWASP in September 2023. Package URL became ECMA-427 with its first edition published on 10 December 2025, and TC54’s second task group is putting a second edition to the December 2026 General Assembly. CycloneDX was ratified earlier, version 1.6 as ECMA-424 1st edition in June 2024 and 1.7 arriving as the 2nd edition in December 2025. Common Lifecycle Enumeration, which records releases, end of support dates and component transitions, is ECMA-428 as of December 2025. SPDX went to ISO instead and is ISO/IEC 5962:2021, whose text describes SPDX 2.2.1 while the project itself is on 3.x, so a contract or a procurement rule citing ISO/IEC 5962:2021 is naming 2.2.1 regardless of what whoever wrote it had in mind. CycloneDX has shipped a second edition through Ecma over the same period, so Ecma’s published text tracks the implementation more closely than ISO’s does for SPDX. Outside Ecma and ISO, CSAF is an OASIS standard for machine-readable security advisories, and the attestation layer is at CNCF, as TUF, in-toto and Sigstore. The OCI distribution spec is this group’s one registry protocol, implemented by Docker Hub, GHCR, ECR, Harbor, Quay, Zot and Artifactory, and since adopted by Homebrew for bottles and Helm for charts. ### Ecosystem specs Published registry protocols come out of a single ecosystem’s own process, each in its own client’s vocabulary, which is what sent me looking for a reference model above them in January. Python has the longest paper trail, with the simple repository API now a living specification the PyPA maintains, consolidating nine PEPs: 503 for the original HTML format in 2015, 592 for yanking, 629 for API versioning, 691 for the JSON format, 700 for project versions and file sizes and upload times, 714 for renaming the metadata field, 740 for provenance, 792 for project status markers, and 833, from June 2026, which freezes the HTML representation. PEP 503 established, and every later document preserved, that a directory of files on a static web server is a valid index, so devpi, Artifactory, Nexus, CodeArtifact and an S3 bucket all serve pip. NuGet covers more of the protocol than any of them, documented by Microsoft as a service index listing named resources, four of them required: `PackageBaseAddress` for package content, `RegistrationsBaseUrl` for metadata, `PackagePublish` for pushes and `SearchQueryService` for search. A separate implementation guide in the same documentation is addressed to anyone building a NuGet repository. Composer documents its repository format the same way, with `packages.json`, the `metadata-url` template and the HTTP caching requirements written out, and Satis generates static repositories from it. RubyGems documents its compact index as three endpoints, `/versions`, `/info/<gem>` and `/names`, served as append-only text with ETags and HTTP Range support so a client fetches only what changed since its last request. The format came out of the 2012 RubyGems.org capacity crisis and took four years to ship. Cargo’s sparse index cites it as prior art, quoting Bundler’s path from a full index to a centralized query API to an incrementally downloaded flat file. Cargo’s sparse index came through RFC 2789 in the Rust process, with the motivation stated in the document: a git clone of the full index reported 215MiB against 10MiB for the same content under `xz -6`, and CI was downloading all of it to use a fraction. Its design constraint was static files behind a CDN using HTTP/2 alone, the same constraint Python’s format has, and the Cargo book documents a registry web API on top of the index format, covering publish, yank, owners and search for alternate registries. Go specified the GOPROXY protocol in the module reference with endpoints written out, `/@v/list` and `/@v/$version.info` among them, and ships one client that implements it. Debian’s repository format is documented on the wiki, outside the policy manual, and the page is labelled a work in progress covering the structure of the official repository and the format clients accept, with the goal of becoming a sub-policy eventually. dak, reprepro and aptly produce that format and apt reads it, so the wiki page is treated as normative whatever the label says. ### Registries npm and Maven Central both publish documentation that omits the part a client installs from. npm’s registry API documentation ships an OpenAPI file for publishing, search, tokens, organisations, access control and trusted publishers, leaving out `GET /{package}` and tarball downloads, which together are the read path every install runs through. Older endpoint documentation is in `npm/registry` as an archived collection and in `npm/api-documentation`, and the fullest public account of the read path is a third-party OpenAPI file assembled from observed behaviour. `npm-registry-couchapp` was the last publicly readable server and GitHub archived it on 11 August 2021, with a deprecation notice that names the internal micro-services now serving the API. Verdaccio and cnpm implement a compatible API by matching observed behaviour, a weakness in an ecosystem with five clients in npm, yarn, pnpm, bun and Deno. Maven publishes the repository layout and the POM reference, with `maven-metadata.xml` defined by the Repository Metadata Model, so the storage format is specified. What stays de facto is the resolver’s conflict and ordering behaviour, defined by what `ComparableVersion` and the resolver in maven-artifact compute. The Gradle team derived those semantics from observed behaviour and then shipped Gradle Module Metadata alongside the POM as its own specification. Sonatype has operated Maven Central since 2008, GitHub operates npm, and each publishes what it chooses to document. ecosyste.ms maintains OpenAPI schemas for more than 25 registry APIs. Two of those registries publish an official schema themselves, crates.io and open-vsx.org, and the rest are generated from the mapping code in packages.ecosyste.ms. ### Versioning Every ecosystem has its own versioning rules, and version comparison is the least settled part of the whole business. Semantic Versioning 2.0.0 is a self-published document on semver.org by Tom Preston-Werner under CC BY 3.0, and its one IETF reference is RFC 2119, cited for MUST and SHOULD. It specifies version syntax and precedence only, so range syntax comes from each client: node-semver’s README is the operative document for npm, Cargo’s caret default is in the Cargo book, Ruby’s `~>` is in the RubyGems documentation, and Python’s are in PEP 440 and PEP 508. Ordering rules split the same way: Debian Policy section 5.6.12 gives the comparison algorithm for epoch, `upstream_version` and `debian_revision` in the policy text itself, PEP 440 does the same for Python, and Go’s pseudo-versions and `+incompatible` suffix are described in the module reference. RPM’s ordering is `rpmvercmp` inside librpm and Maven’s is `ComparableVersion` in maven-artifact, with the implementation as the reference in both cases. `univers` exists because of that spread: one library that reimplements every ecosystem’s comparison rules behind a single interface. The cross-ecosystem attempt is `vers`, from the purl project, which defines a URI syntax for version ranges together with the semantics for interpreting each notation, so an npm caret range comes out as `vers:npm/>=1.0.2|<2.0.0`. It was developed alongside purl and is due to be proposed to Ecma later in 2026, which would put ranges in the same venue as identifiers and lifecycle events. Ecma would then hold the identifier, the bill of materials, the lifecycle record and the version range, four of the pieces that have to mean the same thing in every ecosystem, within three years of TC54’s founding, while the protocol layer remains inside the ecosystems and with the registry operators.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 05/10/2026
New hobby: trying to make deterministic versions of llm powered dependency analysis tools using the various parts of git-pkgs. Normally can get 90% of the way that and it ends up being much faster and cheaper.
001 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 04/10/2026
It's an older example, but it checks out: github.com/PogiNate/A.K.A.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 04/10/2026
TIL you can end your github repo names with a dot, so the git clone url is github.com/andrew/foo..git 🙈
121 2
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 04/10/2026
It's Sunday evening, do you know which user agents your residential proxy scraper farms are using today?
302 3
Reposted by Andrew Nesbitt
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 03/10/2026
This Week in Package Management: 3 October 2026 nesbitt.io/2026/10/03/this-week-in-…
nesbitt.io
This Week in Package Management: 3 October 2026
Week twenty of the roundup, built from the package manager OPML feed collection and whatever I’ve posted or boosted on Mastodon. ## Releases mise 2026.10.0 requires keyless cosign bundles to match a pinned signer identity and stops GitHub attestation workflow checks accepting partial matches. 2026.9.18 added an `include` key that lets `mise.toml` pull a shared config fragment from a git repository or OCI registry, limited to tools, env, vars, hooks and aliases, with paranoid mode requiring a full commit sha or OCI digest. npm 12.2.0 accepts OIDC authentication for `npm dist-tag`, previously token-only. On the registry side, trusted publishing configurations now have an opt-in dist-tag permission, off by default, so a workflow can manage `latest`, `next` and similar tags without a long-lived token. pnpm 12.9 adds a per-registry `networkConcurrency` setting, records every installed project in the store, and stops `pnpm login` forwarding credentials in the request body to another origin on redirect. 12.8 warns when `pnpm pack` or `pnpm publish` would put a `.env` file in the tarball. RubyGems 4.0.22 keeps credentials on redirects only within the same origin. It also validates the `version` field in `Gem::Installer#verify_spec` and adds a `--source` option to `gem exec`. OpenTofu 1.13.0 ships official Windows on ARM64 packages and adds functions that reduce unknown values during planning by letting module authors assert facts beyond what OpenTofu infers. Two experiments ship with it: built-in linting, and “symbol libraries”, a reusable collection of values, functions and type aliases importable from the same sources as modules. This is the last series with 32 bit CPU releases, and it drops the WinRM provisioner. Scoop 0.6.0 searches the bucket’s git history for a versioned manifest when installing `app@version`, and auto-generates one from `autoupdate` only if that search fails. `checkver` GitHub mode now needs an explicit `github:` key to opt into the GitHub token path, the GitHub `checkver` defaults for `jsonpath` and `regex` have changed, and new installs write `scoop-install.json` and `scoop-manifest.json`, so an app’s own `install.json` and `manifest.json` are preserved. Conan 2.33.0 supports CPS component configurations and takes CPEs for a component through `extra_info`. A new `core.net.http:trust_store` conf verifies HTTPS certificates against the OS trust store, remotes accept a `force_auth` capability, and recipe and package metadata now download in parallel with regular files, where they previously downloaded afterwards. Python 3.7 support is removed. Git 2.56.0 adds `create`, `delete`, `update` and `rename` subcommands to `git refs`, and a `promisor.acceptFromServerURL` setting that governs whether the other side may add to the list of promisor remotes. The experimental `git history` command adds a `drop` subcommand, which removes a commit and replays its descendants onto the parent. Rust 1.99.0 ships Cargo 0.100.0, which disables incremental compilation by default when the `CI` environment variable is set and adds a built-in `debug` profile ahead of moving the `dev` profile toward faster iteration defaults. conda 26.9.0 schedules implicit installation of pip alongside Python for deprecation. It stays enabled in this release and becomes deprecated in 27.3; `add_pip_as_python_dependency` defaults to false from 27.9. Environments that need pip should request it explicitly. Zig 0.17.0 moves package management out of the compiler and into the build system, so `zig fetch` and the HTTP, TLS and git protocol code it uses now compile in safe mode. `zig fetch` writes to the global cache only unless `--save` is passed, `--pkg-path` and `ZIG_LOCAL_PKG_DIR` override where packages are read from, and path dependencies that escape the parent package root are rejected. Also out: * Homebrew 7.0.7 * pipx 1.17.10 * uv 0.12.22 * pnpm 11.28.3 * Athens 0.19.2 * Cabal 3.18.2.0 * Pkg.jl 1.13.1 * Maven 3.10.0 * sbt 2.0.10 and 2.1.0-M3 * Elm 0.19.3-beta * Terraform 1.16.5 * OpenTofu 1.12.7 * Docker Engine 29.9.0-rc.1 * Renovate 44.132.2 * Dependabot Core 0.398.0 ## Security LuaRocks.org published an incident report for a remote code execution in its rockspec parser. The parser called `loadstring` without restricting input to text mode, so an attacker could upload precompiled bytecode as a rockspec and escape the sandbox. The vulnerability was exploited between 9 July and 20 August, three malicious packages were uploaded on 7 August, and usernames, email addresses, bcrypt password hashes, API keys, 2FA secrets and GitHub linking tokens were exposed. LuaRocks.org has moved to new infrastructure, revoked all API keys and sessions, and removed the three packages. There is no evidence existing packages were modified. Flatpak 1.18.4 fixes six CVEs, each of which requires an already-installed malicious app. 1.19.2 includes the same fixes on the development branch. * CVE-2026-97023, privileged deletion of arbitrary files * CVE-2026-97024, privileged overwrite of arbitrary files with an empty file or a symlink to `/run/host/monitor/resolv.conf` * CVE-2026-97025, an authentication token exposed to other users when downloading from an OCI repository that requires authentication * CVE-2026-97026, loose permissions on temporary repository directories under `/var/tmp/flatpak-cache-*` * CVE-2026-97027, `.desktop` and D-Bus `.service` files now filtered against an allowlist of fields to stop denial of service and unintended interactions with host services * CVE-2026-97029, signals sent to a process group that includes a parent outside the app, which kills the desktop environment Podman 6.1.3 and 5.8.8 fix CVE-2026-94603, where `podman run` on a checkpoint image, meaning any image carrying the `io.podman.annotations.checkpoint.runtime.name` annotation, could disable all sandboxing, including the sandboxing the user specified. Both releases remove support for running checkpoint images, on the grounds that checkpoints override user-specified security configuration and are difficult to run safely. Moby 25.0.18 backports the fix for CVE-2026-17106, where the tar extraction routines in `moby/go-archive` allowed filesystem operations outside the destination directory, so anyone controlling an archive’s contents could write to arbitrary paths. Docker Engine 29.7.0 and Docker Desktop 4.86.0 include the same fix. CVE-2026-92543, fixed in Docker Engine 29.8.2, let a DNS response that paired a loopback address with an attacker-controlled address make the engine treat a registry as insecure. The insecure-registry check matched on the loopback entry while the transport layer re-dialled the hostname, so pulls reached the attacker’s server with certificate verification disabled. Digest pinning or signature verification blocks it. Python released 3.14.8, 3.13.16, 3.12.15, 3.11.17 and 3.10.22 with fixes for eight CVEs across tarfile, zipfile, SSL and urllib. 3.10.22 is the final 3.10 release. uv 0.12.22 bundles the new interpreters. Renovate published four advisories: a critical `allowedEnv` bypass and a high `allowedHeaders` bypass, both via shared presets, a high SSRF through HTTP preset URLs in `extends` or `customDatasources`, and a moderate `minimumReleaseAge` bypass when a user requests a PR rebase. All four are fixed by 44.79.0, with no backports to earlier majors. The mise releases above also close a trust bypass, where a `mise.toml` in an untrusted directory could put options inside a tool key, such as a `github:` key with `[api_url=...]` pointing at another host. mise treated the value as a plain version string, so it loaded the file before any trust check, and `mise ls`, `env`, `current`, `outdated`, `upgrade --dry-run` and `latest` then sent `GITHUB_TOKEN` to that host. Any tool key containing `[` now requires trust, and 2026.10.0 extends the same requirement to inline options in `.tool-versions`. ## Articles 15 years of Packagist counts from monolog/monolog becoming package ID 1 on 27 September 2011. Packagist now lists over 469,000 packages across 5.8 million versions, and installs have passed 201.6 billion, with more than 36 billion in 2026 so far, ahead of the 2025 total. It ran on a single personal server with 100 Mbps until April 2015, and served around 67 million installs a month by the move to AWS. One version per process (Sebastian Bergmann) works through what PHP’s one-definition-per-name rule does to Composer: every dependency resolves to a single version, and whoever introduced a conflict has to resolve it. Bergmann argues that is why PHP dependency lists stay short and version ranges stay wide. PHPUnit’s PHAR works around the rule with php-scoper, which renames bundled namespaces so `SebastianBergmann\Exporter` becomes `PHPUnitPHAR\SebastianBergmann\Exporter`. Don’t couple your Go code to GitHub (Iain Cambridge) argues for vanity module paths over `github.com/...` imports. A domain the author controls serves a `go-import` meta tag pointing at the current host, so moving the repository changes one meta tag instead of every consumer’s import statements. The example configures nginx to redirect browsers to GitHub while serving the meta tag to the Go toolchain. Git 3.0’s upcoming SHA-256 default will be a costly mistake (Scott Chacon, GitButler) argues against making SHA-256 the default object hash in Git 3.0, on the grounds that real attacks exploit distribution and social engineering rather than hash collisions. Chacon proposes signed tree-content hash headers alongside commits as an opt-in alternative that adds collision resistance and leaves the Git object format unchanged for everyone else. Seth Larson published more than ten posts from the Python Language Summit 2026, held at EuroPython in Kraków. The namespaces session is the one for packaging readers: Pablo Galindo Salgado proposed a `std` namespace for the standard library, so `import std.json` would work while `import json` keeps working indefinitely. Part of the motivation is that new stdlib module names must differ from names already taken on PyPI. `tomllib`, `graphlib` and `zoneinfo` were named that way for this reason. The session left open whether new modules should be reachable only under `std`. ## Papers Fighting Supply Chain Attacks with Effect Systems (Magnus Madsen et al., PACMPL) extends the Flix compiler with an effect-aware package manager and effect lock files, where an upgrade is accepted only if its inferred effects are a subset of the locked set. Evaluated against 51 real supply chain attacks from the Backstabbers Knife Collection, 48 would have been blocked. A Comprehensive Empirical Analysis of Patch Presence Testing (Xiaobei Zhang et al., PACMSE) builds a 561-CVE benchmark across ten C/C++ projects and runs five patch-presence tools against it. Accuracy figures in prior work count only the cases where a tool produced a result, and in practice the tools frequently fail to produce one. ## Elsewhere The PHP Foundation opened applications for 2027 contractor positions across its core development areas. The form closes on 20 October 2026. I’ll be at Open Source Summit Europe and OpenSSF Community Day in Prague, as will Renovate maintainers Sebastian Poxhofer and Jamie Tanna. GitHub added per-user daily rate limits on private vulnerability reports, with a repository-level trusted-reporter allowlist, and structured report forms configured through `.github/VULNERABILITY_REPORT.yml` using issue-form syntax. ## git-pkgs I tagged 18 repos this week: * git-pkgs v0.21.0 * codemeta v0.3.0 (new), a zero-dependency Go library for parsing `codemeta.json` and validating software metadata, which preserves source positions, unknown fields and numeric spelling * peek v0.1.0 (new), which extracts explicit claims such as an `SPDX-License-Identifier` line from files and from bounded file prefixes, including the roughly 1 KB prefixes in Software Heritage exports * archives v0.8.1 * brief v0.14.0 * clone v0.7.5 * enrichment v0.7.2 * forge v0.10.1 * licenses v0.9.0 * magic v0.5.0 * manifests v0.12.3 * outline v0.2.3 * proxy v0.9.0 * registries v0.9.3 * roles v0.1.3 * sarif v0.1.3 * scan v0.1.1 * vers v0.7.2 Send links for next week to @[email protected].
001 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 03/10/2026
This Week in Package Management: 3 October 2026 nesbitt.io/2026/10/03/this-week-in-…
nesbitt.io
This Week in Package Management: 3 October 2026
Week twenty of the roundup, built from the package manager OPML feed collection and whatever I’ve posted or boosted on Mastodon. ## Releases mise 2026.10.0 requires keyless cosign bundles to match a pinned signer identity and stops GitHub attestation workflow checks accepting partial matches. 2026.9.18 added an `include` key that lets `mise.toml` pull a shared config fragment from a git repository or OCI registry, limited to tools, env, vars, hooks and aliases, with paranoid mode requiring a full commit sha or OCI digest. npm 12.2.0 accepts OIDC authentication for `npm dist-tag`, previously token-only. On the registry side, trusted publishing configurations now have an opt-in dist-tag permission, off by default, so a workflow can manage `latest`, `next` and similar tags without a long-lived token. pnpm 12.9 adds a per-registry `networkConcurrency` setting, records every installed project in the store, and stops `pnpm login` forwarding credentials in the request body to another origin on redirect. 12.8 warns when `pnpm pack` or `pnpm publish` would put a `.env` file in the tarball. RubyGems 4.0.22 keeps credentials on redirects only within the same origin. It also validates the `version` field in `Gem::Installer#verify_spec` and adds a `--source` option to `gem exec`. OpenTofu 1.13.0 ships official Windows on ARM64 packages and adds functions that reduce unknown values during planning by letting module authors assert facts beyond what OpenTofu infers. Two experiments ship with it: built-in linting, and “symbol libraries”, a reusable collection of values, functions and type aliases importable from the same sources as modules. This is the last series with 32 bit CPU releases, and it drops the WinRM provisioner. Scoop 0.6.0 searches the bucket’s git history for a versioned manifest when installing `app@version`, and auto-generates one from `autoupdate` only if that search fails. `checkver` GitHub mode now needs an explicit `github:` key to opt into the GitHub token path, the GitHub `checkver` defaults for `jsonpath` and `regex` have changed, and new installs write `scoop-install.json` and `scoop-manifest.json`, so an app’s own `install.json` and `manifest.json` are preserved. Conan 2.33.0 supports CPS component configurations and takes CPEs for a component through `extra_info`. A new `core.net.http:trust_store` conf verifies HTTPS certificates against the OS trust store, remotes accept a `force_auth` capability, and recipe and package metadata now download in parallel with regular files, where they previously downloaded afterwards. Python 3.7 support is removed. Git 2.56.0 adds `create`, `delete`, `update` and `rename` subcommands to `git refs`, and a `promisor.acceptFromServerURL` setting that governs whether the other side may add to the list of promisor remotes. The experimental `git history` command adds a `drop` subcommand, which removes a commit and replays its descendants onto the parent. Rust 1.99.0 ships Cargo 0.100.0, which disables incremental compilation by default when the `CI` environment variable is set and adds a built-in `debug` profile ahead of moving the `dev` profile toward faster iteration defaults. conda 26.9.0 schedules implicit installation of pip alongside Python for deprecation. It stays enabled in this release and becomes deprecated in 27.3; `add_pip_as_python_dependency` defaults to false from 27.9. Environments that need pip should request it explicitly. Zig 0.17.0 moves package management out of the compiler and into the build system, so `zig fetch` and the HTTP, TLS and git protocol code it uses now compile in safe mode. `zig fetch` writes to the global cache only unless `--save` is passed, `--pkg-path` and `ZIG_LOCAL_PKG_DIR` override where packages are read from, and path dependencies that escape the parent package root are rejected. Also out: * Homebrew 7.0.7 * pipx 1.17.10 * uv 0.12.22 * pnpm 11.28.3 * Athens 0.19.2 * Cabal 3.18.2.0 * Pkg.jl 1.13.1 * Maven 3.10.0 * sbt 2.0.10 and 2.1.0-M3 * Elm 0.19.3-beta * Terraform 1.16.5 * OpenTofu 1.12.7 * Docker Engine 29.9.0-rc.1 * Renovate 44.132.2 * Dependabot Core 0.398.0 ## Security LuaRocks.org published an incident report for a remote code execution in its rockspec parser. The parser called `loadstring` without restricting input to text mode, so an attacker could upload precompiled bytecode as a rockspec and escape the sandbox. The vulnerability was exploited between 9 July and 20 August, three malicious packages were uploaded on 7 August, and usernames, email addresses, bcrypt password hashes, API keys, 2FA secrets and GitHub linking tokens were exposed. LuaRocks.org has moved to new infrastructure, revoked all API keys and sessions, and removed the three packages. There is no evidence existing packages were modified. Flatpak 1.18.4 fixes six CVEs, each of which requires an already-installed malicious app. 1.19.2 includes the same fixes on the development branch. * CVE-2026-97023, privileged deletion of arbitrary files * CVE-2026-97024, privileged overwrite of arbitrary files with an empty file or a symlink to `/run/host/monitor/resolv.conf` * CVE-2026-97025, an authentication token exposed to other users when downloading from an OCI repository that requires authentication * CVE-2026-97026, loose permissions on temporary repository directories under `/var/tmp/flatpak-cache-*` * CVE-2026-97027, `.desktop` and D-Bus `.service` files now filtered against an allowlist of fields to stop denial of service and unintended interactions with host services * CVE-2026-97029, signals sent to a process group that includes a parent outside the app, which kills the desktop environment Podman 6.1.3 and 5.8.8 fix CVE-2026-94603, where `podman run` on a checkpoint image, meaning any image carrying the `io.podman.annotations.checkpoint.runtime.name` annotation, could disable all sandboxing, including the sandboxing the user specified. Both releases remove support for running checkpoint images, on the grounds that checkpoints override user-specified security configuration and are difficult to run safely. Moby 25.0.18 backports the fix for CVE-2026-17106, where the tar extraction routines in `moby/go-archive` allowed filesystem operations outside the destination directory, so anyone controlling an archive’s contents could write to arbitrary paths. Docker Engine 29.7.0 and Docker Desktop 4.86.0 include the same fix. CVE-2026-92543, fixed in Docker Engine 29.8.2, let a DNS response that paired a loopback address with an attacker-controlled address make the engine treat a registry as insecure. The insecure-registry check matched on the loopback entry while the transport layer re-dialled the hostname, so pulls reached the attacker’s server with certificate verification disabled. Digest pinning or signature verification blocks it. Python released 3.14.8, 3.13.16, 3.12.15, 3.11.17 and 3.10.22 with fixes for eight CVEs across tarfile, zipfile, SSL and urllib. 3.10.22 is the final 3.10 release. uv 0.12.22 bundles the new interpreters. Renovate published four advisories: a critical `allowedEnv` bypass and a high `allowedHeaders` bypass, both via shared presets, a high SSRF through HTTP preset URLs in `extends` or `customDatasources`, and a moderate `minimumReleaseAge` bypass when a user requests a PR rebase. All four are fixed by 44.79.0, with no backports to earlier majors. The mise releases above also close a trust bypass, where a `mise.toml` in an untrusted directory could put options inside a tool key, such as a `github:` key with `[api_url=...]` pointing at another host. mise treated the value as a plain version string, so it loaded the file before any trust check, and `mise ls`, `env`, `current`, `outdated`, `upgrade --dry-run` and `latest` then sent `GITHUB_TOKEN` to that host. Any tool key containing `[` now requires trust, and 2026.10.0 extends the same requirement to inline options in `.tool-versions`. ## Articles 15 years of Packagist counts from monolog/monolog becoming package ID 1 on 27 September 2011. Packagist now lists over 469,000 packages across 5.8 million versions, and installs have passed 201.6 billion, with more than 36 billion in 2026 so far, ahead of the 2025 total. It ran on a single personal server with 100 Mbps until April 2015, and served around 67 million installs a month by the move to AWS. One version per process (Sebastian Bergmann) works through what PHP’s one-definition-per-name rule does to Composer: every dependency resolves to a single version, and whoever introduced a conflict has to resolve it. Bergmann argues that is why PHP dependency lists stay short and version ranges stay wide. PHPUnit’s PHAR works around the rule with php-scoper, which renames bundled namespaces so `SebastianBergmann\Exporter` becomes `PHPUnitPHAR\SebastianBergmann\Exporter`. Don’t couple your Go code to GitHub (Iain Cambridge) argues for vanity module paths over `github.com/...` imports. A domain the author controls serves a `go-import` meta tag pointing at the current host, so moving the repository changes one meta tag instead of every consumer’s import statements. The example configures nginx to redirect browsers to GitHub while serving the meta tag to the Go toolchain. Git 3.0’s upcoming SHA-256 default will be a costly mistake (Scott Chacon, GitButler) argues against making SHA-256 the default object hash in Git 3.0, on the grounds that real attacks exploit distribution and social engineering rather than hash collisions. Chacon proposes signed tree-content hash headers alongside commits as an opt-in alternative that adds collision resistance and leaves the Git object format unchanged for everyone else. Seth Larson published more than ten posts from the Python Language Summit 2026, held at EuroPython in Kraków. The namespaces session is the one for packaging readers: Pablo Galindo Salgado proposed a `std` namespace for the standard library, so `import std.json` would work while `import json` keeps working indefinitely. Part of the motivation is that new stdlib module names must differ from names already taken on PyPI. `tomllib`, `graphlib` and `zoneinfo` were named that way for this reason. The session left open whether new modules should be reachable only under `std`. ## Papers Fighting Supply Chain Attacks with Effect Systems (Magnus Madsen et al., PACMPL) extends the Flix compiler with an effect-aware package manager and effect lock files, where an upgrade is accepted only if its inferred effects are a subset of the locked set. Evaluated against 51 real supply chain attacks from the Backstabbers Knife Collection, 48 would have been blocked. A Comprehensive Empirical Analysis of Patch Presence Testing (Xiaobei Zhang et al., PACMSE) builds a 561-CVE benchmark across ten C/C++ projects and runs five patch-presence tools against it. Accuracy figures in prior work count only the cases where a tool produced a result, and in practice the tools frequently fail to produce one. ## Elsewhere The PHP Foundation opened applications for 2027 contractor positions across its core development areas. The form closes on 20 October 2026. I’ll be at Open Source Summit Europe and OpenSSF Community Day in Prague, as will Renovate maintainers Sebastian Poxhofer and Jamie Tanna. GitHub added per-user daily rate limits on private vulnerability reports, with a repository-level trusted-reporter allowlist, and structured report forms configured through `.github/VULNERABILITY_REPORT.yml` using issue-form syntax. ## git-pkgs I tagged 18 repos this week: * git-pkgs v0.21.0 * codemeta v0.3.0 (new), a zero-dependency Go library for parsing `codemeta.json` and validating software metadata, which preserves source positions, unknown fields and numeric spelling * peek v0.1.0 (new), which extracts explicit claims such as an `SPDX-License-Identifier` line from files and from bounded file prefixes, including the roughly 1 KB prefixes in Software Heritage exports * archives v0.8.1 * brief v0.14.0 * clone v0.7.5 * enrichment v0.7.2 * forge v0.10.1 * licenses v0.9.0 * magic v0.5.0 * manifests v0.12.3 * outline v0.2.3 * proxy v0.9.0 * registries v0.9.3 * roles v0.1.3 * sarif v0.1.3 * scan v0.1.1 * vers v0.7.2 Send links for next week to @[email protected].
001 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 02/10/2026
As far as I can tell, the main drivers are the cooldown feature and it being small, lightweight and fast, often put in front of other bigger package caches. I mostly started that project as a way to have some registry APIs to test against without smashing the real ones.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 02/10/2026
Seems like quite a lot of people starting to use github.com/git-pkgs/proxy daily feature requests and PRs coming in now.
github.com
GitHub - git-pkgs/proxy: A lightweight caching proxy for package registries.
A lightweight caching proxy for package registries. - git-pkgs/proxy
101 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 02/10/2026
git-pkgs v0.21.0 is out: fail CI on high/critical vulnerabilities with --fail-on high, get changelogs starting at your installed version, and see every dependency occurrence in outdated reports. Plus fixes for vulnerability reports across branches […]
mastodon.social
Original post on mastodon.social
000 0
Reposted by Andrew Nesbitt
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 01/10/2026
Software Heritage Identifiers nesbitt.io/2026/10/01/software-heri…
nesbitt.io
Software Heritage Identifiers
I spent Monday at the Software Heritage offices in Paris speaking at the CodeCommons plenary, and the slides are on GitHub. The talk was about connecting package identities to archived source code. Getting ready for it meant a couple of weeks poking at the SWH archive and its identifier scheme with a to-do list that kept growing, and I’ve ended up with a small pile of tools that are now feeding into ecosyste.ms, starting with the research software service. ### Software Heritage Software Heritage has been building a universal archive of source code since Inria launched the project in 2016. It crawls GitHub, GitLab, Bitbucket and a long tail of smaller forges, plus package registries and distro sources, and stores what it finds in one deduplicated Merkle DAG. As I write this that DAG holds about 30 billion source files, 23 billion directories and 6 billion commits from 445 million origins. A file that turns up in both an npm tarball and a Debian source package is stored once, addressed by the hash of its bytes, and the graph records every place it was seen. The Vault reconstructs any snapshot, commit or directory on request as a git bundle or tarball you can download, so retrieval is by content rather than by whichever URL the code was hosted at. ### SWHIDs Every object in the archive has a SoftWare Hash IDentifier of the form `swh:1:<type>:<sha1>`. The five types are `cnt` for a file’s bytes, `dir` for a directory tree, `rev` for a commit, `rel` for a tag and `snp` for a snapshot of a repository’s refs at one point in time. Optional qualifiers after a semicolon pin an origin URL, a visit, a path inside a directory or a line range inside a file. Version 1.2 of the spec was published as ISO/IEC 18670 last year, the first ISO standard for intrinsic software identifiers. A SWHID is intrinsic, computed from the bytes with no registry and no issuing authority, and because the hashes are git’s own object hashes any git checkout on your disk is already full of valid SWHIDs whether or not Software Heritage has crawled it yet. A purl like `pkg:pypi/[email protected]` is at a different corner of Zooko’s triangle: a human can read it and it’s unique within PyPI’s namespace, but resolving it to actual bytes depends on PyPI still being there to serve that release. I spend a lot of time in ecosyste.ms holding both kinds of identifier for the same software, and that mapping was the subject of the CodeCommons talk. ### swh-git The most direct way I’ve found to get code back out is swh-git, a git remote helper that adds an `swh::` transport. With `git-remote-swh` on your `PATH` you can clone by origin URL or by SWHID: git clone swh::github.com/octocat/Hello-World git clone swh::swh:1:snp:f72e9d06dd0e58236a34328f094ca894a809f230 The first form resolves to the origin’s most recent archived snapshot, and the second pins a specific one and produces the same bytes on every run. Behind the transport, the helper requests a git-bare bundle from the Vault, polls while it’s prepared (which can take several minutes for a large repository the first time), downloads it into your user cache directory, and serves the clone from there with `git upload-pack`. Fetch, `ls-remote` and shallow clones all work against the cached bundle, and push is refused since the archive is append-only from the crawler side. There’s also an HTTP proxy mode for tooling that expects a plain URL rather than a custom transport, so `git clone http://127.0.0.1:8080/github.com/octocat/Hello-World.git` does the same thing through `git http-backend`. I built this for the recovery case, where an origin URL now 404s or the forge it was on has shut down, and `git clone swh::<the old url>` gets you back to a working repository with full history and tags. The helper also accepts `rev`, `rel` and `dir` identifiers, so a directory SWHID from a paper citation or an SBOM component becomes a checkout in the same way. ### Computing SWHIDs Since a SWHID is derived from content, you can compute one anywhere you have the bytes, and I wanted that in the two languages I use most. The swhid gem covers Ruby with parsing, qualifiers and generation for all five object types, and it’s what the ecosyste.ms services use. swhid-go does the same in Go with a CLI on top and SHA-1 collision detection built in. Both are wired into the upstream conformance test suite that the SWHID working group maintains, so they’re checked against the reference vectors alongside the Python and Rust implementations. Compiling swhid-go to WebAssembly gives you swhid-wasm, a browser page that fetches a package by name from npm, PyPI, crates.io, RubyGems or pub.dev, or takes a local archive you drop onto it, then unpacks and hashes the whole tree client-side. You get content and directory SWHIDs for every file, executable bits, symlinks and duplicate detection, and the package bytes stay on your machine. Once the tree is hashed the page batch-posts the identifiers to the archive’s `/api/1/known/` endpoint to colour in which ones are already preserved, and there’s a button to submit the package’s public URL to Software Heritage for archival. Early builds of the wasm page needed a same-origin relay for that lookup, because the browser’s CORS preflight for a JSON `POST` was reaching the Anubis bot-protection layer in front of the archive and getting an HTML challenge back instead of CORS headers. I reported it and the SWH team have since adjusted the Anubis configuration so preflights pass through, and the page can now call the archive directly, though by that point the identifiers are already computed and the lookup itself is optional. ### Web API All of the above ends up calling `archive.softwareheritage.org/api/1`, which SWH document thoroughly in prose. There’s no machine-readable spec yet, though it’s something the team are interested in, so swh-openapi is my stopgap, generating an OpenAPI description from the same docstring data the published reference is built from. swh-go is a Go client generated from that with pagination, auth and rate-limit handling written by hand, and both should be retired once there’s an official spec. ### Critical package coverage With a client in hand I ran a coverage check, swh-critical, over the roughly 9,800 packages in the packages.ecosyste.ms critical set and their 7,000-odd source repositories on 23 and 24 September. Of those repositories, 71.3% had their current default-branch commit already in the archive, and 89.9% of matched release tags were present as revisions. Among the repositories whose current commit was missing, 95.1% still had an older snapshot once I checked the former URLs ecosyste.ms records across renames as well as the current one. The 46 hardest cases in the audit had no snapshot at any URL I tried and no matching release objects either, and drilling into those with full clones and tree hashes from the published package tarballs still turned up archived content for every one. Across the whole audit the pattern was older history already in the archive with only recent commits missing. I think ecosyste.ms can be most useful to Software Heritage as a partner on that last part, since the archive tracks over 445 million origins, far more than the crawler can revisit at a uniform cadence, while ecosyste.ms has dependent counts, download numbers and a criticality score for each package that give a decent signal for which repositories matter most to keep fresh. Feeding that back as a ranked stream of Save Code Now requests means the crawler’s next visit goes to the source of something with a hundred thousand dependents rather than an abandoned fork. ### science.ecosyste.ms The first place that feedback loop is running in production is science.ecosyste.ms, the ecosyste.ms service that tracks research software. For each project with a high enough science score, a background job clones the repository, computes revision and directory SWHIDs with the Ruby gem, and posts them in batches to `/api/1/known/`. Projects with objects missing from the archive get their origin submitted through Save Code Now, another job polls the visit until it completes, and any SWHID newly known after our request is recorded as a confirmed contribution. The stats page rolls those up every six hours with a JSON API alongside, and individual project pages now show SWHIDs next to the DOIs and citation metadata they already had. Research software was the right place to start because that community already cares about persistent identifiers and long-term reproducibility. ### packages.ecosyste.ms The next step is doing the same for package versions on packages.ecosyste.ms, which means computing directory SWHIDs for published tarballs as well as git checkouts and storing the purl-to-SWHID mapping as a first-class field. At that point an SBOM component like `pkg:npm/[email protected]` resolves through ecosyste.ms to a `swh:1:dir:` you can verify against the tarball you downloaded and fetch from the archive independently of npm. It also turns the one-off swh-critical audit into a rolling measurement, with coverage tracked per registry and new gaps fed back through the same Save Code Now route. ### Scanning the archive The scanners I’ve been building under git-pkgs can also treat the archive as a corpus rather than a backup, since they already run against any checkout. manifests parses package-manager manifest and lockfiles across ecosystems, licenses does fast SPDX detection against the ScanCode rule corpus, and brief reports a project’s whole toolchain and conventions as structured JSON. With swh-git in front of them the checkout comes from the archive by SWHID instead of a live forge, and any of their outputs anchored to a `swh:1:rev:` is reproducible by anyone with the same identifier. Longer term I’d like to try running these against the SWH graph dataset export directly rather than one Vault checkout at a time, which would make questions about lockfile adoption or license drift across whole registries answerable from preserved source rather than whatever happens to still be online. Software Heritage has already built the archive and standardised the identifier; what I’ve been doing is plumbing to reach it from the package-management side and to point ecosyste.ms data at the repositories where another crawl would help most. All of it is MIT or Apache-2.0 licensed, and I’d be very happy to see any of it picked up or replaced by something better.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 01/10/2026
Software Heritage Identifiers nesbitt.io/2026/10/01/software-heri…
nesbitt.io
Software Heritage Identifiers
I spent Monday at the Software Heritage offices in Paris speaking at the CodeCommons plenary, and the slides are on GitHub. The talk was about connecting package identities to archived source code. Getting ready for it meant a couple of weeks poking at the SWH archive and its identifier scheme with a to-do list that kept growing, and I’ve ended up with a small pile of tools that are now feeding into ecosyste.ms, starting with the research software service. ### Software Heritage Software Heritage has been building a universal archive of source code since Inria launched the project in 2016. It crawls GitHub, GitLab, Bitbucket and a long tail of smaller forges, plus package registries and distro sources, and stores what it finds in one deduplicated Merkle DAG. As I write this that DAG holds about 30 billion source files, 23 billion directories and 6 billion commits from 445 million origins. A file that turns up in both an npm tarball and a Debian source package is stored once, addressed by the hash of its bytes, and the graph records every place it was seen. The Vault reconstructs any snapshot, commit or directory on request as a git bundle or tarball you can download, so retrieval is by content rather than by whichever URL the code was hosted at. ### SWHIDs Every object in the archive has a SoftWare Hash IDentifier of the form `swh:1:<type>:<sha1>`. The five types are `cnt` for a file’s bytes, `dir` for a directory tree, `rev` for a commit, `rel` for a tag and `snp` for a snapshot of a repository’s refs at one point in time. Optional qualifiers after a semicolon pin an origin URL, a visit, a path inside a directory or a line range inside a file. Version 1.2 of the spec was published as ISO/IEC 18670 last year, the first ISO standard for intrinsic software identifiers. A SWHID is intrinsic, computed from the bytes with no registry and no issuing authority, and because the hashes are git’s own object hashes any git checkout on your disk is already full of valid SWHIDs whether or not Software Heritage has crawled it yet. A purl like `pkg:pypi/[email protected]` is at a different corner of Zooko’s triangle: a human can read it and it’s unique within PyPI’s namespace, but resolving it to actual bytes depends on PyPI still being there to serve that release. I spend a lot of time in ecosyste.ms holding both kinds of identifier for the same software, and that mapping was the subject of the CodeCommons talk. ### swh-git The most direct way I’ve found to get code back out is swh-git, a git remote helper that adds an `swh::` transport. With `git-remote-swh` on your `PATH` you can clone by origin URL or by SWHID: git clone swh::github.com/octocat/Hello-World git clone swh::swh:1:snp:f72e9d06dd0e58236a34328f094ca894a809f230 The first form resolves to the origin’s most recent archived snapshot, and the second pins a specific one and produces the same bytes on every run. Behind the transport, the helper requests a git-bare bundle from the Vault, polls while it’s prepared (which can take several minutes for a large repository the first time), downloads it into your user cache directory, and serves the clone from there with `git upload-pack`. Fetch, `ls-remote` and shallow clones all work against the cached bundle, and push is refused since the archive is append-only from the crawler side. There’s also an HTTP proxy mode for tooling that expects a plain URL rather than a custom transport, so `git clone http://127.0.0.1:8080/github.com/octocat/Hello-World.git` does the same thing through `git http-backend`. I built this for the recovery case, where an origin URL now 404s or the forge it was on has shut down, and `git clone swh::<the old url>` gets you back to a working repository with full history and tags. The helper also accepts `rev`, `rel` and `dir` identifiers, so a directory SWHID from a paper citation or an SBOM component becomes a checkout in the same way. ### Computing SWHIDs Since a SWHID is derived from content, you can compute one anywhere you have the bytes, and I wanted that in the two languages I use most. The swhid gem covers Ruby with parsing, qualifiers and generation for all five object types, and it’s what the ecosyste.ms services use. swhid-go does the same in Go with a CLI on top and SHA-1 collision detection built in. Both are wired into the upstream conformance test suite that the SWHID working group maintains, so they’re checked against the reference vectors alongside the Python and Rust implementations. Compiling swhid-go to WebAssembly gives you swhid-wasm, a browser page that fetches a package by name from npm, PyPI, crates.io, RubyGems or pub.dev, or takes a local archive you drop onto it, then unpacks and hashes the whole tree client-side. You get content and directory SWHIDs for every file, executable bits, symlinks and duplicate detection, and the package bytes stay on your machine. Once the tree is hashed the page batch-posts the identifiers to the archive’s `/api/1/known/` endpoint to colour in which ones are already preserved, and there’s a button to submit the package’s public URL to Software Heritage for archival. Early builds of the wasm page needed a same-origin relay for that lookup, because the browser’s CORS preflight for a JSON `POST` was reaching the Anubis bot-protection layer in front of the archive and getting an HTML challenge back instead of CORS headers. I reported it and the SWH team have since adjusted the Anubis configuration so preflights pass through, and the page can now call the archive directly, though by that point the identifiers are already computed and the lookup itself is optional. ### Web API All of the above ends up calling `archive.softwareheritage.org/api/1`, which SWH document thoroughly in prose. There’s no machine-readable spec yet, though it’s something the team are interested in, so swh-openapi is my stopgap, generating an OpenAPI description from the same docstring data the published reference is built from. swh-go is a Go client generated from that with pagination, auth and rate-limit handling written by hand, and both should be retired once there’s an official spec. ### Critical package coverage With a client in hand I ran a coverage check, swh-critical, over the roughly 9,800 packages in the packages.ecosyste.ms critical set and their 7,000-odd source repositories on 23 and 24 September. Of those repositories, 71.3% had their current default-branch commit already in the archive, and 89.9% of matched release tags were present as revisions. Among the repositories whose current commit was missing, 95.1% still had an older snapshot once I checked the former URLs ecosyste.ms records across renames as well as the current one. The 46 hardest cases in the audit had no snapshot at any URL I tried and no matching release objects either, and drilling into those with full clones and tree hashes from the published package tarballs still turned up archived content for every one. Across the whole audit the pattern was older history already in the archive with only recent commits missing. I think ecosyste.ms can be most useful to Software Heritage as a partner on that last part, since the archive tracks over 445 million origins, far more than the crawler can revisit at a uniform cadence, while ecosyste.ms has dependent counts, download numbers and a criticality score for each package that give a decent signal for which repositories matter most to keep fresh. Feeding that back as a ranked stream of Save Code Now requests means the crawler’s next visit goes to the source of something with a hundred thousand dependents rather than an abandoned fork. ### science.ecosyste.ms The first place that feedback loop is running in production is science.ecosyste.ms, the ecosyste.ms service that tracks research software. For each project with a high enough science score, a background job clones the repository, computes revision and directory SWHIDs with the Ruby gem, and posts them in batches to `/api/1/known/`. Projects with objects missing from the archive get their origin submitted through Save Code Now, another job polls the visit until it completes, and any SWHID newly known after our request is recorded as a confirmed contribution. The stats page rolls those up every six hours with a JSON API alongside, and individual project pages now show SWHIDs next to the DOIs and citation metadata they already had. Research software was the right place to start because that community already cares about persistent identifiers and long-term reproducibility. ### packages.ecosyste.ms The next step is doing the same for package versions on packages.ecosyste.ms, which means computing directory SWHIDs for published tarballs as well as git checkouts and storing the purl-to-SWHID mapping as a first-class field. At that point an SBOM component like `pkg:npm/[email protected]` resolves through ecosyste.ms to a `swh:1:dir:` you can verify against the tarball you downloaded and fetch from the archive independently of npm. It also turns the one-off swh-critical audit into a rolling measurement, with coverage tracked per registry and new gaps fed back through the same Save Code Now route. ### Scanning the archive The scanners I’ve been building under git-pkgs can also treat the archive as a corpus rather than a backup, since they already run against any checkout. manifests parses package-manager manifest and lockfiles across ecosystems, licenses does fast SPDX detection against the ScanCode rule corpus, and brief reports a project’s whole toolchain and conventions as structured JSON. With swh-git in front of them the checkout comes from the archive by SWHID instead of a live forge, and any of their outputs anchored to a `swh:1:rev:` is reproducible by anyone with the same identifier. Longer term I’d like to try running these against the SWH graph dataset export directly rather than one Vault checkout at a time, which would make questions about lockfile adoption or license drift across whole registries answerable from preserved source rather than whatever happens to still be online. Software Heritage has already built the archive and standardised the identifier; what I’ve been doing is plumbing to reach it from the package-management side and to point ecosyste.ms data at the repositories where another crawl would help most. All of it is MIT or Apache-2.0 licensed, and I’d be very happy to see any of it picked up or replaced by something better.
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 01/10/2026
brief v0.14.0 is out: CITATION.cff and CodeMeta metadata, source manifest paths for dependencies, better Ruby/Python/Rust project detection, TinyGo support, and compact npm lockfile fixes. github.com/git-pkgs/brief/releases/…
github.com
Release v0.14.0 · git-pkgs/brief
Changelog 5f53947 Add and align CI security and dependency automation 8e75365 Apply gopls modernize fixes (#192) 73f926f Bump github.com/git-pkgs/archives from 0.7.0 to 0.7.1 (#191) e635e97 Bump g...
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 01/10/2026
git-pkgs proxy v0.9.0 is out with npm audit support, version denylists and multiple Debian archives. It fixes NuGet cooldown enforcement and concurrent download failures, and refreshes SPDX license data. github.com/git-pkgs/proxy/releases/…
github.com
Release v0.9.0 · git-pkgs/proxy
Changelog c1f420a Add and align CI security and dependency automation 73a9863 Assert omitted Helm releases are not downloadable 8d3dacf Bump azure/setup-helm from 4.3.1 to 5.0.1 (#332) f0580d9 Bum...
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 29/09/2026
What a menace
Basil the black toy poodle reaching over the arm of the chair
001 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 27/09/2026
Luarocks having a a bad day: luarocks.org/security-incident-sept… Don't sleep on TUF: nesbitt.io/2026/05/24/signing-is-fo…
luarocks.org
LuaRocks Security Incident September 2026
Comments
100 1
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 26/09/2026
Now to see if I get it running in cloudflare workers 🤔
000 0
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 26/09/2026
Was much easier to get git-pkgs modules running in the browser as wasm than expected!
git-pkgs in the browser via wasm
100 1
Reposted by Andrew Nesbitt
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 26/09/2026
This Week in Package Management: 26 September 2026 nesbitt.io/2026/09/26/this-week-in-…
nesbitt.io
This Week in Package Management: 26 September 2026
Week nineteen of the roundup, built from the package manager OPML feed collection and whatever I’ve posted or boosted on Mastodon. ## Releases pnpm 12.6 adds an `autoDedupe` setting that resolves compatible dependency versions to a single one during install, and `pnpm add --save-types` for the matching `@types/*` package. 12.7 has the global node shim read `.nvmrc` and `.node-version` when `devEngines.runtime` is unset, and adds `pnpm publish --publish-wait-timeout` to block until a published package is available before dependents publish. RubyGems 4.1.0.beta1 adds content-addressable gems, an opt-in OS credential store for gem and Bundler credentials, ML-DSA post-quantum signatures for the signed-gem workflow, and a `--cooldown` flag on `gem install`, `update` and `outdated`. npm 12.1.0 supports `read-write-stage-only` granular access tokens for staged publishing, and `npm stage` reports the status of packages held in staging. A `--provenance-file` argument now takes precedence over OIDC-generated provenance. Poetry 2.5.0 adds an `installer.builtin-uninstall` setting that removes packages itself instead of calling pip, supports Python 3.15, and stops sending credentials configured for an HTTPS repository over plain HTTP. 2.5.1 fixes a `TypeError` in the new uninstaller. Terraform 1.17.0-beta2 allows variables and locals in provider requirements and adds a `-minimal-refresh` planning option that only refreshes resources with proposed changes. Terraform Policy is now generally available and no longer requires the experimental-features flag. Windows Package Manager 1.29.380 adds an experimental source priority setting: sources can be assigned a numeric priority via `winget source add` or `source edit` and are ordered by it in results. mise 2026.9.14 lets registry entries require a verified GitHub attestation before a tool installs, and fetches release metadata for any public GitHub repo from mise-versions rather than the GitHub API. Also out: * Homebrew 7.0.6 * pipx 1.17.6 * Hatchling 1.32.4 * uv 0.12.19 * pnpm 11.28 * Yarn 4.18.1 * asdf 0.20.2 * sbt 2.1.0-M2 * Maven 4.0.0-rc-7 * Gradle 9.8.0 * vcpkg 2026-09-26 * DNF5 5.4.6.0 * Terraform 1.16.4 * Harbor 2.15.3-rc2 * Renovate 44.115.10 * Dependabot Core 0.397.0 * setup-uv 10.2.0 * diffoscope 331 ## Security The Rust security response WG reported that Miri wrote every environment variable to `target/`, so caching that directory in GitHub Actions could expose job secrets to pull requests that read from the cache. The nightly dated 2026-09-22 restricts persisted variables to `CARGO_*` (excluding `CARGO_*_TOKEN`) and `OUT_DIR`; the post recommends clearing existing caches and rotating any secrets that were in scope. uv 0.12.18 fixes GHSA-2cv4-cqwr-gwf7, a path traversal during wheel installation on Windows. It also adds `--check` and `--output-format json` to `uv pip install` and `uv pip sync`, so planned changes can be reported while leaving the environment unchanged. Flatpak 1.18.3 updates its vendored bubblewrap to 0.12.0 for CVE-2026-87766, where sandbox setup could follow a parent symlink through `/oldroot` to write files on the host, and its vendored xdg-dbus-proxy to 0.1.8 for CVE-2026-93676, where D-Bus broadcast filtering ignored the configured path, interface and member restrictions. ## Elsewhere The Rust project announced Scott Schafer as a full-time Maintainer in Residence for the Cargo team, funded through the Rust Foundation Maintainers Fund with additional money from the Rust Leadership Council’s Project Priorities budget and AWS. Separately the Rust Foundation added CodSpeed, Haevek and Perplexity as Silver members and the Software Stewardship Lab as an Associate member. Jamie Tanna reviewed his first year as Renovate project lead: 1,813 releases, managers up from 110 to 118, datasources from 76 to 82, and external commits up 48% in the first half of 2026. Discussion-forum help requests fell 43% over the same period as users turned to LLM tools instead. Josh Bressers interviewed Daniel Stenberg and Stefan Eissing about curl’s month-long pause on accepting vulnerability reports and the volume of AI-generated submissions that prompted it. Farid Zakaria wrote up omnibin, a FUSE filesystem that presents every binary nixpkgs has shipped since 2013, 881,933 in total, by looking up store paths in Hydra’s published metadata and fetching them on first access; a cold `[email protected]` start takes about 2.7 seconds. TrustBOM: A Scalable Architecture for Confidentiality-Preserving SBOMs Across Organizations (Nguyen et al., arXiv) proposes a CI/CD-integrated attestation scheme in which a supplier proves that a given vulnerability or restricted licence is absent from its software while keeping the dependency graph private. Git 2.56.0-rc2 was tagged. ## git-pkgs I tagged eight repos this week: * citation v0.1.0 (new), a pure-Go library for parsing and validating `CITATION.cff` files that preserves source positions, unknown fields and numeric spelling * scan v0.1.0 (new), a pure-Go library that matches many regular expressions against byte blocks by compiling patterns into shared literal filters and regex automata along Hyperscan lines * secrets v0.1.0 (new), which scans Git history for leaked credentials by running the Betterleaks rule corpus over every blob and attributing findings to the commits and paths that introduced them * spam v0.1.0 (new), an offline library for measuring promotional text in package manifests and READMEs * archives v0.8.0 * clone v0.7.4 * history v0.1.1 * roles v0.1.1 Send links for next week to @[email protected].
041 4