# FOG Security Test Plan Status: Structural test plan Date: 2026-08-18 ## 1. Purpose and Claim Boundary This plan defines the security test families required before an operator alpha. It supplies test contracts, not passing protocol evidence. Existing non-cryptographic fixture results may validate the harness but cannot close a protocol-functional gate. Every retained result must identify the software revision, active profile digests, test configuration, host class, seed or corpus digest where relevant, start and end dates, pass criteria, observed failures, and artifact SHA-256. Private keys, capabilities, packet identifiers, user data, and fine-grained production traffic do not belong in test reports. ## 2. Test Levels | Level | Target | Minimum evidence | | --- | --- | --- | | Unit | pure codecs, state transitions, bounds, profile registry | deterministic tests and mutation cases | | Conformance | canonical bytes and public protocol behavior | vectors consumed by two independent implementations | | Integration | adjacent roles and complete route | fixed-profile success and fail-closed cases | | Fuzz | every untrusted parser and stateful sequence | retained corpus, crash triage, allocation ceilings | | Race | daemon concurrency and persistent state | race detector plus restart and contention cases | | Fault | process, network, disk, clock, and key failures | deterministic scenario result and restoration check | | Load | authenticated and unauthenticated saturation | CPU, memory, queue, latency, and amplification bounds | | Side channel | valid and invalid cryptographic paths | reviewed measurement method and statistical result | | Simulation | traffic, topology, compromise, suppression | scenario corpus, sensitivity analysis, confidence bounds | ## 3. Mandatory Adversarial Matrix | Family | Required scenarios | Required invariant | | --- | --- | --- | | Replay | duplicate packet, restart, replay-state loss, epoch overlap, reply reuse | no repeated semantic effect; unsafe replay state stops processing | | Tagging | mutate every authenticated field, packet truncation and extension, SURB mutation | uniform rejection before service effect | | n-1 | suppress background traffic, inject hostile traffic, isolate a target, stop cover process | measured isolation signal and explicit degraded or stopped state | | Flooding | pre-auth connections, malformed handshakes, fragments, queue pressure, storage fan-out | bounded CPU, memory, connections, disk, and response amplification | | Clock | forward and backward jump, excessive uncertainty, cross-authority disagreement | no fresh state outside validity; coarse fault only | | Consensus | stale, rollback, freeze, same-epoch fork, malformed mirror, hard expiry | no merge, downgrade, local synthesis, or trust-on-first-use recovery | | Authority | one offline, quorum loss, sign-once restart, online-key compromise, replacement | deterministic liveness loss without invalid consensus | | Node loss | entry, each mix layer, courier, reconnect storm, replay database corruption | no layer skip, direct fallback, or undeclared route | | Storage loss | one replica, quorum loss, stale replica, lost receipt, tombstone conflict | no fabricated durability or resurrection | | Network | fragmentation, reordering at application boundaries, partition, asymmetric loss | strict ordered wire state and bounded randomized recovery | | State | crash before and after atomic commit, restore old state, disk full, partial write | commit-before-effect and fail-closed recovery | | Supply chain | altered binary, dependency change, revoked release, rollback | verification failure or explicit stop, never silent acceptance | ## 4. Parser and Fuzz Targets Every versioned object parser must have a dedicated target for empty, truncated, oversized, non-canonical, duplicate, unknown-critical, trailing, deeply nested, maximum-count, and cross-version input. Stateful fuzzers must cover handshake, fragmentation, replay, consensus transition, ratchet, capability stream, receipt, tombstone, Composer import, recovery, update, and FOG-SX reconstruction sequences. Fuzz harnesses must enforce the protocol's allocation and work limits. A result is incomplete when the fuzzer merely avoids panics but permits unbounded memory, CPU, disk, file descriptors, goroutines, or cryptographic operations. ## 5. Local Alpha Laboratory Matrix The local laboratory uses three authority fixtures, two mixes per layer, one entry, one courier, and four stores. It must exercise both mix choices in every layer and cover at least: 1. all eight combinations of one mix per layer; 2. loss of either mix in each layer while an allowed alternate remains; 3. loss of both mixes in a layer with no bypass; 4. one authority offline with quorum preserved; 5. two authorities offline with no new consensus; 6. loss of one store and loss of the required receipt quorum; 7. partitions on every permitted adjacency and probes on every forbidden edge; 8. restoration that proves stale replay, consensus, and storage state is not silently reused. These scenarios validate orchestration and protocol behavior only. They do not close operator-independence or anonymity gates. ## 6. Pass and Failure Handling A test family passes only when all declared cases meet byte-exact or bounded numeric criteria and every failure has been triaged. Flaky, skipped, timed-out, or infrastructure-invalid cases are not passes. Expected failure tests must assert the exact permitted coarse outcome and the absence of forbidden side effects. Security regressions retain the smallest non-secret reproducer. Reports use aggregate timing and resource data and must not introduce packet-level production telemetry. High-severity unresolved findings keep the affected readiness gate open. ## 7. Required Commands by Go Module Each production or conformance Go module must pass: ```sh gofmt -d . go test ./... go test -race ./... go vet ./... ``` Parser modules additionally run their registered fuzz targets under a documented time and resource budget. Cryptographic modules run dependency verification, complete-operation benchmarks, invalid-input timing tests, and independent vector comparison. Container laboratories validate the effective runtime state, not only source manifests. ## 8. Gate Mapping The retained results map directly to `deploy/alpha/readiness.json`. Partial fixture evidence remains described in the gate note while status stays `open`. A gate changes to `pass` only after its complete scope has immutable evidence. The readiness validator does not run tests or trust filenames; it checks the declared status and evidence shape so review remains explicit.