Skip to content

Port remaining production hardening and verify witness conformance in CI - #6

Merged
wolfv merged 1 commit into
mainfrom
feat/remaining-production-hardening
Sep 19, 2026
Merged

wolfv merged 1 commit into
mainfrom
feat/remaining-production-hardening

Conversation

@wolfv

@wolfv wolfv commented Sep 19, 2026

Copy link
Copy Markdown
Member

Summary

Selectively ports the still-useful changes from #4 onto current main, retaining #5's Rekor v2, persistent deduplication, strict signature verification, atomic witness/monitor updates, bounded HTTP clients, current dependencies, and contiguous serialized vindex indexing.

  • C2SP cosignature/v1 output from witnesses, monitors and in-process witnesses; strict verification of pinned external witness signatures, accepting alg-0x01 and alg-0x04 public keys without changing the existing EXTERNAL_WITNESSES / EXTERNAL_WITNESS_KEYS configuration. Timestamped witness signatures cannot satisfy log-signature verification.
  • Configurable publication quorum, counting distinct verified names/public keys. Tests cover missing witnesses and duplicate witness identities.
  • CRC32 v3 WAL (legacy v2 readable), snapshots/WAL compaction, automatic rebuild from entry bundles, strict contiguous replay after snapshots, rejection of incomplete bundles, and synchronization between indexing and snapshots.
  • SIGTERM handling for server/witness/monitor, server worker supervision, idle rate-limit bucket cleanup, request timeout, startup origin validation, release overflow checks, stricter tile paths and non-leaking internal-error responses.
  • Dedicated witness conformance CI job with locked Python dependencies and uploaded test reports.

Witness suite quality

The original HTTP suite mostly checked status codes and an em-dash prefix, which was insufficient. Every successful response now independently verifies the C2SP wire signature using Python cryptography: signer, alg-0x04 key ID, 76-byte encoding, timestamp and exact signed checkpoint body. Added verifier-tampering checks, process-restart persistence and simultaneous conflicting first checkpoints. Missing test case files fail rather than silently skip; unsupported public-only custom log configurations fail explicitly.

The new concurrency test exposed a real SQLite initialization race (500 on simultaneous first requests). get_or_init now uses a conflict-safe insert then reads the winning state, preserving main's atomic conditional state updates.

This is our regression suite, not an official C2SP certification. Its README documents that it uses our Python Merkle helper and SQLite, and does not simulate power loss or exhaust the protocol. Existing Rust security tests and PostgreSQL CI coverage remain enabled.

Deliberately not ported

  • The bulk importer: it bypasses current log-mode and Rekor deduplication invariants and needs its own mode-aware design/review. No raw JSONL backdoor into Rekor logs.
  • Staging-specific Fly configuration, stale remaining-work/benchmark claims and legacy-only benchmark harness.
  • Trusting arbitrary forwarding headers for rate limiting. Peer-IP extraction and newer security fixes remain intact.
  • Duplicate older implementations of atomic state updates, monitor validation, rate-limit replenish fixes and atomic filesystem writes already present on main.

Validation

  • cargo test --workspace: passes (PostgreSQL-specific test needs CI's configured service).
  • cargo clippy --workspace --all-targets --all-features -- -D warnings: passes.
  • cargo fmt --all -- --check: passes.
  • cd witness-conformance && uv run --locked pytest --entrypoint=../target/debug/witness -q: 31 passed.
  • Go Rekor interoperability remains checked in CI; Go is not installed in the local environment.

Supersedes the production changes in #4; does not include its bulk-import/deployment scope.

@wolfv
wolfv merged commit d869718 into main Sep 19, 2026
8 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.

1 participant