Phase 1: supply-chain, regression tests, and release tooling#21
Open
johnzfitch wants to merge 3 commits into
Open
Phase 1: supply-chain, regression tests, and release tooling#21johnzfitch wants to merge 3 commits into
johnzfitch wants to merge 3 commits into
Conversation
Implements Phase 1 of the next-level roadmap (distribution + hardening), all within AGENTS.md "always safe" boundaries -- no crypto or vault-format changes. Supply chain: - Add deny.toml (cargo-deny): permissive license allowlist, crates.io-only sources, and a hard single-version rule for the core crypto crates (ml-kem, x25519-dalek, aes-gcm, argon2, sha2, hmac, hkdf). Validated offline with cargo-deny 0.16.4 (bans/licenses/sources ok). - Add a cargo-deny CI job alongside the existing rustsec audit-check. Regression tests (close the deferred SECURITY-AUDIT.md test gaps): - header_tamper_v7: every v7 key-commitment-covered header field is rejected at unlock when tampered. - downgrade_rejected: a v7 body claiming an older version is rejected. - argon2_dos: hostile KDF params (memory/time/parallelism/algorithm) are rejected by validate_kdf_params before Argon2 runs (asserted fast). - export_env_quoting: shell-metachar secret values round-trip byte-exactly through `eval` in /bin/sh and never execute (injection canary). - stdin_overflow: oversized piped `set` input is refused and not stored; at-cap input is accepted. Distribution: - Cargo.toml: add repository/readme/keywords/categories + exclude paper media, historical source snapshot, and audit/CI/agent files from the published crate (verified via `cargo package --list`). - release.yml: tag-triggered portable cross-platform release binaries with SHA256 checksums, neutralizing the repo's target-cpu=native pin.
…l-kem) The advisories check denied five findings that the existing rustsec audit-check job only warns on. All are known and accepted: - RUSTSEC-2024-0381 / 2026-0162 / 2026-0163: the pqcrypto-* crates are the read-only legacy v1-v5 Kyber migration path (feature = "legacy-migration"). v6+ vaults use the maintained ml-kem crate. 2024-0381 is already accepted in .cargo/audit.toml; the two 2026 IDs are its newly-split siblings. - RUSTSEC-2026-0097 (rand 0.8.5 unsound): triggers only via a custom `log` logger calling thread_rng(); dota uses OsRng directly. Patch bump to rand >=0.8.6 tracked as follow-up. - digest 0.11.1 yanked: pulled in transitively by the pinned ml-kem 0.3.2, whose byte layout is part of the v7 on-disk contract. Set yanked = "warn" since the pin is not ours to bump. Each ignore carries a documented reason. Validated locally: the config parses and bans/licenses/sources pass (advisories DB fetch needs network, available in CI).
Contributor
There was a problem hiding this comment.
Pull request overview
Phase 1 of the project roadmap focused on tightening supply-chain controls, adding security/regression coverage around v7 vault integrity and CLI edge-cases, and introducing tag-driven release automation needed for future distribution work.
Changes:
- Add new integration/regression tests covering v7 header tampering, anti-rollback, Argon2 DoS parameter validation,
export-envshell-safe quoting, and stdin size limits fordota set. - Introduce
cargo-denypolicy (deny.toml) and wire it into CI as a dedicated “deny” job. - Add crates.io metadata and exclusions, and add a tag-triggered GitHub Actions release workflow producing multi-platform binaries with checksums.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/stdin_overflow.rs | E2E regression tests for stdin secret-size cap enforcement. |
| tests/header_tamper_v7.rs | Regression tests ensuring v7 key-commitment detects header tampering. |
| tests/export_env_quoting.rs | E2E regression tests ensuring export-env output is safe to eval and round-trips exactly. |
| tests/downgrade_rejected.rs | Regression tests for anti-rollback by tampering version on a v7 vault. |
| tests/argon2_dos.rs | Regression tests ensuring hostile KDF params are rejected before Argon2 executes. |
| deny.toml | New cargo-deny config: license allowlist, sources restriction, and crypto-crate single-version enforcement. |
| Cargo.toml | Add crates.io metadata and exclude non-distribution artifacts from packaging. |
| .github/workflows/release.yml | New tag-triggered release workflow building portable binaries + checksums. |
| .github/workflows/ci.yml | Add CI job running cargo deny check advisories bans licenses sources. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- stdin_overflow: helper returns stderr only, not 'combined stderr'. - argon2_dos: use 1_048_576 KiB so the value matches the '1 GiB' comment; note memory_cost is in KiB. Still far above the 256 MiB ceiling. - header_tamper_v7: helper asserts internally and returns (), so describe it as asserting the unlock fails rather than returning a result.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
This is Phase 1 of a phased "next level" roadmap for dota. The roadmap sequences four directions (security/v8, distribution, research/paper, features) by dependency, shipping the lowest-risk momentum first and isolating the eventual
v8format break into its own later release.Phase 1 deliberately stays within
AGENTS.md"always safe" territory: no cryptographic or vault-format changes. It closes the deferred supply-chain and test items fromSECURITY-AUDIT.mdand stands up the release machinery that later phases will need.Supply chain
deny.toml(cargo-deny): vetted permissive license allowlist, crates.io-only sources, and a hard single-version rule for the core crypto crates (ml-kem,x25519-dalek,aes-gcm,argon2,sha2,hmac,hkdf) — a duplicate copy of any of these would silently widen the trusted-code surface. Transitive non-crypto duplicates (thedigest/crypto-common0.10-vs-0.2 split pulled in byml-kem, plus Windows target crates) arewarn, notdeny.bans ok, licenses ok, sources ok.denyjob runningcheck advisories bans licenses sources, alongside the existingrustsec/audit-check.Regression tests (close deferred
SECURITY-AUDIT.mdgaps)All drive the public
dotaAPI or the real binary; 18 new test cases.header_tamper_v7— every field covered by the v7 HMAC key commitment (KDF params/salt, both public keys, suite, min_version) is rejected at unlock when tampered.downgrade_rejected— a genuine v7 body that lies about itsversion(claims v6/v5/v1) is rejected.argon2_dos— hostile KDF params (1 GiB memory, huge time/parallelism, unknown algorithm) are rejected byvalidate_kdf_paramsbefore Argon2 runs (asserted via a sub-second deadline).export_env_quoting— secret values full of shell metacharacters (',",;,$( ), backticks, newlines) round-trip byte-for-byte throughevalin/bin/sh, and an injection canary confirms nothing executes.stdin_overflow— pipedsetinput one byte over the 1 MiB cap is refused and not stored; an at-cap value is accepted.Distribution
Cargo.toml:repository/readme/keywords/categoriesfor crates.io, plusexcludeto keep the published crate lean (drops paper media, the historicaldotav7/source snapshot, the audit doc, and CI/agent dirs). Verified withcargo package --list.release.yml: tag-triggered (v*) portable cross-platform release binaries (linux gnu/musl, macOS x86_64/aarch64, windows) with SHA256 checksums, neutralizing the repo'starget-cpu=nativepin so artifacts run on older user CPUs.Verification
cargo fmt --all -- --check✓cargo clippy --all-targets --all-features -- -D warnings✓cargo test --all -- --test-threads=1✓ (full suite, including the 18 new cases)cargo deny check licenses bans sources✓ (offline)cargo package --list✓ (excludes confirmed)Deferred (next, with sign-off)
clap_complete,clap_mangen) — "ask first" perAGENTS.md.install.shdepend on the first tagged release existing (consumerelease.ymlartifacts).v8: seed-form ML-KEM keys + encrypted metadata) is the isolated format break, planned for its own major release.https://claude.ai/code/session_01Shd8ksfntVUy49DyVtaLqH
Generated by Claude Code