Skip to content

ci(security): decide yanked/unsound/unmaintained advisory posture (LAB-1152) - #71

Open
27Bslash6 wants to merge 3 commits into
mainfrom
lab-1152-advisory-posture
Open

27Bslash6 wants to merge 3 commits into
mainfrom
lab-1152-advisory-posture

Conversation

@27Bslash6

@27Bslash6 27Bslash6 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Closes LAB-1152.

Decision per advisory class

Class Posture Why
yanked fail on the weekly schedule run (cargo audit --deny yanked); warn on PR/push A yank lands against an unchanged lockfile — it must not block unrelated PRs — and the schedule run exists precisely for advisories no PR diff touches. The red is typically fixed same-day with cargo update -p; enforcement lives on the audit side because cargo-deny's feature-resolved graph pruned the actual yanked crate (chacha20, behind reqwest's unused quinn path) while audit saw it.
unsound keep warn everywhere Born red on 3 counts today; rand 0.8.5 (via fred 9.4 + memcache 0.19, RUSTSEC-2026-0097) has no compatible upgrade — enforcement forces an accumulating ignore-list, a worse posture than an honest warning.
unmaintained keep warn everywhere By definition no fixed version exists; same treadmill with no unblock path. deny.toml scopes stay narrow — widening to "all" would only duplicate what audit already reports from the verbatim lockfile every run.

deny.toml's untracked TODO ("widening both scopes to all is open work, not covered") is replaced by this decision of record. README table and Makefile updated to match; make audit runs the strict form so a local pass covers every CI event.

Yanked check proven to execute — and now self-proving

  • Historical evidence on cachekit-lean: run 33334234173 (green, 2026-08-30) shows Updating crates.io index followed by Warning: yanked in the audit step — the check runs on that runner and detects real yanks; it just exited 0.
  • New finding (verified locally on the pinned 0.22.1): with the crates.io index unreachable but the advisory DB reachable, cargo audit --deny yanked silently skips the yank check and exits 0 — no warning at all. Total network loss fails closed (advisory DB fetch errors out). Since the weekly run is the sole enforcement point, its leg now requires positive evidence (Updating crates.io index present, no couldn't check warning) and fails otherwise. Fail-closed brittleness is confined to the schedule event — a wording change in the pinned tool can only redden the weekly run, never a PR.

Green-on-clean proof (local, pinned tool versions 0.19.4 / 0.22.1)

  • cargo update -p chacha20 → 0.10.1 (yanked) → 0.10.2 (not yanked; crates.io checksum verified; sole dependent rand 0.10.2 wants ^0.10). cargo check --all-features --locked passes.
  • cargo deny --locked --all-features check → exit 0: advisories ok, bans ok, licenses ok, sources ok (--locked and --all-features preserved).
  • cargo audit --deny yanked → exit 0, warning: 3 allowed warnings found (the three unsound advisories that stay warn by decision: anyhow, rand 0.8.5, scc).

Notes

  • Expert panel (bug-hunter, security, craftsman, catchphrase) reviewed the diff; applied findings: the proof-of-run guard above, softened the "a yank always has a fix" overclaim, de-duplicated the rationale to deny.toml as single decision of record, fixed the stale Makefile header, README row now covers push runs. No findings rejected.
  • Sibling posture (noted, not fixed here — LAB-1037 territory): cachekit-core and cachekit-py both leave yanked at warn and run bare cargo audit; cachekit-core installs cargo-audit unpinned.
  • Trivial-conflict warning: #68 (LAB-1151) touches the same two files; whichever lands second rebases (accepted on-ticket).

Summary by CodeRabbit

  • Bug Fixes

    • Improved scheduled security checks to reliably detect vulnerabilities, yanked crates, and dependency index lookup failures.
    • Maintained vulnerability enforcement across all checks while limiting yanked-crate enforcement to scheduled audits.
  • Documentation

    • Clarified the differences between local, pull request, push, and scheduled security checks.
    • Documented behaviour when the package registry is unavailable and how unsound or unmaintained advisories are reported.

…B-1152)

yanked: enforced — cargo audit --deny yanked on the weekly schedule run,
where advisories against an unchanged lockfile belong; PR/push runs keep
the warning so an upstream yank never blocks unrelated PRs. The schedule
leg now also proves the yank check ran (cargo-audit 0.22.1 silently skips
it and exits 0 when the crates.io index is unreachable — verified).

unsound / unmaintained: stay warnings on every event. Neither class
guarantees a fixed version exists (rand 0.8.5 via fred 9.4 + memcache
0.19 has no compatible upgrade today), so enforcement means an
ignore-list treadmill. deny.toml scopes stay narrow: cargo audit already
reports every transitive case from the verbatim lockfile each run.

deny.toml's untracked TODO is replaced by the decision of record;
README table and Makefile follow. cargo update -p chacha20 clears the
one yanked crate (0.10.1 -> 0.10.2) so the enforced class is born green.
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: 841c02f1-4e1e-4569-994f-bff3e88f1802

📥 Commits

Reviewing files that changed from the base of the PR and between 42697bd and 0a3a93e.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • .github/workflows/security.yml
  • Makefile
  • README.md
  • deny.toml

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 3 reviews per hour.


Walkthrough

The pull request adds event-specific cargo audit enforcement, makes the local audit target stricter, and updates security documentation for yanked, unsound, and unmaintained advisories.

Changes

Supply-chain audit enforcement

Layer / File(s) Summary
Scheduled cargo audit enforcement
.github/workflows/security.yml
Scheduled runs use --deny yanked, record and stream audit output, and fail when yank checks or package lookups fail. Other runs continue to enforce vulnerabilities without denying yanked crates.
Local command and policy alignment
Makefile, README.md, deny.toml
The local audit target uses --deny yanked. The README and deny.toml document CI differences and advisory handling for yanked, unsound, and unmaintained crates.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Other

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions as GitHub Actions
  participant CargoAudit as cargo-audit
  participant CratesIo as crates.io
  GitHubActions->>CargoAudit: Run cargo audit with event-specific flags
  CargoAudit->>CratesIo: Query advisory and package data
  CratesIo-->>CargoAudit: Return advisory and yank results
  CargoAudit-->>GitHubActions: Stream and record audit output
  GitHubActions->>GitHubActions: Apply scheduled-run enforcement
Loading

Merge Risk: ⚪ Minimal · up to 0a3a9

The supply-chain audit policy changes are aligned across CI, local commands, and documentation, with no unresolved merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarises the main change: defining the CI security advisory posture for yanked, unsound, and unmaintained crates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lab-1152-advisory-posture

Comment @coderabbitai help to get the list of available commands.

@kodus-27b

This comment has been minimized.

Comment thread .github/workflows/security.yml
…lure (LAB-1152)

Kody flagged the proof-of-run guard as brittle on a warm index cache.
The premise is wrong — cargo-audit 0.22.1 prints 'Updating crates.io
index' unconditionally before the fetch attempt (auditor.rs), so a
fresh cache cannot suppress it; verified empirically cold and warm.

But the review surfaced a real hole in the opposite direction: on
index fetch/open failure the tool warns "couldn't update|open
crates.io index", skips the yank check entirely, and exits 0 — and
the guard's failure grep only matched "couldn't check", so the
weekly enforcing run would go green on a skipped check (the attempt
line prints before the failed fetch). Broaden the failure grep to all
three skip signals; keep the attempt-line grep, which is what catches
the check being disabled outright (e.g. a future -n).
@27Bslash6

Copy link
Copy Markdown
Contributor Author

@kody start-review

@kodus-27b

kodus-27b Bot commented Aug 30, 2026

Copy link
Copy Markdown

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

kodus-27b[bot]
kodus-27b Bot previously approved these changes Aug 30, 2026
…se (LAB-3406)

clippy 1.99 (beta) fires double_must_use nine times through the bare
#[must_use] that async-trait 0.1.89 emits on its Pin<Box<dyn Future>>
methods (rust-clippy#17529). async-trait 0.1.92 stopped emitting it
(dtolnay/async-trait#303). Lockfile-only; the transitive syn 3 entry is
pinned to 3.0.4 so the hunk is byte-identical to main (92637cc), which
took the same bump — keeps the PR mergeable without a lockfile conflict.
@27Bslash6

Copy link
Copy Markdown
Contributor Author

Pushed 0a3a93e to clear the red beta check (LAB-3406). It is a lockfile-only bump of async-trait 0.1.89 → 0.1.92: clippy 1.99 beta fires double_must_use on async-trait ≤ 0.1.91's generated Pin<Box<dyn Future>> methods (rust-lang/rust-clippy#17529, fixed upstream in dtolnay/async-trait#303). Same bump main already carries in 92637cc; transitive syn pinned to 3.0.4 so the hunk matches main byte-for-byte and the merge stays clean. Nothing in this PR's own diff changed. Local beta/stable clippy, tests, cargo deny and cargo audit --deny yanked all pass.

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.

1 participant