From 25356debcce4118cdfa86842029278fde1e64518 Mon Sep 17 00:00:00 2001 From: Gab <24553253+gabrix73@users.noreply.github.com> Date: Tue, 18 Aug 2026 21:43:48 +0200 Subject: Publish FOG design documentation and Merkle tree --- docs/FOG-LOCAL-POC.md | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 docs/FOG-LOCAL-POC.md (limited to 'docs/FOG-LOCAL-POC.md') diff --git a/docs/FOG-LOCAL-POC.md b/docs/FOG-LOCAL-POC.md new file mode 100644 index 0000000..d156e10 --- /dev/null +++ b/docs/FOG-LOCAL-POC.md @@ -0,0 +1,345 @@ +# FOG Local Podman PoC + +Status: Runnable Fixture 0.2 + +Date: 2026-08-08 + +## 1. Purpose and Claim Boundary + +`FOG-LOCAL-POC-1` is the first runnable local process, isolation, baseline, +and failure-test boundary for FOG. It turns the architecture's role and +reachability rules into a validated rootless Podman fixture. + +The machine-readable artifacts and validator are in `../deploy/podman/`. + +This definition is functional evidence only. It cannot demonstrate operator +independence, infrastructure diversity, an anonymity set, traffic-analysis +resistance, availability, capacity, production key handling, or a safe +numeric protocol profile. All containers run on one host under one user and +therefore share a host kernel, storage stack, management account, clock, and +failure domain. + +The fixture does not activate FOG-WIRE, FOG-PKI, KEMSphinx, storage, +messaging, cover, delay, polling, retry, or degraded-mode parameters. It does +not implement or substitute for any protocol daemon. Its deliberately bounded +and non-cryptographic transport is named `FOG-POC-FIXTURE-1`. + +## 2. Requirements + +The PoC definition is governed by: + +- `ARC-001`, separate trust domains even when co-located; +- `ARC-002`, a networkless Composer; +- `ARC-003`, no data-plane bypass; +- `ARC-005`, complete authenticated network views; +- `ARC-007`, one private-key owner and no shared writable state; +- `ARC-008`, bounded configuration, work, and state; +- `ARC-009`, no privacy-weakening fallback; +- `IF-06` through `IF-09`, exact online data-plane adjacencies; +- `TM-NET-03`, `TM-NET-04`, `TM-PKI-02`, `TM-PKI-03`, + `TM-ROLE-01`, `TM-ROLE-02`, `TM-ROLE-03`, `TM-CRYPTO-01`, and + `TM-AVAIL-01`; +- `PKI-INV-01`, `PKI-INV-03`, `PKI-INV-04`, and `PKI-INV-08`; +- `WIRE-INV-07`, `WIRE-INV-08`, `WIRE-INV-09`, and `WIRE-INV-10`. + +Podman 5.8.3 and podman-compose 1.6.0 are present on the first local host. The +runtime contract targets rootless Podman and internal bridge networks. Podman +documents `network=none` as a network namespace without configured network +interfaces and an internal bridge as restricting external access. These +runtime properties remain acceptance-test subjects rather than assumptions. + +## 3. Deployment Stages + +### 3.1 Definition stage, completed + +The checked-in JSON plan and standard-library Go validator define roles, +network edges, private state ownership, container hardening, resource +containment, and the mandatory fault matrix. + +This stage prevented placeholder ports, fake cryptography, reusable example +keys, or an unreviewed generic fixture protocol from becoming accidental +implementation defaults. + +### 3.2 Fixture stage, current + +The executable harness provides explicitly named PoC-only binaries. They +exercise process lifecycle, exact opaque object geometry, network +reachability, bounded connections and work, restart behavior, role-local +state, secret isolation, and fault outcomes. They do not call their transport +FOG-WIRE or their public data FOG-PKI. + +The stage builds one scratch image without build-time networking, addresses it +by its local OCI manifest digest, and deterministically generates a Compose +manifest from validated `topology.json`. The internal TCP port `17001` belongs +only to the fixture harness and is not a selected FOG protocol port. + +### 3.3 Protocol-functional stage + +Actual role executables replace the fixtures only after the relevant exact +profiles, libraries, parsers, key formats, and conformance vectors are +selected. Each replacement must retain the same state and network ownership +contract and pass the same fault matrix. + +## 4. Role Inventory + +| Instance | Executable contract | Purpose | Network state | +| --- | --- | --- | --- | +| `composer-fixture` | `fog-poc-composer-fixture` | Networkless public-fixture acceptance state | `none` | +| `authority-fixture` | `fog-poc-authority-fixture` | Networkless authority-condition state | `none` | +| `relay` | `fog-client-relay` | Opaque client queue and entry submission | private pairwise network | +| `entry` | `fog-entry` | Entry boundary outside the mix layers | two private pairwise networks | +| `mix-l1` | `fog-mix`, fixed layer 1 | First mix position | two private pairwise networks | +| `mix-l2` | `fog-mix`, fixed layer 2 | Second mix position | two private pairwise networks | +| `mix-l3` | `fog-mix`, fixed layer 3 | Third mix position | two private pairwise networks | +| `courier` | `fog-courier` | Terminal request and replica mediation | five private pairwise networks | +| `store-a` through `store-d` | `fog-store` | Four separate storage fixtures | one private pairwise network each | + +The three-node description refers to the three fixed mix positions. Entry and +courier remain outside those three KEMSphinx delay layers. Four storage +containers exist so the PoC does not normalize a smaller shared storage +fixture into the intended architecture. + +The authority and Composer fixtures are networkless process and state +boundaries. Fault flags model only coarse acceptance states such as quorum +loss or conflicting public fixtures. They do not create signatures, +consensus objects, identities, contacts, capabilities, or message secrets and +supply no authority-independence claim. + +An observer is not in this first topology. `FOG-OBSERVABILITY-1` now defines +the separate structural logging and aggregate contract, but no observer, +numeric observability profile, or IF-11 codec is active in this fixture. No +container may substitute ordinary logs or packet traces for `fog-observer`. + +## 5. Network Segmentation + +Every declared network is internal and contains exactly two roles: + +```text +relay <-> entry <-> mix-l1 <-> mix-l2 <-> mix-l3 <-> courier + |-- store-a + |-- store-b + |-- store-c + `-- store-d +``` + +The nine networks are: + +| Network | Members | Interface | +| --- | --- | --- | +| `relay-entry` | relay, entry | `IF-06` | +| `entry-l1` | entry, mix-l1 | `IF-07` | +| `l1-l2` | mix-l1, mix-l2 | `IF-07` | +| `l2-l3` | mix-l2, mix-l3 | `IF-07` | +| `l3-courier` | mix-l3, courier | `IF-08` | +| `courier-store-a` | courier, store-a | `IF-09` | +| `courier-store-b` | courier, store-b | `IF-09` | +| `courier-store-c` | courier, store-c | `IF-09` | +| `courier-store-d` | courier, store-d | `IF-09` | + +There is no shared data-plane bridge. No role uses the host network. No +container port is published to the host. The Composer and authority fixtures +use `network=none`. Coarse public-data failure conditions are written only to +the targeted role's private fixture state and contain no consensus bytes or +cryptographic material. + +The runnable harness proves that containers cannot reach an +external address, host-local services, or undeclared roles. Name resolution +success is not sufficient evidence of an authorized protocol edge, and +failure of one edge must never create another. + +## 6. Filesystem, Keys, and Container Hardening + +Every role-container contract requires: + +- rootless execution as a dedicated non-root container user; +- one digest-pinned immutable image; +- a read-only root filesystem; +- `no-new-privileges`; +- all Linux capabilities dropped; +- no privileged mode, device passthrough, host PID, host IPC, host UTS, or + host network namespace; +- private `/run` and `/tmp` tmpfs mounts with bounded sizes in the generated + manifest; +- exactly one role-owned writable state volume; +- no source checkout, container socket, generic host directory, or other + role's state mounted; +- disabled core dumps and no secret-bearing diagnostic output; +- explicit CPU, memory, PID, file-descriptor, connection, and queue limits. + +The checked-in CPU, memory, and PID values are harness containment limits, not +capacity results or protocol profile parameters. Their only purpose is to +make local fault tests bounded. + +One 32-byte non-cryptographic fixture token per role is generated in memory +from the operating-system CSPRNG. It is streamed into a distinct Podman Secret +object. The installed `podman-compose` plus `runc` combination cannot mount +that file directly into a read-only role root filesystem, so a networkless, +bounded, one-shot stager copies it into a newly created role-specific volume +with mode `0400`. The Podman Secret source is removed immediately and the role +mounts only its own secret volume read-only. + +Tokens never enter source, JSON plans, images, host-supplied files, command +arguments, environment templates, logs, test reports, or public fixture objects. A +constant-time runtime challenge confirms that each role received its intended +token without reporting a value or digest. Teardown removes the disposable +secret and state volumes. Destruction of the `mix-l2` replay fixture requires +the separate `--allow-destructive` option and names the exact target first. + +## 7. Baseline Functional Flow + +The runnable fixture performs these steps from clean role state: + +1. Start the Composer and authority process fixtures without a configured + network interface and validate their private state and token scope. +2. Generate one opaque fixed-size packet fixture with the current 16,150-byte + candidate geometry, clearly labeled as non-cryptographic PoC data. +3. Admit the fixture only at relay, then traverse entry, mix-l1, mix-l2, + mix-l3, and courier in that order. +4. Dispatch one bounded opaque operation from courier to the storage fixture + set and collect only the modeled receipt result. +5. Return a bounded opaque result through the declared reverse adjacency, + without creating a direct courier-to-relay connection. +6. Verify that no role mounted another role's state or token and that no + container gained an undeclared network. +7. Report only the role names, scenario IDs, and coarse fixture outcomes. + +The successful first-host result is `complete-fixture`, four modeled fixture +receipts, and four fixture hops after entry. These counts describe only this +test transport and must not be read as storage durability or anonymity +evidence. + +The harness keeps no packet transcript. Container logging is disabled and no +result contains packet bytes, object identifiers, per-packet timing, keys, +route secrets, capabilities, or source addresses. + +## 8. Fault Matrix + +`fault-scenarios.json` defines fifteen mandatory scenarios: + +| Scenario | Expected invariant | +| --- | --- | +| `forbidden-role-edge` | Only declared pairwise reachability exists | +| `entry-stop` | No relay-to-layer-1 fallback | +| `mix-layer-two-stop` | No layer skip or courier delivery | +| `layer-two-three-partition` | Bounded failure on the same adjacency | +| `mix-replay-state-loss` | Same-epoch processing fails closed | +| `stale-consensus` | New work stops at hard expiry | +| `same-epoch-consensus-fork` | Consumers freeze instead of choosing a view | +| `authority-quorum-loss` | Partial views and insufficient signatures fail | +| `clock-uncertainty` | Time-sensitive acceptance stops | +| `single-store-loss` | No false durability result | +| `receipt-quorum-loss` | Required receipts cannot be fabricated | +| `courier-stop` | No layer-3 or client connection to storage | +| `entry-handshake-flood` | Work and responses remain bounded | +| `cover-process-stop` | A cover-dependent claim cannot continue silently | +| `role-secret-isolation` | No cross-role state or fixture-token access | + +Each scenario names target roles, the abstract action, expected behavior, +explicitly prohibited fallback, requirement IDs, automation status, and +whether it mutates role state. Abstract actions deliberately contain no shell +command. The fault runner resolves container and volume targets +from the validated plan, show destructive targets before execution, and start +state-destructive tests from disposable snapshots. + +No scenario may run concurrently with another. Each begins from a documented +clean baseline so an earlier partition, stopped role, or modified volume +cannot make a later test pass for the wrong reason. + +On the first host, all fourteen automatable scenarios pass. The +`cover-process-stop` row remains `not-automatable`: the fixture has no cover +scheduler and therefore cannot silently retain a cover or unobservability +claim. The effective runtime verifier completes 239 checks before the fault +matrix begins. + +## 9. Acceptance Gates + +### 9.1 Definition gate, satisfied + +- The strict parser accepts the checked-in topology and fault plan. +- Duplicate or unknown fields, trailing JSON, oversized or non-regular inputs + fail. +- Required roles, exact mix layers, four stores, pairwise internal networks, + private state, private secret scopes, hardening flags, and resource bounds + are enforced. +- Forbidden edges, host exposure, shared volumes, missing faults, and invalid + traceability references fail validation. +- The validator uses only the Go standard library and performs no network or + filesystem writes. + +### 9.2 Runnable fixture gate, satisfied + +- One local scratch image is built and referenced by its OCI manifest digest. +- PoC-only fixture roles and future online security roles have distinct + executable entrypoints. +- The generated Compose manifest derives from validated `topology.json`. +- Effective Podman state, not only source YAML, passes 239 runtime checks. +- Rootless operation, pairwise internal networks, failed host and external + probes, no published ports, private volumes, read-only roots, zero process + capability sets, and role-token isolation pass. +- The baseline and all fourteen automatable fault scenarios pass. +- Reports contain only coarse outcomes. The cover-only row is explicitly not + automatable and grants no cover claim. + +### 9.3 Protocol-functional gate, not yet satisfied + +- Replace fixtures with exact parsers, cryptographic profiles, key ownership, + replay persistence, command policy, consensus transitions, and storage + receipts from the normative specifications. +- Pass the PKI and FOG-WIRE functional PoC gates. +- Add parser conformance, fuzz, race, allocation, load, and mutation tests. +- Demonstrate current and next epoch transition, rollback refusal, revocation, + per-record rekey, fresh handshakes, exact packet geometry, and strict + failure behavior. + +None of these gates creates an anonymity or production claim. + +## 10. Validation Commands + +From `deploy/podman/`: + +```sh +gofmt -d cmd/fog-poc-plan/*.go internal/plan/*.go +go test ./... +go test -race ./... +go vet ./... +go run ./cmd/fog-poc-plan +go run -buildvcs=false ./cmd/fog-poc-lab -action all -allow-destructive +``` + +The expected summary is twelve roles, three mix layers, four stores, nine +internal pairwise networks, fifteen fault scenarios, and the claim +`functional-only`. + +## 11. Deferred Decisions + +This definition does not select: + +- a Noise or hybrid post-quantum construction, library, profile ID, port, + record size, timer, socket profile, or command shape; +- a PKI authentication suite, exact epoch schedule, topology shuffle, + authority wire-key profile, or recovery ceremony; +- an active KEMSphinx suite or entry capsule; +- storage request geometry, durability profile, or receipt primitive; +- cover, delay, loop, retry, polling, queue, or shutdown distributions; +- observability fields, aggregation windows, release delays, or thresholds; +- a production container base image, release channel, deployment user, host + firewall, backup, or update mechanism. + +These remain explicit dependencies. The fixture generator supplies none of +them. Any future protocol-functional manifest generator must fail when a +required value is absent rather than converting fixture values into an +undocumented protocol default. + +## 12. References + +- FOG threat model: `FOG-THREAT-MODEL.md` +- FOG architecture: `FOG-ARCHITECTURE.md` +- FOG PKI: `FOG-PKI.md` +- FOG wire protocol: `FOG-WIRE.md` +- FOG traffic simulator: `FOG-SIMULATION.md` +- Podman run and network modes: + +- Podman internal network option: + +- Podman secret management: + -- cgit v1.2.3