You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[CI/Security] Automated dependency-audit workflow (pip-audit + osv-scanner) publishing a reproducible security evidence base as a nightly-release artifact #1949
Add a security-audit job to CI that runs pip-audit and osv-scanner against a fully resolved autobahn environment, emits a machine- and human-readable security
evidence base (resolved versions + the matching OSV/GHSA/CVE advisories, including transitive dependencies), uploads it as a verified artifact, and — via the existing release.yml flow — attaches it to the nightly master-* release alongside the wheels
(e.g. like master-202609220126).
This makes the dependency-floor security review automatic, reproducible, and transitive-aware,
and replaces hand-collected advisory tables with signed, dated, tool-verified CI output. It is the foundation issue: the follow-up dependency-floor bump for 26.9.1 should be driven off the
evidence base this produces, not off a manual spreadsheet.
Timely: autobahn just shipped a security fix of its own — CVE-2026-77528 / GHSA-hxp9-w8x3-p566
(compressed-frame maxMessagePayloadSize bypass, fixed in 26.7.1) — so standing up a continuous
dependency-audit is a natural next step in the same security track.
Why (motivation)
Reproducible & evidence-backed. A resolved-env scan against the OSV database is reproducible
and cites canonical advisory IDs, rather than relying on ad-hoc, possibly-stale manual research.
(The scanners are consumers of vulnerability databases — they are not themselves authoritative
about whether a vulnerability exists or is exploitable in autobahn's actual use.)
Transitive coverage. autobahn declares only direct deps; the real attack surface includes
transitive packages (e.g. numpy via bjdata, argon2-cffi-bindings via argon2-cffi, cryptography via service-identity). A resolved-env scan sees all of them.
Auditable over time. Publishing the evidence base as a release asset means every nightly
carries a timestamped SBOM + advisory report — a lightweight, continuously-updated supply-chain
record. New advisories against already-shipped versions surface on the next nightly.
Drives policy, not just alerts. The evidence base is the input to the deliberate floor policy
(raise a floor only where there is a real, reachable advisory — see the follow-up issue).
What to build
1. New security-audit job in .github/workflows/main.yml
Runs on ubuntu-24.04, in parallel with the other main.yml jobs (quality-checks, test-serdes, import-smoke, build-schema, ...). Uses the existing just create / uv toolchain.
2. Resolve the environment(s) — one scan per dependency scope
Audit each scope separately so findings are attributable to where a dep enters:
runtime: autobahn[all] (the union extra: twisted, compress, serialization, encryption, scram, nvx)
build: .[build-tools]
dev: .[dev] (dev/build tooling executes locally on maintainer machines and in CI, so its CVEs matter)
For each scope: install into a fresh venv, then capture the exact resolved set
(uv pip freeze / uv export) into the evidence base. (autobahn intentionally does not track a uv.lock; the resolution is captured per run into the artifact for reproducibility, which is also
what lets the scan catch newly-disclosed advisories in transitive deps.)
3. Run both scanners over each resolved scope
pip-audit — PyPI/OSV-backed, Python-native; emit JSON and CycloneDX SBOM.
osv-scanner — run over the generated SBOM / frozen requirements; emit JSON.
Running both cross-verifies findings and gives richer OSV↔GHSA↔CVE linkage. Pin the tool
versions and record the OSV database snapshot timestamp so a report is reproducible.
4. Evidence-base format (committed to the artifact, not the repo)
pip-audit-<scope>.json, osv-scanner-<scope>.json — raw tool output.
advisories-<scope>.md/.json — normalized rollup: one row per finding with OSV id, GHSA id, CVE id, severity/CVSS, affected range, fixed version, package, resolved
version, direct-vs-transitive, which extra/group pulled it in.
summary.md — human rollup + provenance header: autobahn version + commit, tool versions,
OSV DB snapshot time, run URL, UTC timestamp.
5. Publish as a nightly-release artifact
Upload via wamp-proto/wamp-cicd/actions/upload-artifact-verified@main (same verified-artifact
path the wheels/schema jobs already use).
Extend release.yml to download-artifact-verified the audit artifact from the main run
(main_run_id is already resolved there) and attach autobahn-security-evidence-<tag>.zip to the master-* release, so it ships next to the wheels.
6. CI job summary
Write the advisory rollup table to $GITHUB_STEP_SUMMARY so findings are visible on the run page
without downloading the artifact.
Design decisions (please confirm in-issue)
Gating policy. Recommend non-blocking / reporting-only initially (always upload the
evidence base; never fail unrelated PRs on a freshly-disclosed transitive advisory) — consistent
with the project's "float tools, fix from substance" philosophy. Add opt-in gating later, scoped
to direct declared deps resolving below their security floor (once the floors from the
follow-up issue land), with a documented, reviewed allowlist for accepted/again-unreachable
findings (e.g. python-ecdsa Minerva — see below).
Scopes. Audit runtime [all]and[build-tools]and[dev] (dev/build CVEs are
in-scope because those packages execute locally).
Both tools (pip-audit + osv-scanner), pinned, with OSV DB snapshot recorded.
Acceptance criteria
security-audit job runs on push/PR in main.yml, one scan per scope (runtime/build/dev), both tools.
Evidence base produced with resolved versions (direct + transitive), SBOMs, raw tool output,
normalized advisory rollup (OSV/GHSA/CVE + severity + affected/fixed + direct/transitive + extra), and a provenance header.
Evidence base uploaded via upload-artifact-verified and attached to the master-* nightly release by release.yml.
Advisory rollup written to the CI job summary.
Tool + OSV-DB versions pinned/recorded so a report is reproducible.
Non-blocking by default (documented), with a clear path to opt-in gating + allowlist.
FlatBuffers hardening is a separate, coordinated autobahn + zlmdb issue — the vendored
FlatBuffers version is asserted equal to zlmdb's (autobahn.check_zlmdb_flatbuffers_version_in_sync()
test_zlmdb_flatbuffers_in_sync), so it cannot be bumped in autobahn alone.
python-ecdsa / Minerva (CVE-2024-23342) is N/A across autobahn, wamp-xbr and crossbar:
python-ecdsa is used only for secp256k1 BIP32 derivation math (never P-256, never .sign());
signing is Ed25519 (nacl) and Ethereum secp256k1 (eth_account/libsecp256k1). A good first
allowlist entry once gating is added.
Nightly release example the artifact should ride along with: https://github.com/crossbario/autobahn-python/releases/tag/master-202609220126
Ties into the WAMP-group CI/CD (wamp-cicd); the audit job + evidence-base format is a candidate
to generalize to the other group repos (txaio, zlmdb, cfxdb, crossbar, wamp-xbr) afterwards.
Summary
Add a
security-auditjob to CI that runs pip-audit and osv-scanner against afully resolved autobahn environment, emits a machine- and human-readable security
evidence base (resolved versions + the matching OSV/GHSA/CVE advisories, including
transitive dependencies), uploads it as a verified artifact, and — via the existing
release.ymlflow — attaches it to the nightlymaster-*release alongside the wheels(e.g. like
master-202609220126).This makes the dependency-floor security review automatic, reproducible, and transitive-aware,
and replaces hand-collected advisory tables with signed, dated, tool-verified CI output. It is the
foundation issue: the follow-up dependency-floor bump for 26.9.1 should be driven off the
evidence base this produces, not off a manual spreadsheet.
Timely: autobahn just shipped a security fix of its own — CVE-2026-77528 / GHSA-hxp9-w8x3-p566
(compressed-frame
maxMessagePayloadSizebypass, fixed in 26.7.1) — so standing up a continuousdependency-audit is a natural next step in the same security track.
Why (motivation)
and cites canonical advisory IDs, rather than relying on ad-hoc, possibly-stale manual research.
(The scanners are consumers of vulnerability databases — they are not themselves authoritative
about whether a vulnerability exists or is exploitable in autobahn's actual use.)
transitive packages (e.g.
numpyviabjdata,argon2-cffi-bindingsviaargon2-cffi,cryptographyviaservice-identity). A resolved-env scan sees all of them.carries a timestamped SBOM + advisory report — a lightweight, continuously-updated supply-chain
record. New advisories against already-shipped versions surface on the next nightly.
(raise a floor only where there is a real, reachable advisory — see the follow-up issue).
What to build
1. New
security-auditjob in.github/workflows/main.ymlRuns on
ubuntu-24.04, in parallel with the othermain.ymljobs (quality-checks,test-serdes,import-smoke,build-schema, ...). Uses the existingjust create/uvtoolchain.2. Resolve the environment(s) — one scan per dependency scope
Audit each scope separately so findings are attributable to where a dep enters:
autobahn[all](the union extra: twisted, compress, serialization, encryption, scram, nvx).[build-tools].[dev](dev/build tooling executes locally on maintainer machines and in CI, so its CVEs matter)For each scope: install into a fresh venv, then capture the exact resolved set
(
uv pip freeze/uv export) into the evidence base. (autobahn intentionally does not track auv.lock; the resolution is captured per run into the artifact for reproducibility, which is alsowhat lets the scan catch newly-disclosed advisories in transitive deps.)
3. Run both scanners over each resolved scope
versions and record the OSV database snapshot timestamp so a report is reproducible.
4. Evidence-base format (committed to the artifact, not the repo)
A directory (zipped) containing, per scope:
resolved-<scope>.txt— frozenpkg==version(direct + transitive).sbom-<scope>.cdx.json— CycloneDX SBOM.pip-audit-<scope>.json,osv-scanner-<scope>.json— raw tool output.advisories-<scope>.md/.json— normalized rollup: one row per finding withOSV id, GHSA id, CVE id, severity/CVSS, affected range, fixed version, package, resolved
version, direct-vs-transitive, which extra/group pulled it in.
summary.md— human rollup + provenance header: autobahn version + commit, tool versions,OSV DB snapshot time, run URL, UTC timestamp.
5. Publish as a nightly-release artifact
wamp-proto/wamp-cicd/actions/upload-artifact-verified@main(same verified-artifactpath the wheels/schema jobs already use).
release.ymltodownload-artifact-verifiedthe audit artifact from themainrun(
main_run_idis already resolved there) and attachautobahn-security-evidence-<tag>.zipto themaster-*release, so it ships next to the wheels.6. CI job summary
Write the advisory rollup table to
$GITHUB_STEP_SUMMARYso findings are visible on the run pagewithout downloading the artifact.
Design decisions (please confirm in-issue)
evidence base; never fail unrelated PRs on a freshly-disclosed transitive advisory) — consistent
with the project's "float tools, fix from substance" philosophy. Add opt-in gating later, scoped
to direct declared deps resolving below their security floor (once the floors from the
follow-up issue land), with a documented, reviewed allowlist for accepted/again-unreachable
findings (e.g. python-ecdsa Minerva — see below).
[all]and[build-tools]and[dev](dev/build CVEs arein-scope because those packages execute locally).
Acceptance criteria
security-auditjob runs on push/PR inmain.yml, one scan per scope (runtime/build/dev), both tools.normalized advisory rollup (OSV/GHSA/CVE + severity + affected/fixed + direct/transitive + extra), and a provenance header.
upload-artifact-verifiedand attached to themaster-*nightly release byrelease.yml.Notes / links
off this evidence base, not a manual table. Confirmed already-landed:
cryptography>=50([CI] PyPy-ARM64 wheel job times out: scope the smoke test by tier (lightweight on emulated) + raise emulated-job limits #1947).FlatBuffers version is asserted equal to zlmdb's (
autobahn.check_zlmdb_flatbuffers_version_in_sync()test_zlmdb_flatbuffers_in_sync), so it cannot be bumped in autobahn alone.python-ecdsa is used only for secp256k1 BIP32 derivation math (never P-256, never
.sign());signing is Ed25519 (
nacl) and Ethereum secp256k1 (eth_account/libsecp256k1). A good firstallowlist entry once gating is added.
https://github.com/crossbario/autobahn-python/releases/tag/master-202609220126wamp-cicd); the audit job + evidence-base format is a candidateto generalize to the other group repos (txaio, zlmdb, cfxdb, crossbar, wamp-xbr) afterwards.