Status honesty + real HMAC attestation; refuse fake asymmetric keys#75
Merged
Conversation
TOPOLOGY.md advertised "OVERALL 100% v1.0 Production Ready" and per-
component 100%s ("MPR security by construction proven", "audit trail
validated") while STATE.a2ml records completion 60% / CRG grade D and
READINESS.md grades the project D (Alpha, Unstable). This is the
"dashboard that lies" pattern.
- Rewrite the completion dashboard to summarise STATE.a2ml / READINESS.md
(60%, Grade D), naming the real caveats: homerolled attestation MAC,
label-only Ed25519/X25519, obliteration not guaranteed on SSD/CoW,
formal proofs pending and unlinked to the Rust.
- Add a prominent ARCHIVED banner to TESTING-REPORT.adoc (a stale
2025-12-29 snapshot whose "all tests passed / robust" framing overstates
current status), pointing readers to READINESS.md / STATE.a2ml.
No code changes; documentation truthfulness only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz
…etric keys Two honesty/security fixes flagged by the threat model and STATE.a2ml. B3 — attestation MAC: - Replace the homerolled `SHA256(key || data || previous_hash)` (not a MAC; banned by the Trustfile `no-homerolled-hmac` invariant) with a real HMAC-SHA256 via the `hmac` crate (RFC 2104), with a versioned scheme label bound in as a domain separator (januskey.attestation.HMAC-SHA256.v1). - `compute_attestation` now returns Result and hard-errors when no key is set, removing the `unwrap_or([0u8; 32])` all-zero-key fallback that silently produced forgeable, unkeyed attestations. - Producer (log_event) and verifier (verify_integrity) both propagate the error, so they stay consistent. B4 — fake asymmetric crypto: - `SecretKey::generate()` only ever produces 32 random bytes and ignores the algorithm, so selecting ed25519/x25519 yielded a random blob merely labelled "Ed25519"/"X25519" — not a keypair. Refuse generation of these types at the CLI with a clear "not implemented" error. Enum variants are retained (documented as reserved/unimplemented) so historical serialized metadata and audit entries still deserialize. Regression tests added: test_attestation_refused_without_key, test_attestation_is_genuinely_keyed (wrong key fails verification — a plain hash would not catch this, proving the MAC is genuinely keyed). Verified: `cargo build -p januskey` clean; `cargo test -p januskey --lib` 26 passed / 0 failed; attestation E2E + P2P chain-integrity tests pass. STATE.a2ml blockers updated (homerolled-hmac RESOLVED). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz
The `audit` CI job (cargo audit --deny warnings / --deny unmaintained) denied on two advisories, both pre-existing and unrelated to the crypto change on this branch. Resolve them at the source rather than ignoring: - Bump indicatif 0.17 -> 0.18: 0.18 drops the `number_prefix` dependency entirely, clearing RUSTSEC-2025-0119 (number_prefix unmaintained). Only ProgressBar + ProgressStyle::default_bar() are used here, stable across the bump; `cargo build -p januskey` is clean on 0.18.6. - Update anyhow 1.0.102 -> 1.0.103, the patched release for RUSTSEC-2026-0190 (unsound Error::downcast_mut). That API is not called anywhere in this codebase in any case. number_prefix is now absent from Cargo.lock; anyhow is 1.0.103. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz
Four CI checks failed on every PR (and on main) for reasons unrelated to any code change — the "CI that cannot pass" problem. Fix each: - rust-ci.yml: the job calls the shared reusable rust-ci-reusable.yml with no `with:` block, so its required `toolchain` input was empty and the "parse toolchain version" step failed with `'toolchain' is a required input`. Pass `toolchain: stable` (matches .tool-versions and the dtolnay/rust-toolchain pins in e2e.yml). - tests/aspect/cross_cutting_test.sh: the Documentation check asserted README.adoc, but the repo ships README.md (root .adoc is EXPLAINME.adoc). Accept either; aspect suite now PASS 29 / FAIL 0. - cargo-audit.yml create-issue: `needs: audit` + `if: failure()` ran on PR events where GITHUB_TOKEN is read-only, so `gh issue create` 403'd. Guard with `&& github.event_name != 'pull_request'`; issues are still filed on push/schedule runs. Both workflow files keep their SPDX line-1 header and top-level permissions block (workflow-linter.yml requirements); YAML validated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz
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
Two related honesty problems flagged by the survey, threat model, and
STATE.a2ml: dashboards that overstate status, and cryptography that isn't what its labels claim.Changes
B1 — status reconciliation (docs)
TOPOLOGY.mdadvertised "OVERALL 100% v1.0 Production Ready" whileSTATE.a2mlrecords 60% / CRG grade D andREADINESS.mdgrades it D (Alpha, Unstable). Rewrote the completion dashboard to summarise the real state and name the actual caveats (homerolled MAC, label-only asymmetric crypto, obliteration not guaranteed on SSD/CoW, formal proofs pending).TESTING-REPORT.adoc(2025-12-29) whose "all tests passed / robust" framing overstates status.B3 — real attestation MAC (code)
SHA256(key || data || previous_hash)(not a MAC; banned by Trustfileno-homerolled-hmac) with a real HMAC-SHA256 (hmaccrate, RFC 2104) with a versioned domain separator.compute_attestationnow returnsResultand hard-errors when no key is set, removing theunwrap_or([0u8; 32])all-zero-key fallback that silently produced forgeable attestations. Producer and verifier both propagate the error.B4 — no fake asymmetric crypto (code)
SecretKey::generate()only produces 32 random bytes and ignores the algorithm, soed25519/x25519yielded a random blob merely labelled asymmetric. Generation of these types is now refused at the CLI with a clear "not implemented" error. Enum variants are retained (documented reserved/unimplemented) for backward-compatible deserialization.Verification
cargo build -p januskey— clean (pre-existing dead-code warnings only).cargo test -p januskey --lib— 26 passed / 0 failed; attestation E2E + P2P chain-integrity pass.test_attestation_refused_without_key,test_attestation_is_genuinely_keyed(wrong key fails verification — proves the MAC is genuinely keyed, which a plain hash would not catch).STATE.a2mlblockers updated (homerolled-hmac→ RESOLVED).Context
Tasks B1/B3/B4 of a broader estate assessment. Draft pending human review. Note: on-disk audit logs written under the old homerolled scheme will not verify under the new versioned MAC (intentional, alpha-stage).
🤖 Generated with Claude Code
https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz
Generated by Claude Code