Skip to content

ci: add Miri job for vitaminc-protected's unsafe (#213 fallback)#214

Merged
coderdan merged 1 commit into
mainfrom
ci/add-protected-miri
Jun 23, 2026
Merged

ci: add Miri job for vitaminc-protected's unsafe (#213 fallback)#214
coderdan merged 1 commit into
mainfrom
ci/add-protected-miri

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

What

Adds a Miri CI job (.github/workflows/miri.yml) that runs cargo +nightly miri test -p vitaminc-protected on every PR touching the crate.

Why

vitaminc-protected is the only crate in the workspace with first-party unsafe: the move-out in move_inner_out (ptr::read + mem::forget) introduced in #185, which is how risky_unwrap / flatten / transpose move the inner secret out past the zeroizing Drop. Miri interprets the tests under the Stacked/Tree Borrows model, catching aliasing/provenance UB that a normal test run (and even ASan) can miss.

This is the agreed #213 fallback: a full #![forbid(unsafe_code)] on the crate proved impractical (it would require either an Option<T> field — ~44 .0 rewrites plus impossible-panic .expect() calls and a layout cost — or a breaking risky_unwrap API change). Rather than force an ugly rewrite of a foundational primitive, we keep the single audited unsafe move-out and guard it with Miri in CI. It also closes the review ask James raised on #185.

Note on history

This job was authored on the #185 branch but landed ~12 minutes after that PR merged, so it never reached main. This PR re-lands it cleanly off current main — no code changes, CI only.

Scope

Scoped to vitaminc-protected on purpose: Miri can't execute the aws-lc-rs FFI (vitaminc-encrypt) or the entropy syscalls in random/permutation/password, and protected is where the only unsafe lives. Expand the matrix if other crates grow pure-Rust unsafe.

Refs #213.

https://claude.ai/code/session_015jJwUcMbyjuttxTLh4vh6q

 fallback)

`vitaminc-protected` is the only crate with first-party `unsafe` — the move-out
in `move_inner_out` (`ptr::read` + `mem::forget`) behind `risky_unwrap` /
`flatten` / `transpose`. This runs its tests + doctests under Miri on every PR
touching the crate, catching aliasing/provenance UB a normal run can't. It's the
standing guardrail requested in review.

Context: full `#![forbid(unsafe_code)]` was evaluated and is impractical here —
it needs either an `Option<T>` field (~44 `.0` rewrites across the crate plus
impossible `.expect()` panics and a layout cost) or a breaking change to
`risky_unwrap`'s return type. Per #213 this Miri check is the agreed fallback for
the one irreducible move-out unsafe. Tracked in #213.

Claude-Session: https://claude.ai/code/session_015jJwUcMbyjuttxTLh4vh6q

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated GitHub Actions workflow to run the vitaminc-protected crate’s test suite under Miri on relevant pull requests, providing CI coverage for the workspace’s only first-party unsafe code.

Changes:

  • Introduces a new .github/workflows/miri.yml workflow triggered on PRs that modify packages/protected/**.
  • Sets up Rust nightly with the Miri component and runs cargo +nightly miri test -p vitaminc-protected.
  • Adds CI ergonomics (caching + concurrency cancellation) for faster, less noisy runs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +62 to +68
- name: miri test (vitaminc-protected)
# Interprets the protected unit tests + doctests under Miri. The
# move-out regression tests (drop_zeroizes_inner /
# risky_unwrap_does_not_zeroize / flatten / transpose) exercise the one
# unsafe block; Miri proves it has no UB. The first run builds a Miri
# sysroot (a few minutes); subsequent cached runs are quick.
run: cargo +nightly miri test -p vitaminc-protected

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong, @copilot.

Look at the step immediately above.

It does exactly what is suggested.

Try harder.

@auxesis auxesis left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good overall improvement, thanks @coderdan.

@coderdan
coderdan merged commit 3c3f604 into main Jun 23, 2026
3 checks passed
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.

3 participants