Repository navigation
Conversation
Supersedes Dependabot #2814, which bumped the versions alone and failed Audit with four unvetted crates. Dependabot cannot write supply-chain audits, so a group bump never goes green on its own. russh 0.64.1 -> 0.65.0, napi 3.15.0 -> 3.16.1, napi-derive 3.6.13 -> 3.7.0 and napi-derive-backend 6.1.6 -> 7.0.0 behind it. Targeted `cargo update -p` keeps the lockfile to those four entries, with no opportunistic re-resolution. No other lockfile in the tree references these crates. russh 0.65.0 needs no source change: its breaking change is server-side (Handler::auth_publickey_offered and auth_publickey now take server::PublicKeyOffer and server::VerifiedPublicKey) and this tree implements only client::Handler. Four of its six advisories harden paths it reaches, and all four narrow -- EXT_INFO is capped at two per session per RFC 8308 section 2.4, a peer-declared zero maximum_packet_size is rejected in both channel-open directions, and certificate nesting is bounded at 8 `-cert-v01@` markers on the live PublicKeyOrCertificate path. The agent-server advisories are unreachable; this tree runs no SSH agent server. Channel windows now saturating_add the adjustment instead of overwriting it, matching RFC 4254 section 5.2, where the old overwrite could shrink the window. async-trait leaves the graph. napi's unsafe count rises only because the threadsafe-function call sites are centralized into one helper, which reclaims the boxed call data Node-API does not take on a non-ok status and drops it after the aborted guard releases, because those destructors are user code that can relock the handle. ClassId compacts to Option<NonZeroU32> through an append-only registry bounded at 65_536, in the module gated to non-napi8 -- which is what bashkit-js selects. The backend major is a public-AST break (symbol_for, well_known_symbol) plus a static-flag fix: the generated property key now carries is_static, so a static and an instance member of one name no longer collapse into one descriptor. Four hand delta audits chained onto the existing entries record the review, so `cargo vet --locked` passes without new exemptions or broadened publisher trust. Claude-Session: https://claude.ai/code/session_01Wy7MBup4thzdX8Mm38y59z
Review verdictLooks good to merge. Dependency-only bump with the four matching FindingsNone — no P0/P1/P2. What I checked beyond the diff
Not reviewed / limits
|
|
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bashkit | 0564845 | Commit Preview URL Branch Preview URL |
Nov 03 2026, 01:14 PM |
|
Closing as superseded by #2826, merged as For the record, the diagnosis in this comment was correct and is what unblocked it: The rebase needed only a Generated by Claude Code |
What changed
russh0.64.1 → 0.65.0,napi3.15.0 → 3.16.1,napi-derive3.6.13 → 3.7.0, andnapi-derive-backend6.1.6 → 7.0.0 behind it, plus the fourcargo vetdelta auditsthe bump needs. No source changes — only the root manifest, the root lockfile,
supply-chain/audits.tomland the knowledge log.No behavior change for callers. The SSH builtins keep their API and their sandbox
boundary; the Node binding keeps its ABI shape. What users get is the hardening in
these releases, listed below.
Targeted
cargo update -pkeeps the lockfile to exactly those four entries, with noneof the opportunistic re-resolution Dependabot's own run carried. No other lockfile in the
tree (
crates/bashkit/fuzz,examples/hyperlight,examples/hyperlight/host) referencesthese crates, so the
--lockedfailure that sank #2806/#2810 cannot recur here — that onecame from the stale fancy-regex pin already fixed on
main.Why
Supersedes Dependabot #2814, which bumped the versions alone and failed Audit with four
unvetted crates. Dependabot cannot write supply-chain audits, so a group bump never goes
green on its own — the same shape as #2792 and #2790 before it.
Checkwas red only as theaggregate gate reporting Audit; every other job on #2814 was green.
This also picks up six russh advisories, four of which touch paths this tree reaches.
Before / After
Before —
cargo vet --lockedon the bumped lockfile:After:
No new exemptions, no broadened publisher trust, and no stale exemption left behind — the
existing
russh0.63.3 andnapi3.12.4 exemptions stay because they anchor these deltachains.
Builds and tests, locally:
The 24 ssh tests include the sandbox-boundary cases —
ssh_blocked_host,ssh_wildcard_host,ssh_not_configured,scp_blocked_host,scp_not_configured,sftp_not_configured— so the allowlist behavior is intact across the russh bump.Not green locally:
ssh_supabase::ssh_supabase_connects. It dials the live publicsupabase.shendpoint, and outbound port 22 is blocked in this sandbox entirely — a rawsocket to
supabase.sh:22and togithub.com:22both time out, so the test cannot passhere on any russh version. It is a required CI gate and runs there.
What the audits actually say
The four delta audits record a source-safety review of each published package diff. Common
to all four: no new
build.rsbehavior (napi's is byte-identical, the others have none),no new
std::fs/std::net/std::process/std::envreference, and no new dependency.src/) — still exactly oneunsafeblock, theoffset_frominserver/encrypted.rs, textually unchanged.async-traitand its cratefeature are removed. The two added
tokio::net::Unix*references are both inside#[cfg(test)]modules. The breaking change is server-side (Handler::auth_publickey_offered/
auth_publickeynow takeserver::PublicKeyOffer/server::VerifiedPublicKey); this treeimplements only
client::Handler, which is why it builds unchanged. Of the six advisories:EXT_INFO is now capped at two per session per RFC 8308 §2.4, bounding previously unbounded
received_extensionsgrowth a malicious server could drive (client-reachable); apeer-declared zero
maximum_packet_sizeis rejected in bothOpenChannelMessage::parseandthe new
ChannelOpenConfirmation::parse, which is reachable here via the confirmation aserver sends for our channel open; certificate nesting is bounded at
MAX_CERT_NESTING = 8-cert-v01@markers, guardingparse_public_keyandPublicKeyOrCertificate::decode, andthis tree uses
PublicKeyOrCertificate. The remaining three are agent-server issues(pageant framing,
SSH_AGENT_CONSTRAIN_CONFIRMdedup, the defunctAgent::confirm) and areunreachable — no SSH agent server here. Separately,
WindowSize::update(value)becomesgrow(amount)withsaturating_add: the old code overwrote the window with the adjustmentand could therefore shrink it, against RFC 4254 §5.2's additive semantics.
unsaferises 1812 → 1844, but that iscentralization, not new raw-pointer work: a new
unsafe fn call_threadsafe_function_with_dataabsorbs call sites that already held those blocks. It is also the real fix — Node-API takes
ownership of the boxed call data only on
napi_ok, so onnapi_queue_full/napi_closingthe box previously leaked; it is now reclaimed, and dropped only after the
abortedreadguard releases, because those destructors are user code that can relock the same handle.
ClassIdcompacts fromOption<TypeId>toOption<NonZeroU32>via an append-only internregistry bounded at
MAX_CLASS_IDS = 65_536with an explicit full error; append-only is whatkeeps an ID valid for every
REFERENCE_MAPentry that recorded it. That module is gated tonon-
napi8, andbashkit-jsselectsnapi6, so it is the path compiled here.unsafeunchanged at 73, zeroambient references in either version. The major is a public-AST break (
NapiFnandNapiStructFieldgainsymbol_for/well_known_symbol), with napi-derive 3.7.0 the onlyconsumer and pinned to exactly 7.0.0. It also carries a genuine fix: the generated property
key now includes
is_static, so a static and an instance member of the same name no longercollapse into one descriptor.
Each note states its own scope — source safety review of the delta, not a cryptographic audit
and not a review of the whole crate.
Risk
both the SSH and Node surfaces build and test clean, and no other lockfile is involved.
client and the published Node ABI now carry audits rather than exemptions. Every advisory in
the russh delta narrows, and the napi changes are leak and identity fixes, so the direction of
travel is toward less attack surface — but
napi-derive-backendis a major bump, and the onelive-endpoint SSH test is proved only by CI, not locally.
Checklist
cargo vet --lockedpassing, with no new exemptionsknowledge/log.md)Follow-ups
https://claude.ai/code/session_01Wy7MBup4thzdX8Mm38y59z
Generated by Claude Code
Open in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need.