|
1 | 1 | // SPDX-License-Identifier: PMPL-1.0-or-later |
2 | | -= Project Wharf — Show Me The Receipts |
| 2 | +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
| 3 | += Project Wharf — Sovereign Web Hypervisor — Show Me The Receipts |
3 | 4 | :toc: |
4 | 5 | :icons: font |
5 | 6 |
|
6 | | -The README makes claims. This file backs them up. |
| 7 | +The README makes claims. This file backs them up. Wharf separates CMS |
| 8 | +administration (the Wharf controller, offline) from the live site runtime (the |
| 9 | +Yacht) using a Zero Trust mesh network (the Mooring). The core philosophy is |
| 10 | +the quote: "The gun should not be in the safe." |
| 11 | + |
| 12 | +== Claim: AST-aware database proxy that blocks writes to immutable tables |
7 | 13 |
|
8 | 14 | [quote, README] |
9 | 15 | ____ |
10 | | -The gun should not be in the safe. |
| 16 | +The Yacht Agent acts as a SQL proxy, parsing queries using an Abstract Syntax |
| 17 | +Tree (via sqlparser 0.39, not regex!) to enforce security policies. |
| 18 | +Mutable Tables (Blue Zone): content like comments — allowed to write. |
| 19 | +Immutable Tables (Red Zone): config like users and plugins — blocked unless |
| 20 | +from Wharf. |
| 21 | +INSERT INTO wp_users blocked: "Policy violation: write to immutable table wp_users" |
11 | 22 | ____ |
12 | 23 |
|
13 | | -== Technology Choices |
| 24 | +The database proxy lives in `crates/wharf-core/src/db_policy.rs`. It intercepts |
| 25 | +MySQL connections on `127.0.0.1:3307`, parses every incoming SQL statement with |
| 26 | +the `sqlparser` crate (v0.39, AST-based, not regex), and evaluates each parsed |
| 27 | +statement against the policy table loaded from |
| 28 | +`configs/policies/database.ncl` (Nickel). A write to a Red Zone table returns a |
| 29 | +policy-violation error immediately; the statement never reaches MariaDB. A write |
| 30 | +to a Blue Zone table passes through. Hybrid (Grey Zone) tables like `wp_options` |
| 31 | +are evaluated by row-level conditional rules. The WordPress adapter |
| 32 | +(`adapters/wordpress/db.php`) routes all WordPress DB calls through |
| 33 | +`127.0.0.1:3307` transparently. |
| 34 | + |
| 35 | +**Caveat:** The proxy handles MySQL wire protocol only. PostgreSQL sites |
| 36 | +(e.g., Drupal on Postgres) require a separate adapter not yet implemented. |
| 37 | +The `sqlparser` crate parses standard SQL; vendor-specific MySQL extensions |
| 38 | +(e.g., `INSERT IGNORE ... ON DUPLICATE KEY UPDATE`) are handled but |
| 39 | +complex stored procedures may require additional pattern registration. |
| 40 | + |
| 41 | +- DB proxy: `crates/wharf-core/src/db_policy.rs` |
| 42 | +- Policy config: `configs/policies/database.ncl` |
| 43 | +- WordPress adapter: `adapters/wordpress/db.php` |
| 44 | +- WordPress dashboard plugin: `adapters/wordpress-wharf/` |
| 45 | + |
| 46 | +== Claim: Post-quantum hybrid signatures on all mooring protocol traffic |
| 47 | + |
| 48 | +[quote, README] |
| 49 | +____ |
| 50 | +Both the Wharf CLI and Yacht Agent persist their Ed448 + ML-DSA-87 hybrid |
| 51 | +keypairs to disk. All mooring requests and responses carry hybrid signatures — |
| 52 | +both must verify. An attacker must break both algorithms (quantum or classical) |
| 53 | +to forge a signature. |
| 54 | +____ |
| 55 | + |
| 56 | +The mooring protocol is implemented in `crates/wharf-core/src/mooring.rs` |
| 57 | +and `mooring_client.rs`. All `INIT` and `COMMIT` phase requests carry two |
| 58 | +independent signatures: one Ed448 (classical elliptic curve) and one ML-DSA-87 |
| 59 | +(FIPS 204 post-quantum lattice). The Yacht's `verify_mooring_request()` checks |
| 60 | +both — either signature failing causes the entire request to be rejected. |
| 61 | +Key material is stored in a custom binary format (`WHRF` magic + version + |
| 62 | +length-prefixed key) at `~/.wharf/keys/wharf.key` (Wharf CLI) and |
| 63 | +`/etc/wharf/keys/yacht.key` (Yacht Agent), both mode `0600`. File integrity |
| 64 | +during sync uses BLAKE3 manifests (`crates/wharf-core/src/integrity.rs`). |
| 65 | +Key derivation for password-encrypted offline storage uses HKDF-SHAKE512 + |
| 66 | +XChaCha20-Poly1305. The default signature scheme is `ml-dsa-87-only` |
| 67 | +(pure post-quantum) until the ed448-goldilocks library completes external audit; |
| 68 | +hybrid mode is available via `--signature-scheme hybrid`. |
| 69 | + |
| 70 | +**Caveat:** The `ml-dsa-87-only` default is recommended for production; the |
| 71 | +hybrid mode has a dependency (`ed448-goldilocks`) that has not yet had a |
| 72 | +third-party security audit. The FIDO2 emergency override path is designed |
| 73 | +but requires a physical FIDO2 device and `libfido2` at runtime. |
| 74 | + |
| 75 | +- Mooring protocol: `crates/wharf-core/src/mooring.rs` |
| 76 | +- Crypto primitives: `crates/wharf-core/src/crypto.rs` |
| 77 | +- Integrity (BLAKE3): `crates/wharf-core/src/integrity.rs` |
| 78 | +- Nebula mesh: `crates/wharf-core/src/nebula.rs` |
| 79 | + |
| 80 | +== Dogfooded Across The Account |
14 | 81 |
|
15 | 82 | [cols="1,2"] |
16 | 83 | |=== |
17 | | -| Technology | Learn More |
| 84 | +| Technology | Also Used In |
| 85 | + |
| 86 | +| **Rust (multi-crate workspace)** | https://github.com/hyperpolymath/neurophone[neurophone], |
| 87 | + https://github.com/hyperpolymath/protocol-squisher[protocol-squisher], |
| 88 | + https://github.com/hyperpolymath/ephapax[ephapax], |
| 89 | + https://github.com/hyperpolymath/burble[burble] |
| 90 | +| **Nickel configuration language** | https://github.com/hyperpolymath/bofig[bofig], |
| 91 | + https://github.com/hyperpolymath/awesome-nickel[awesome-nickel], |
| 92 | + https://github.com/hyperpolymath/nafa-app[nafa-app] (nickel-rituals), |
| 93 | + https://github.com/hyperpolymath/developer-ecosystem[developer-ecosystem] |
| 94 | +| **Chainguard base images / Containerfile** | Container policy applied |
| 95 | + account-wide; see https://github.com/hyperpolymath/burble[burble], |
| 96 | + https://github.com/hyperpolymath/stapeln[stapeln], |
| 97 | + https://github.com/hyperpolymath/neurophone[neurophone] |
| 98 | +| **Selur-compose / Vordr runtime** | https://github.com/hyperpolymath/stapeln[stapeln], |
| 99 | + https://github.com/hyperpolymath/burble[burble] and other deployed services |
| 100 | +| **eBPF for kernel-level enforcement** | `crates/wharf-ebpf/` XDP firewall; |
| 101 | + eBPF patterns also appear in https://github.com/hyperpolymath/svalinn[svalinn] |
| 102 | +|=== |
18 | 103 |
|
19 | | -| **Rust** | https://www.rust-lang.org |
| 104 | +== File Map |
| 105 | + |
| 106 | +[cols="1,3"] |
20 | 107 | |=== |
| 108 | +| Path | What's There |
| 109 | + |
| 110 | +| `crates/wharf-core/src/mooring.rs` |
| 111 | +| Mooring protocol types, `MooringError`, protocol version constants, phase |
| 112 | + definitions (INIT / VERIFY / RSYNC / COMMIT). Session state machine. |
| 113 | + |
| 114 | +| `crates/wharf-core/src/mooring_client.rs` |
| 115 | +| HTTP client for the Wharf CLI side. 30-second request timeout, |
| 116 | + 10-second connect timeout, connection pooling (2 idle per host). |
| 117 | + Sends hybrid-signed INIT, per-layer VERIFY, and COMMIT requests. |
| 118 | + |
| 119 | +| `crates/wharf-core/src/crypto.rs` |
| 120 | +| Ed448 + ML-DSA-87 key generation, signing, verification. HKDF-SHAKE512 KDF. |
| 121 | + XChaCha20-Poly1305 AEAD. Argon2id (512 MiB / 8 iter / 4 lanes) for |
| 122 | + password-based key protection. |
| 123 | + |
| 124 | +| `crates/wharf-core/src/integrity.rs` |
| 125 | +| BLAKE3 filesystem manifest generation and verification. Detects mismatched, |
| 126 | + missing, and unexpected files during mooring verify phase. |
| 127 | + |
| 128 | +| `crates/wharf-core/src/db_policy.rs` |
| 129 | +| MySQL proxy with sqlparser AST evaluation. Red/Blue/Grey zone classification. |
| 130 | + Policy loaded from Nickel config. |
| 131 | + |
| 132 | +| `crates/wharf-core/src/nebula.rs` |
| 133 | +| Full Nebula overlay mesh management: CA key generation, certificate signing, |
| 134 | + IP allocation, revocation. Admin ports invisible to public internet. |
| 135 | + |
| 136 | +| `crates/wharf-core/src/fleet.rs` |
| 137 | +| Fleet configuration types. Maps Wharf Yacht definitions from Nickel config. |
| 138 | + |
| 139 | +| `crates/wharf-core/src/sync.rs` |
| 140 | +| rsync-based file transfer for the RSYNC mooring phase. Delta-only transfers. |
| 141 | + |
| 142 | +| `crates/wharf-ebpf/src/main.rs` |
| 143 | +| eBPF XDP program loader. Kernel-level packet filtering. Falls back to |
| 144 | + nftables when `CAP_BPF` is unavailable. |
| 145 | + |
| 146 | +| `adapters/wordpress/db.php` |
| 147 | +| WordPress DB drop-in. Routes all `wpdb` calls through `127.0.0.1:3307` |
| 148 | + (Yacht Agent proxy). Zero security logic in PHP — all enforcement in Rust. |
| 149 | + |
| 150 | +| `adapters/wordpress-wharf/` |
| 151 | +| WordPress dashboard plugin (GPL-2.0). Dashboard widget: allowed/blocked |
| 152 | + query counts, firewall mode, signature scheme. Admin bar indicator. |
| 153 | + 30-second transient caching. |
| 154 | + |
| 155 | +| `configs/fleet.ncl` |
| 156 | +| Nickel: declare your Yacht targets. |
| 157 | + |
| 158 | +| `configs/policies/database.ncl` |
| 159 | +| Nickel: Red/Blue/Grey zone table classification rules. |
| 160 | + |
| 161 | +| `configs/policies/airlock.ncl` |
| 162 | +| Nickel: HTTP header strip/inject rules for the header airlock. |
| 163 | + |
| 164 | +| `configs/policies/filesystem.ncl` |
| 165 | +| Nickel: immutable/writable/ephemeral path classifications. |
| 166 | + |
| 167 | +| `configs/policies/network.ncl` |
| 168 | +| Nickel: Nebula mesh and firewall rules. |
| 169 | + |
| 170 | +| `infra/selur-compose.yaml` |
| 171 | +| Selur-compose orchestration. Builder (wolfi-base), runtime agent (static), |
| 172 | + nginx (hardened), MariaDB — all Chainguard images. |
| 173 | + |
| 174 | +| `deploy/` |
| 175 | +| Deployment guide and `setup.sh` (5-minute Podman quick start). |
| 176 | + |
| 177 | +| `docs/wharf-architecture.png` |
| 178 | +| Architecture diagram referenced in README header. |
| 179 | + |
| 180 | +| `docs/HACK-ME-CHALLENGE.adoc` |
| 181 | +| Security research challenge: documented attack surface for researchers. |
| 182 | + |
| 183 | +| `Justfile` |
| 184 | +| Build recipes: `init`, `build`, `moor`, `audit`, `gen-nebula-ca`, |
| 185 | + `gen-yacht-cert`, `gen-email-records`, `container-build`, `deploy-selur`. |
| 186 | + |
| 187 | +| `.machine_readable/6a2/` |
| 188 | +| A2ML checkpoint files: STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK. |
| 189 | +|=== |
| 190 | + |
| 191 | +== Checking It |
| 192 | + |
| 193 | +[source,bash] |
| 194 | +---- |
| 195 | +# Build all crates |
| 196 | +just build |
| 197 | +
|
| 198 | +# Run tests |
| 199 | +just test |
| 200 | +
|
| 201 | +# Lint and format check |
| 202 | +just lint && just fmt-check |
| 203 | +
|
| 204 | +# Generate Nebula CA (offline, for Wharf controller) |
| 205 | +just gen-nebula-ca |
21 | 206 |
|
22 | | -== Questions? |
| 207 | +# Deploy Yacht Agent to server |
| 208 | +just deploy-yacht |
23 | 209 |
|
24 | | -Open an issue or reach out directly — happy to explain anything in more detail. |
| 210 | +# Container build |
| 211 | +just container-build |
| 212 | +---- |
0 commit comments