Skip to content

Forensic sealing (BEACON_COMMIT), ForensicBundle export, account registry, BSM adapter#20

Merged
mdheller merged 3 commits into
mainfrom
feature/exodus-forensic-sealing
Jul 5, 2026
Merged

Forensic sealing (BEACON_COMMIT), ForensicBundle export, account registry, BSM adapter#20
mdheller merged 3 commits into
mainfrom
feature/exodus-forensic-sealing

Conversation

@mdheller

Copy link
Copy Markdown
Member

Closes the cryptographic + operational gaps between the committed Phase-0 metadata schema pack and a court-presentable evidence corpus — Metadata Standards §6/§8/§10, and the doc's GAP-06/07/08/09/10. Stacks on the zone-gate engine (#19).

Forensic sealing — scripts/exodus_seal.py (GAP-09, atom signing GAP-06)

TriTRPC BEACON_COMMIT custody sealing. A detached Ed25519 signature (deterministic, RFC 8032) over a canonical commit statement that binds content-hash ↔ signer ↔ sealing-time, plus a BLAKE3-256 frame hash (SHA-256 fallback, always labeled).

  • verify_receipt() is independently verifiable from the receipt JSON + embedded public key — the FRE 902(14) requirement; an opposing expert needs nothing from the platform.
  • Deterministic replay harness: committed receipts re-seal byte-for-byte (test_exodus_seal.py). This is the legal replay harness, not a test convenience.

ForensicBundle export — scripts/exodus_bundle.py (GAP-07)

build_bundle() → §10 ForensicBundle (manifest + compact custody snapshot + replay manifest + BLAKE3-256 & SHA-256 master hashes + Ed25519 seal). verify_bundle() re-derives every hash and checks the signature from the JSON alone. Conforms to schemas/forensic-bundle.json.

Account registry — scripts/account_registry.py (GAP-08)

Backs CHK-09: only active accounts in examples/account-registry.json may enter intake.

BSM adapter — scripts/bsm_intake.py (AC-09, GAP-10)

praudit -xn → syscall sequence, uid/pid map, file-access timeline, privilege-escalation flags. Tested against a synthetic fixture (no real audit data / praudit needed). Implementation gap closed; only operational ingest on the target Mac remains.

Canonicalization

examples/serializer-spec.canon-v0_1.json pins CANON-v0.1 (sorted-key, whitespace-free, UTF-8 JSON), consistent with the shipped intake/gate hashing; versioned so a future move to deterministic CBOR won't break older receipts.

Verification

15 assertions across 2 test scripts, wired into CI (pip install cryptography blake3): byte-exact replay, independent verification, and tamper detection (payload, receipt metadata, signature, bundle core, manifest hash, signature swap). All new instances validate against their schemas; existing validators still green.

Genuinely remaining (operational / key-custody, not implementation)

Run praudit against the live /var/audit; bind a production signing key + chain-of-trust (the committed key is a clearly-labeled synthetic test key); HellGraph atom persistence beyond the receipt layer.

🤖 Generated with Claude Code

…M adapter

Closes the cryptographic + operational gaps between the Phase-0 schema pack and
a court-presentable corpus (Metadata Standards §6/§8/§10; GAP-06/07/08/09/10).

- scripts/exodus_seal.py: TriTRPC BEACON_COMMIT custody sealing. Ed25519
  (deterministic, RFC 8032) detached signature over a canonical commit
  statement binding content-hash <-> signer <-> time; BLAKE3-256 frame hash
  (SHA-256 fallback, labeled). verify_receipt() is independently verifiable from
  the receipt JSON + embedded public key (FRE 902(14)).
- scripts/exodus_bundle.py: §10 ForensicBundle build + independent verify
  (BLAKE3-256 + SHA-256 master hashes, sealed; conforms to forensic-bundle.json).
- scripts/account_registry.py + schemas/account-registry.schema.json +
  examples/account-registry.json: backs CHK-09 (GAP-08).
- scripts/bsm_intake.py + fixture: praudit -xn -> AC-09 enrichments
  (syscall seq, uid/pid map, file-access timeline, privilege-escalation flags);
  implementation gap closed, only operational ingest remains (GAP-10).
- examples/serializer-spec.canon-v0_1.json: pins CANON-v0.1 (json-canonical).
- tests/sealing-fixtures + tests/bsm-fixtures + 2 test scripts wired into CI:
  byte-exact replay harness + tamper detection (15 assertions). CANON-v0.1
  serialization, Ed25519, BLAKE3 all real.
- CANON-v0.1 canonicalization, deterministic replay = the legal replay harness.

Remaining is operational/key-custody (run praudit on the Mac; bind a production
signing key + chain-of-trust), not implementation.
@gitguardian

gitguardian Bot commented Jun 29, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
34361131 Triggered Generic High Entropy Secret ed17b50 tests/sealing-fixtures/test-signing-key.json View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

mdheller added 2 commits July 5, 2026 17:25
…y from seed

Keeper review of PR #20 found real personal data in a PUBLIC repo. Sanitized:
- examples/account-registry.json: real account emails -> synthetic (example.org/.com)
- tests/bsm-fixtures + test_intake_adapters.py: /Users/mdheller/... mail path -> synthetic
- forensic-bundle.json: case_id MBA-2025-06-27-CS -> SYNTH-CASE-0001; filename -> synthetic
- tests/sealing-fixtures/test-signing-key.json (committed Ed25519 private key, GitGuardian red)
  REMOVED; replaced with test-signing-seed.json — the key is now DERIVED at runtime as
  sha256(seed), so no private key is committed.

Golden fixtures (custody-event.receipt.json, forensic-bundle.json) regenerated with the
derived key + synthetic data; the byte-exact replay + tamper harness still passes (10/10),
intake tests pass (5/5).
@mdheller

mdheller commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Sanitized + merging (keeper, 2026-07-05). Removed all real personal data (account emails, /Users/mdheller mail path, case_id MBA-2025-06-27-CS, filename) → synthetic; the committed Ed25519 test key is removed and now derived at runtime from a seed (no private key in tree). Golden fixtures regenerated; replay+tamper harness 10/10, intake 5/5.

GitGuardian is red on branch HISTORY only — an intermediate commit still contains the (synthetic, clearly-labelled) test key. Verified the branch tip tree has no key file (seed only) and mergeStateStatus=UNSTABLE/MERGEABLE (not a required check). Squash-merge collapses to the final tree, so the key never reaches main. Treat the old synthetic key value as burned (it was only ever a test fixture).

Separately flagged: examples/valid-evidence-artifact.json still carries the real filename — it is pre-existing on public main (not this PR) and needs a history scrub in a follow-up.

@mdheller mdheller merged commit 3dd12bb into main Jul 5, 2026
5 of 6 checks passed
@mdheller mdheller deleted the feature/exodus-forensic-sealing branch July 5, 2026 21:44
mdheller added a commit that referenced this pull request Jul 5, 2026
…act example (#23)

examples/valid-evidence-artifact.json carried the real-case original_filename
"console faults.rtf" (pre-existing on main, not from PR #20). Everything else in the
fixture is already synthetic. Forward-scrub to a synthetic filename.

NOTE: this file was already public on main, so the value persists in git history — a
history rewrite (filter-repo/BFG) is the complete fix and is a separate deliberate op
(rewrites public history; affects anyone who cloned).
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