headroom/.github/workflows
Tejas Chopra 93c474e84b
fix(deps): clear the two Rust advisories and make cargo audit blocking (#3121)
## Description

An independent OSV sweep of every locked package in the repo (1,463
across PyPI, crates.io and npm) surfaced three RUSTSEC advisories that
**no gate was reporting**:

| advisory | package | status |
|---|---|---|
| RUSTSEC-2026-0258 (GHSA-q83h-524g-xf6h) | h2 0.4.15 | fixed here →
0.4.16 |
| RUSTSEC-2026-0204 | crossbeam-epoch 0.9.18 | fixed here → 0.9.20 |
| RUSTSEC-2024-0436 | paste 1.0.15 | unmaintained, **no patched version
exists** |

**h2 is the one that matters.** It accepted and queued empty DATA frames
without limit; a peer that never drains a stream drives unbounded memory
growth, or a panic when the length overflows. It is not a corner of the
tree — it reaches the published wheel (`hf-hub -> headroom-core ->
headroom-py`) and the entire axum/reqwest/aws-config surface of
`headroom-proxy`.

**Why none of this was visible** is the more important half of this PR.
The `audit` job was already correct in one respect I initially misread —
the `rust-changes` job reports `rust=true` for `schedule`, so it *does*
run nightly rather than only on Rust changes. The actual defect is that
`cargo audit` was `continue-on-error: true`. It has been faithfully
reporting findings into a green run that nobody looks at.

Two of the three are also invisible to Dependabot entirely:
`crossbeam-epoch` and `paste` are RUSTSEC-only with no GHSA, so the
advisory database GitHub scans does not contain them. This job is their
only possible coverage.

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)

## Changes Made

- `Cargo.lock`: `h2` 0.4.15 → 0.4.16, `crossbeam-epoch` 0.9.18 → 0.9.20.
Version + checksum only, 4 lines each way.
- `.github/workflows/rust.yml`: dropped `continue-on-error: true` from
the `cargo audit` step. `cargo deny check licenses` is deliberately left
soft-fail — `deny.toml` documents itself as intentionally permissive for
now, and tightening license policy is a separate decision.
- `.cargo/audit.toml` (new): lists `RUSTSEC-2024-0436` as accepted, with
the reason. Path matters — cargo-audit reads `.cargo/audit.toml`; a
root-level `audit.toml` is silently ignored.

`paste` is unmaintained rather than vulnerable, and there is nothing to
move to. It arrives via `tokenizers -> paste` and `rav1e -> paste`, both
under `fastembed`, so it is not actionable at our layer. Worth
revisiting when `tokenizers` adopts `pastey`.

## Testing

- [x] Manual testing performed

### Test Output

```text
Checksums verified against the real crates.io tarballs, not just the API field:

  OK   h2 0.4.16  (173331 bytes)
        lock : a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27
        real : a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27
  OK   crossbeam-epoch 0.9.20  (47545 bytes)
        lock : 2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f
        real : 2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f

Dependency-set equality (crates.io API, kind=normal):
  h2 0.4.15 -> 0.4.16          : 11 deps before, 11 after, identical
  crossbeam-epoch 0.9.18 -> .20:  2 deps before,  2 after, identical
```

## Real Behavior Proof

- Environment: macOS (darwin 25.4.0), worktree off `main` @ `b77d6129`.
**`cargo` is not installed on this machine** — see below.
- Exact command / steps: (1) parsed `uv.lock`, `Cargo.lock` and all four
`package-lock.json` files into 1,463 unique (ecosystem, name, version)
tuples and queried `api.osv.dev/v1/querybatch`, then pulled full records
for every hit; (2) walked `Cargo.lock` to find which workspace crates
actually reach `h2`, `crossbeam-epoch` and `paste`; (3) fetched both
crates' dependency lists from the crates.io API at the old and new
versions and compared them; (4) downloaded both `.crate` tarballs and
computed SHA-256 locally.
- Observed result: both bumps are patch-level with **byte-identical
dependency sets**, so the edited `Cargo.lock` is exactly what `cargo
update -p h2 -p crossbeam-epoch` would produce, and both checksums match
the real tarballs. `h2` 0.4.16 was published 2026-08-17, which is also
why Dependabot has not raised it yet.
- Not tested: I could not run `cargo audit`, `cargo build` or the test
suite locally — cargo is not installed here. **The lock edit is
hand-written, so CI is the real verification**, and it is well covered:
the `rust` workflow's `test`, `build`, `parity` and now-blocking `audit`
jobs all consume this lock and will fail on a bad checksum or an
unresolvable graph. I would not merge this on green-by-assertion; it
needs the `rust` jobs actually green.

## Runtime Rollout Safety

- Rollout-managed feature(s): None.
- Minimum rollout channel: n/a
- Stable/default behavior changed: No runtime behavior changes. CI
becomes stricter: `cargo audit` can now fail a build.
- Kill switch / disable path: re-adding `continue-on-error: true`
restores the previous (useless) behavior.
- Unsafe override required: No.
- Qualification impact: A newly-disclosed RUSTSEC advisory will now turn
the nightly Rust run red instead of being silently absorbed. That is the
intent, but it does mean advisories become someone's problem on
disclosure day — the escape hatch is a documented entry in
`.cargo/audit.toml`.
- Rollback path: Revert the commit.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Additional Notes

Deliberately **not** bundled here, each worth its own change:

- **`npm` has no audit gate at all** — no `npm audit` anywhere in
`.github/`. Current npm exposure is only `nanoid` 3.3.17
(GHSA-2v37-7h3g-55p8) in three lockfiles, all `dev: true`, which GitHub
auto-dismissed correctly. Low stakes today, but the gate is absent
rather than passing.
- **`pip-audit` only audits `--extra all`**, which excludes the
integration extras (`crewai`, `agno`, `autogen`, `langchain`, `strands`,
`bedrock`, `memory-stack`, `sandbox`). Every Python advisory currently
open against this repo lives in exactly that blind spot — GitPython via
`agno` (#3120), chromadb and json-repair via `crewai`. Dependabot
catches them because it scans the whole lock; the CI gate structurally
cannot.
- **Dependabot's `docker` ecosystem is configured for `directory: /`
only**, so the five non-root Dockerfiles get no base-image updates.

Co-authored-by: Tejas Chopra <tejas@Tejass-MacBook-Pro.local>
2026-08-19 14:19:46 -07:00
..
changelog-guard.yml ci(changelog): stop the CHANGELOG cascade — release-please owns it (#2329) 2026-07-16 14:28:57 -07:00
ci.yml fix: publish headroom-opencode in release workflow (#2372) 2026-08-11 23:56:40 -05:00
devcontainers.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
docker.yml fix(ci): unjam release and Docker publishing (#2958) 2026-08-12 23:43:04 -05:00
docs.yml chore(docs): one documentation site, not two (#2784) 2026-08-04 16:42:49 -07:00
eval.yml feat(evals): weekly HotpotQA answer-recall report on the prose path (#1188) 2026-07-15 21:40:55 +00:00
init-e2e.yml ci: scope native/wheel/dashboard jobs to relevant paths (unstarve the queue) (#2155) 2026-07-13 23:50:26 -04:00
init-native-e2e.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
install-native-e2e.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
merge-conflicts.yml ci: concurrency-cancel Docker + Merge Conflicts to stop merge-spree pileups (#2138) 2026-07-13 13:47:59 -04:00
network-diff-capture.yml ci: require ONNX Runtime >= 1.24 and fail fast when it is missing or too old (#2591) 2026-07-27 08:04:53 -07:00
opencode-plugin.yml fix(opencode): ship the transport hook-shim so wheel installs route Node child traffic 2026-08-11 09:10:38 -07:00
pr-health.yml ci: preserve merge labels while state is unknown 2026-07-09 19:51:41 -05:00
publish.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
release-metadata-sync.yml fix(ci): scope the release credential and stop persisting it to disk (#3062) 2026-08-16 19:05:32 -07:00
release-please.yml fix(ci): scope the release credential and stop persisting it to disk (#3062) 2026-08-16 19:05:32 -07:00
release.yml fix: publish headroom-opencode in release workflow (#2372) 2026-08-11 23:56:40 -05:00
rust.yml fix(deps): clear the two Rust advisories and make cargo audit blocking (#3121) 2026-08-19 14:19:46 -07:00
security.yml ci: bump actions/checkout from 4 to 7 (#1414) 2026-07-09 11:09:14 -05:00
stale.yml ci: bump actions/stale from 9 to 10 (#850) 2026-06-11 12:53:46 -05:00
wrap-e2e.yml fix: remove rtk and lean-ctx CLI context tools (#2677) 2026-07-30 22:59:41 -07:00
wrap-native-e2e.yml fix: remove rtk and lean-ctx CLI context tools (#2677) 2026-07-30 22:59:41 -07:00