# 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.
