Skip to content

Phase 1: supply-chain, regression tests, and release tooling#21

Open
johnzfitch wants to merge 3 commits into
mainfrom
claude/dota-next-level-plan-scWyw
Open

Phase 1: supply-chain, regression tests, and release tooling#21
johnzfitch wants to merge 3 commits into
mainfrom
claude/dota-next-level-plan-scWyw

Conversation

@johnzfitch

Copy link
Copy Markdown
Owner

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 v8 format 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 from SECURITY-AUDIT.md and 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 (the digest/crypto-common 0.10-vs-0.2 split pulled in by ml-kem, plus Windows target crates) are warn, not deny.
    • Validated offline with cargo-deny 0.16.4: bans ok, licenses ok, sources ok.
  • CI: new deny job running check advisories bans licenses sources, alongside the existing rustsec/audit-check.

Regression tests (close deferred SECURITY-AUDIT.md gaps)

All drive the public dota API 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 its version (claims v6/v5/v1) is rejected.
  • argon2_dos — hostile KDF params (1 GiB memory, huge time/parallelism, unknown algorithm) are rejected by validate_kdf_params before Argon2 runs (asserted via a sub-second deadline).
  • export_env_quoting — secret values full of shell metacharacters (', ", ;, $( ), backticks, newlines) round-trip byte-for-byte through eval in /bin/sh, and an injection canary confirms nothing executes.
  • stdin_overflow — piped set input one byte over the 1 MiB cap is refused and not stored; an at-cap value is accepted.

Distribution

  • Cargo.toml: repository/readme/keywords/categories for crates.io, plus exclude to keep the published crate lean (drops paper media, the historical dotav7/ source snapshot, the audit doc, and CI/agent dirs). Verified with cargo 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's target-cpu=native pin 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)

  • Shell completions + man pages need new build deps (clap_complete, clap_mangen) — "ask first" per AGENTS.md.
  • Homebrew formula + install.sh depend on the first tagged release existing (consume release.yml artifacts).
  • Phase 3 (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

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.
Copilot AI review requested due to automatic review settings June 13, 2026 23:54
…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).

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

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-env shell-safe quoting, and stdin size limits for dota set.
  • Introduce cargo-deny policy (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.

Comment thread tests/stdin_overflow.rs Outdated
Comment thread tests/argon2_dos.rs Outdated
Comment thread tests/header_tamper_v7.rs Outdated
- 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.
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