Skip to content

11.2.0 Release - #305

Draft
liquidsec wants to merge 36 commits into
stablefrom
dev
Draft

liquidsec wants to merge 36 commits into
stablefrom
dev

Conversation

@liquidsec

@liquidsec liquidsec commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

11.2.0 Release

Merges dev into stable to cut v11.2.0.

Draft. Required-check names need updating before this can merge, and #310 should land first.

Blockers

  • helm/Chart.yaml aborts the release. The shared release-check requires every tracked Chart.yaml version/appVersion to equal the release version, and ours still says 1.0.0:
    $ manifest.py --root . tag v11.2.0
    tag v11.2.0 does not match helm/Chart.yaml version 1.0.0
    
    check is the first job in publish.yml and every other job needs: it, so pushing v11.2.0 would publish nothing at all. release.sh runs the same check locally, so it refuses before the tag is pushed — with the misleading message merge the version bump first. Set the chart to 11.2.0 and keep it in lockstep every release, or stop tracking it.
  • The ruleset's required checks no longer exist. The active default branch ruleset requires docker-test and test (3.10)–test (3.14). fix(lookup): attribute providers to the entries they declare #304 renamed every one of them, so those contexts will never report: this PR shows 15 passing checks and still sits at BLOCKED. Point the ruleset at rust / passed, python / passed and docker.
  • build(deps): bump pyo3 to 0.29 for Python 3.15 #310 — pyo3 0.27 -> 0.29. Python 3.15 ships Oct 9, and the matrix now follows requires-python instead of a fixed list, so 3.15 joins both tests and wheels on release day. pyo3 0.27 refuses to build against it.
  • Register the PyPI trusted publisher (workflow publish.yml, environment pypi), then delete PYPI_API_TOKEN and PYPI_TOKEN. The first tagged release fails at the pypi job without it.

Releasing changed

Merging this PR publishes nothing. Pushing to stable used to tag v<version> from Cargo.toml and then publish to PyPI, crates.io and Docker Hub. #304 removed that: the only thing that publishes now is a human-pushed v* tag, which runs publish.yml -> release-check -> tests -> wheels -> crates.io + PyPI -> Docker -> GitHub release. release-check refuses any tag that isn't vMAJOR.MINOR.PATCH(-rc.N) or that disagrees with Cargo.toml.

So: merge this, then push v11.2.0. See ## Releasing in the README.

Lookup attribution (#304)

lookup() returns only the providers whose own entries contain the target (#294). Entries are inserted broadest-first into a Normal-mode radix tree, each inheriting its nearest container's resolved provider list; entries that add nothing are skipped. Resolution moved to build time, so lookup() is one tree get() plus a map hit.

query before after
18.195.165.195 Amazon, Cloudfront, Quiccloud Amazon
52.67.31.86 Amazon, Cloudfront, Gocache Amazon
foo.s3.amazonaws.com Amazon, GitHub, HPE, Microsoft Amazon
hpefonts.s3.amazonaws.com Amazon, HPE

This changes attribution results, and is the main reason for the minor bump.

CI moved onto the org's shared workflows (#304)

Pinned to blacklanternsecurity/CLA@e532142 (branch feat/shared-workflows, blacklanternsecurity/CLA#3). No repo-local copies of the test, wheel, crates, docker, release or SBOM steps remain.

was is now
rust-tests.yml (fmt, clippy, test + crates.io publish on stable push) tests.yml -> shared rust-tests.yml; publishing moved to publish.yml
python-tests.yml (3.10–3.14 matrix, PyPI publish, auto-tag, 5 wheel jobs, sdist, release) tests.yml -> shared python-tests.yml (matrix from requires-python, plus ruff lint); wheels/sdist/release in publish.yml
pipeline-tests.yml folded into the pytest args (test_cloudcheck.py cloudcheck_update)
docker-tests.yml (test + publish + Hub tag cleanup) docker job in tests.yml; image publishing via shared docker.yml
cla.yml (91 lines inline) shared cla-reusable.yml

Preserved: every wheel target (linux x86_64/x86/aarch64/armv7/ppc64le, musllinux x86_64/x86/aarch64/armv7, windows x64/x86, macos x86_64/aarch64), the sdist, and build-provenance attestation. s390x stays dropped, as it already was. Added: SPDX SBOMs for the repo and each image, a real GitHub Release, --locked builds, SHA-pinned actions, and least-privilege permissions: blocks.

Removed on purpose

  • Publishing or tagging on any branch push. The daily signature commit to stable no longer republishes, and drops its hardcoded Python 3.12 so uv follows requires-python.
  • Docker sha-, branch and PR image tags, and the daily rebuild on every stable push. The image only carries the binary — signatures are fetched at runtime — so the daily rebuild was churn.
  • The Docker Hub tag-cleanup step. It evidently never kept to its stated limit anyway: the repository holds 156 tags.
  • PYPI_TOKEN in favour of OIDC trusted publishing.

Worth a decision before tagging

  • Docker tags lose their v prefix. release-check emits the manifest version, so the shared workflow pushes 11.2.0, 11.2, 11, latest, stable. Everything on Docker Hub today is v11.1.0, v11.1, v11. Anyone pinned to :v11 or :v11.1 silently freezes on the current image instead of failing loudly.
  • manylinux floor — decided, keeping 2_28. 11.1.0 shipped manylinux_2_17 wheels; the shared default raises the glibc floor to 2.28, dropping CentOS 7, RHEL 7, Ubuntu 18.04 and Amazon Linux 2. Those are not officially supported, so this is accepted deliberately. All five linux targets still build: x86_64 and i686 from the pypa images, aarch64/armv7/ppc64le from the maturin cross images.
  • Re-running a release is no longer idempotent. The old jobs used cargo search guards and --skip-existing; crates.yml now runs a bare cargo publish and the PyPI job has no --skip-existing. A partial failure late in publish.yml cannot be fixed by re-running the whole workflow, only the failed jobs.
  • The shared workflows are pinned to a commit on an unmerged branch. The SHA makes it immutable, but if feat/shared-workflows is deleted or force-pushed before CLA#3 lands, every workflow here stops resolving. Re-pin to a default-branch SHA once it merges.
  • No rust-toolchain.toml. The shared Rust jobs run rustup show active-toolchain || rustup toolchain install, so the toolchain is whatever ubuntu-24.04 ships rather than a pinned channel.

Dependabot (#307)

Weekly, grouped minor/patch and major PRs per ecosystem, all targeting dev, with cargo added as an ecosystem for the first time, plus the shared auto-merge workflow for minor and patch updates.

Dependency updates

  • blasthttp 0.9.0 -> 0.10.0
  • maturin 1.14.1 -> 1.15.0
  • pydantic 2.13.4 -> 2.13.5
  • ruff 0.15.18 -> 0.16.9

actions-rust-lang/setup-rust-toolchain 1 -> 2 (#309) landed before #304 deleted the workflows that used it, so it is a no-op in this release.

Signature data

Daily updates since 11.1.0: -198 CIDRs, domains and the 60-provider list unchanged.

Version

11.1.0 -> 11.2.0 in Cargo.toml, Cargo.lock and uv.lock; pyproject.toml now reads its version from Cargo.toml via dynamic = ["version"]. Docker tags are derived from the release tag instead of hardcoded.

dependabot Bot and others added 30 commits June 28, 2026 00:12
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.18 to 0.15.20.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.15.18...0.15.20)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.15.20
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…uff-0.15.20

build(deps-dev): bump ruff from 0.15.18 to 0.15.20
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.20 to 0.16.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.15.20...0.16.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [maturin](https://github.com/pyo3/maturin) from 1.14.1 to 1.15.0.
- [Release notes](https://github.com/pyo3/maturin/releases)
- [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md)
- [Commits](PyO3/maturin@v1.14.1...v1.15.0)

---
updated-dependencies:
- dependency-name: maturin
  dependency-version: 1.15.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps blasthttp from 0.9.0 to 0.10.0.

---
updated-dependencies:
- dependency-name: blasthttp
  dependency-version: 0.10.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.13.4 to 2.13.5.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.13.5/HISTORY.md)
- [Commits](pydantic/pydantic@v2.13.4...v2.13.5)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.13.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.16.2 to 0.16.8.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.16.2...0.16.8)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the github-actions group with 1 update in the / directory: [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain).


Updates `actions-rust-lang/setup-rust-toolchain` from 1 to 2
- [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases)
- [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md)
- [Commits](actions-rust-lang/setup-rust-toolchain@v1...v2)

---
updated-dependencies:
- dependency-name: actions-rust-lang/setup-rust-toolchain
  dependency-version: '2'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
ubuntu-latest is a label GitHub moves. The image changes under us and
a green pipeline turns red on a morning nobody touched the code.
Pinning to ubuntu-24.04 means the runner moves when we move it.

dtolnay/rust-toolchain was called at @stable, a branch, not a release.
It is pinned to a commit, dated in the trailing comment because that
repo publishes no release tag for it. Version-tagged actions are
untouched.
…lasthttp-0.10.0

build(deps-dev): bump blasthttp from 0.9.0 to 0.10.0
…uff-0.16.8

build(deps-dev): bump ruff from 0.16.2 to 0.16.8
…aturin-1.15.0

build(deps-dev): bump maturin from 1.14.1 to 1.15.0
lookup() returned every provider nested anywhere inside the matching
entry, not just those whose own entry contains the target. HPE declares
one bucket, hpefonts.s3.amazonaws.com, and that made every
*.amazonaws.com host come back tagged HPE; one QUIC.cloud /32 did the
same to 8.4M addresses around it. Downstream in bbot a stray cdn tag
makes portfilter drop every non-web port, so this showed up as missing
findings rather than wrong ones.

The tree was built in ScopeMode::Acl, which deliberately collapses a
nested entry into whatever already covers it. That is correct for an
access list and fatal for attribution: the provider was filed under the
container's key, so by lookup time nothing could tell HPE's bucket from
Amazon's whole namespace. The two-pass loop was an earlier fix for ACL
mode destroying GitHub's blob.core.windows.net when Azure's windows.net
was inserted; it preserved the child but widened the key to windows.net.

Build in ScopeMode::Normal instead, so every entry keeps its own node,
and resolve each entry's provider set once at build time by inserting
broadest first and inheriting from the nearest container already in the
tree. Entries that add no provider their container lacks are skipped:
anything under them resolves to that container for the same answer, which
keeps a provider's own nested subnets from inflating the tree. lookup()
is unchanged, still one get() plus a map hit.

Legitimate nesting survives. A tenant's own host returns the tenant and
the infrastructure owner both, so hpefonts.s3.amazonaws.com is still
Amazon + HPE and GitHub's Azure ranges are still Microsoft + GitHub.
Only hosts the tenant never claimed stop matching.

Against the live signature file, keys covering more than one provider
fall from 133.2M addresses to 35.0M, and the remainder is real shared
attribution. Build cost goes from 205ms to 312ms once per 24h refresh;
the map holds Arc handles so the extra keys cost pointers, not strings.

test_lookup_windows_blob_domain asserted the old behaviour, that
asdf.blob.core.windows.net returns GitHub. GitHub lists specific hosts
under blob.core.windows.net and not that one, so it now asserts the
opposite, alongside regression tests for the amazonaws.com and AWS-IP
leaks and a case covering real tenancy.

Fixes #294

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
build_data_structures inserted every CIDR and domain into an ACL-mode
radix tree, which keeps only the outermost entry. A nested entry was
filed under its container's key, so a lookup anywhere in the container
returned the nested provider too. One QUIC.cloud /32 tagged all of
18.128.0.0/9 as a CDN, and HPE's one S3 bucket claimed every
*.amazonaws.com host.

The tree now runs in Normal mode, so every entry keeps its own node and
its own providers. resolve() walks from the most specific match up
through each containing entry and returns the union. A target gets the
providers whose own entry contains it: ancestors, never siblings or
descendants. The second insert pass existed only to converge the ACL
merge and is gone.

test_lookup_windows_blob_domain asserted that an arbitrary
*.blob.core.windows.net host is GitHub. GitHub lists only specific blob
hosts, so the test now checks a host GitHub lists (GitHub and Microsoft)
and an unlisted one (Microsoft only).

New unit tests build from a synthetic signature file. Before the fix:
10.9.9.9, 10.1.2.4 and www.bigcloud.example returned
["BigCloud", "TinyCdn"] where ["BigCloud"] was expected.

Against the live signature file after the fix:
18.195.165.195 -> Amazon (was Amazon, Cloudfront, Quiccloud)
foo.s3.amazonaws.com -> Amazon (was Amazon, GitHub, HPE, Microsoft)
18.192.146.200 -> Amazon, Quiccloud (its own /32 still attributes)

Fixes #294
…ydantic-2.13.5

build(deps-dev): bump pydantic from 2.13.4 to 2.13.5
…ctions/github-actions-b24befd130

build(deps): bump actions-rust-lang/setup-rust-toolchain from 1 to 2 in the github-actions group across 1 directory
Cargo.toml, pyproject.toml, both lockfiles, and the Docker image tags.
Merging to stable publishes to PyPI and tags the release from the
Cargo.toml version, so the bump has to land before the release merge.
master was never updated to the v3 signature format — it only ever had
cloud_providers.json — so the link 404s today. stable is the default
branch and carries the file the daily job writes.
Takes liquidsec's build-time resolution per review: each entry stores
the providers that contain it, so lookup is one get plus a map hit.
resolve(), parent_of() and ipnet are gone.

Keeps this branch's offline fixture tests, ported to the radix get
path, including the insert-order rebuild test that guards the breadth
sort.
Every push to stable published to crates.io, PyPI, and Docker Hub,
decided whether to tag by comparing a grepped version against `git
describe`, and minted the tag in CI. The daily signature commit to
stable therefore republished, and the Docker tags were hand-edited
literals (v11, v11.2, v11.2.0).

- Cargo.toml is the only declared version. pyproject.toml reads it
  through maturin (`dynamic = ["version"]`).
- New publish.yml, `v*` tags only. Fails unless the tag equals
  Cargo.toml, reruns the rust, python, and docker test workflows,
  then publishes the crate, the wheel matrix with attestation, and
  the Docker image. Docker tags derive from the version. Actions are
  SHA-pinned, windows and macos runners pinned.
- The test workflows only test: callable, read-only, no publish jobs.
- Dropped: the tag-guessing step, CI tag minting, `--skip-existing`
  masking re-publishes, and Docker Hub tag pruning.
- The three test workflows grouped concurrency on github.workflow,
  which under workflow_call is the caller's name, so all three shared
  publish.yml's group. Use fixed per-file prefixes and only cancel
  superseded PR runs.
- crates.io and Docker Hub published as soon as tests passed, so a
  failed wheel build still shipped the crate and image. Both now wait
  on every wheel and the sdist, like PyPI.
publish.yml refuses tags outside vMAJOR.MINOR.PATCH and
vMAJOR.MINOR.PATCH-rc.N before comparing to Cargo.toml. PyPI upload
drops PYPI_TOKEN for trusted publishing, registry jobs run in the
release environment, and a final job creates the GitHub Release with an
SPDX JSON SBOM in the same tag run.

daily-update and pipeline-tests gain a contents: read permissions
block, every remaining tag-ref action is pinned to a commit SHA, and
CLA calls the shared reusable workflow.
Governance declares one gated environment named pypi across published
repos. crates and docker jobs stay in release.
ipnet was added to Cargo.toml but nothing imports it. The attribution
docs restated the mechanism line by line and carried em dashes; keep
only the why (Normal vs Acl mode, broadest-first inheritance).
Four test workflows plus an inline wheel matrix, docker push, crates
upload and release duplicated what the shared workflows in
blacklanternsecurity/CLA now provide. tests.yml calls rust-tests.yml
and python-tests.yml (pipeline tests fold into the python job) and keeps
a docker job for test_docker.py. publish.yml calls release-check.yml,
maturin-wheels.yml, crates.yml, docker.yml and publish.yml, keeping only
the trusted-publishing PyPI upload at top level. Docker tags and image
name come from release-check outputs and the repository name instead of
literals; DOCKER_USERNAME is now a repository secret.

daily-update drops the hardcoded Python 3.12 so uv follows
requires-python. ruff lint rules are declared in pyproject so the dev
dependency range cannot widen them silently, and README examples are
ruff formatted.
Releases are a pushed tag cut with the shared release.sh, which checks
the tag against the manifest. State that here instead of copying the
script.
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.16.8 to 0.16.9.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.16.8...0.16.9)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the github-actions group with 1 update: [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain).


Updates `actions-rust-lang/setup-rust-toolchain` from 1 to 2
- [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases)
- [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md)
- [Commits](actions-rust-lang/setup-rust-toolchain@v1...v2)

---
updated-dependencies:
- dependency-name: actions-rust-lang/setup-rust-toolchain
  dependency-version: '2'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
…uff-0.16.9

build(deps-dev): bump ruff from 0.16.8 to 0.16.9
…r and patch (#307)

* ci(dependabot): group updates weekly and auto-merge minor and patch

Individual dependabot PRs pile up faster than one engineer can review
them and go stale until they conflict (bbot-enterprise#141).

Every ecosystem now runs weekly against dev and opens at most two
grouped PRs: one for minor and patch bumps, one for majors. A
pull_request_target workflow enables auto-merge (squash) on the
minor/patch group so it lands once required checks pass. Majors still
need a human.

* ci(dependabot): call the shared auto-merge workflow

The auto-merge job was a byte-identical copy in ten repositories. It now
calls dependabot-auto-merge.yml in blacklanternsecurity/.github, pinned
by SHA, so the fetch-metadata pin and merge policy live in one place.

The trigger moves from pull_request_target to pull_request. Dependabot
branches live in this repository, so the privileged target context was
never needed and zizmor flags it as a dangerous trigger.

* ci(dependabot): call auto-merge from the public CLA repository

blacklanternsecurity/.github is private, so public repositories cannot
call reusable workflows from it and the run failed as a workflow file
issue. The shared workflow lives in blacklanternsecurity/CLA, which is
public and already hosts cla-reusable.yml.

* ci(dependabot): gate auto-merge on finished checks

dev carries no required checks (#139), so gh pr merge --auto would merge
immediately rather than on green. The shared workflow now waits for
every other check on the head commit, refuses on failure or cancel, and
merges with --match-head-commit. The caller grants checks: read so it can
read check state.

* ci(dependabot): pin the shared workflow to the current CLA tip

Aligns with the SHA the other shared CLA workflows are pinned to. The
auto-merge workflow is unchanged between the two commits.
singlerider and others added 5 commits October 6, 2026 08:26
The insert-order test rebuilt the same fixture repeatedly, but the
breadth sort is a total order, so the insert sequence never varied.

Add a three-level CHAIN fixture that fails if an entry inherits its
ancestor's declared providers instead of the ancestor's resolved list.
names() now delegates to names_in(fixture, target).
…ctions/github-actions-b24befd130

build(deps): bump actions-rust-lang/setup-rust-toolchain from 1 to 2 in the github-actions group
fix(lookup): attribute providers to the entries they declare
pyo3 0.27 stops the build on interpreters it doesn't know, and 3.15.0
final ships October 9. The shared python-tests.yml and maturin-wheels.yml
derive their matrix from requires-python = ">=3.10", so 3.15 joins both
the moment it releases: `python / test (3.15)` would fail at `maturin
develop` and take the required `python / passed` check with it, blocking
every PR, and the 3.15 wheel leg would stop publish.yml before PyPI,
crates.io and the release.

pyo3 0.29.0 added 3.15 support (PEP 820 module init, PyModExport/PyABIInfo).
No source changes: python.rs is already on the Bound/Python::attach API.

Capping requires-python was the alternative, but that locks 3.15 users
out of installing.
build(deps): bump pyo3 to 0.29 for Python 3.15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants