Repository navigation
06 roadmap
A step-by-step plan from this foundation to a working browser client and hosted service. Each phase has explicit acceptance criteria so progress is verifiable rather than vibes-based.
Progress note. Phase 0 is done. Phase 1 (browser client) and Phase 3 (hosting) now have working scaffolds — see
web/,services/, anddocs/03-browser-client.md/docs/04-hosting-services.md. The acceptance criteria below still require a machine with the Nym toolchain to demonstrate.
Deliverables
-
docs/01-architecture.md— system view, modes, trust boundaries. -
docs/02-addressing-and-routing.md— no-DNS model, byte layouts, algorithm. -
crates/sphinx-core/— reference Sphinx: header, blinding, filler, MAC, Lioness payload, SURB, address parsing, path selection. - This roadmap.
Acceptance criteria
-
cargo test -p sphinx-corepasses: 3-hop build→process→recover, tamper rejection, SURB reply, address round-trip. - Packet geometry equals production: header 348, payload 2065, total 2413.
- Key schedule matches
sphinx-packet(X25519 + HKDF-SHA256 → 288 B).
Gate before Phase 1. Read §1.1's production rule. From here on, the browser and service code depends on Nym's audited crates.
sphinx-corestays as documentation/test vectors.
Deliverables (see web/ and 03-browser-client.md)
-
web/React app: connection status, chosen path + hop count, pure-mixnet vs exit, latency, leak-guard state. -
workers/mixnet.ts: memoised one-shotensureTunnel()aroundsetupMixTunnel, lazy dynamic import, hard/soft disconnect. - Request modes:
-
mixFetch(url, init)— clearnet HTTPS via IPR exit. - direct Nym-address messaging via
@nymproject/sdk(send/wait_for_messages,send_reply). -
MixWebSocketfor streaming clearnet services.
-
-
Leak guard: wrap
fetch/XHR.open; configurable fail-open/closed. - CSP template:
worker-src 'self' blob:,connect-src 'self' wss: https://validator.nymtech.net ....
Acceptance criteria
-
mixFetch('https://echo.example/ip')returns a source IP different from clearnetfetch(the "prove the tunnel carried it" test). - Direct request to a routed host is blocked in fail-closed mode.
- Second
ensureTunnel()call does not spawn a second tunnel. - UI shows hop count and exit-vs-pure correctly.
- Bundle builds; WASM worker loads under the CSP template.
Notes / gotchas
- One tunnel per page; reload required after disconnect.
- Expect a multi-MB worker chunk; never block first paint on it.
Deliverables
-
extension/manifest v3, background service worker hosting the tunnel. - Tabs routed through the mixnet for allow-listed hosts (declarativeNetRequest can only redirect; actual routing happens in the worker — document this).
- Popup: on/off, per-site rule, current path, exit selection.
- Firefox build via
web-ext.
Acceptance criteria
- Extension loads unpacked in Chrome and Firefox.
- Allow-listed host requests go through the mixnet; all others remain direct.
- No direct leak for an allow-listed host with fail-closed on.
Honest constraint. A browser extension still cannot transparently proxy
all browser traffic (no system-wide SOCKS). For true "browser traffic through
the mixnet", the supported paths are (a) route requests inside your own page
with mixFetch, or (b) ship a companion local nym-socks5-client and set the
OS/browser proxy to 127.0.0.1:1080. State this in the README.
See services/ and 04-hosting-services.md.
-
services/echo-provider/— Rust,nym-sdkMixnetClientwithStoragePaths(stable identity) andwait_for_messages/send_reply. -
crates/nysiris-sdk/+services/nysiris-cli/— host a service with one command (nysiris host echo|files), print its stable address,fetchit back, and manage local petnames (13-sdk-cli.md). - Pin to a chosen Gateway with
request_gateway(...). - Reply budget accounting (default ≈50 real packets/s shared across all clients; idle cover ≈5/s).
Acceptance: provider prints a stable Nym address across restarts; a client sends a message and receives a SURB reply.
-
services/hybrid/—docker-compose.ymlwithcaddy(or nginx) + a Nym exit/requester front end. Document which parts are exposed and which are not.
Acceptance: clearnet clients reach the service normally; mixnet clients reach it by Nym address; no inbound port is required for the pure path.
-
services/gateway/—nym-nodeconfig, static public IP requirement, systemd unit, and registration vianyxd/nym-cli. - Document the DMZ split: Gateway public, provider private.
Acceptance: provider address is stable because it depends on a Gateway you
control; nym-cli shows the node registered and bonded.
The threat model is in
05-security.md; the controls are implemented and tested:
-
crates/sphinx-core/src/enforcement.rs— route policy (no repeated operator, no entry/exit collusion), SURB single-use + expiry, bounded SURB attachment, reply budget, exit rotation, cover-traffic guardrail. -
web/src/mixnet/enforcement.mjs— the same controls at browser runtime: reply dedupe + TTL, reply rate limiting, the cover-traffic guardrail wired intoensureTunnel, and exit-rotation guidance inmixnetFetch. -
crates/bridge-guard/— open-proxy guards for the hybrid bridge. -
web/src/mixnet/routedHosts.mjs+web/test/routedHosts.test.mjs— leak-guard decisions, verified withnode --test. -
crates/sphinx-core/tests/fuzz_parser.rs— deterministic mutation fuzzing of the packet/header/payload/address parsers (runs incheck). -
crates/sphinx-core/tests/soak.rs+crates/sphinx-core/fuzz/— heavy route soak (release) and optional coverage-guided fuzzing. -
.github/workflows/ci.ymlruns./build.sh checkon every push/PR.
Verification commands
./build.sh check # 32 Rust tests + 16 web tests, clippy -D warnings, docs
./build.sh soak # SPHINX_SOAK_ITERS=5000 route/message soak (release)
./build.sh acceptance # live-network delivery + SURB reply (needs the Nym toolchain)
cd crates/sphinx-core && cargo +nightly fuzz run parse_packet # optionalVerified on mainnet (2026-09-19, Rust 1.94, nym-sdk 1.21.6): the harness
built in ~4.5 minutes and passed — delivery RTT ≈ 7.6 s, SURB reply RTT ≈ 7.1 s.
Reproduce with ./build.sh acceptance; setup is in
services/acceptance/README.md.
Remaining follow-ups: keep the live test in a scheduled (not per-PR) job, extend the fuzz corpus over time, and add a browser end-to-end test once a headless WASM harness is available.
A native .deb that serves the PWA on loopback and opens it in a Chromium
--app window. See 07-desktop-linux.md.
-
desktop/launcher/— dependency-free Rust launcher; unit-tested (path traversal, MIME, cross-origin-isolation headers). Runs in./build.sh check. -
desktop/debian/—control,postinst,prerm,.desktop, icon and abuild-deb.shproducingdist/nysiris_<version>_<arch>.deb. -
desktop/electron/— Electron alternative (bundled Chromium) for users without a system Chromium.
./build.sh web
./build.sh desktop # -> dist/nysiris_0.1.0_amd64.deb
sudo apt install ./dist/nysiris_0.1.0_amd64.debVerified: .deb builds and its layout is correct; the launcher returns
200 with COOP/COEP/CORP, serves application/wasm, rejects raw and
percent-encoded path traversal with 400, and applies the SPA fallback.
Remaining follow-ups: a Tauri/WebKitGTK spike with the §7.5 checklist, a Flatpak manifest, and an apt repository with GPG signing for distribution.
- Threat model review against §5 (tagging, timing, SURB hoarding, exit trust, replay, n-1 attacks).
- Cover traffic tuning: Poisson rates, loop cover,
disable_*flags and their privacy cost. - Observability without leaking: metrics that never log destinations/addresses.
- Key management: storage encryption at rest, key rotation, SURB pool purge (24-epoch validity).
- Fuzz/soak: malformed headers/payloads, replay filter behaviour.
Acceptance: written threat-model sign-off; no plaintext destination or Nym address in logs; soak test survives 10⁶ packets without leaks or panics.
Only if you need to operate an exit (as opposed to using existing ones):
-
nym-node --mode exit-gatewaywith the Network Requester and IPR. - Explicit exit policy (ports/hosts) and abuse handling.
- Legal review: running an exit changes your risk profile materially.
Acceptance: policy denies by default; documented logging/abuse process.
| Decision | Recommendation | Rationale |
|---|---|---|
| Reimplement Sphinx? |
No. Use mix-tunnel / nym-sdk. |
Audited crypto; sphinx-core is reference only. |
| Local daemon vs WASM? | WASM in-browser; local nym-socks5-client for non-web apps |
Browsers cannot open raw sockets |
| Naming | Ship addresses in config; no public directory | Avoid enumerability/unlinkability loss |
| Path length | 5 Sphinx hops (entry, 3 mixes, destination gw) | Matches MAX_PATH_LENGTH = 5
|
| Exit vs pure | Pure by default; exit only when the destination is clearnet | Strongest privacy for services you control |
| Reply strategy | SURBs (single-use) + replenishment for large replies | No address disclosure |
| Transport | WSS to Entry Gateway | Browser-compatible, TLS-protected |
- A user can open the web app/extension, see the mixnet status and path, and fetch a clearnet URL through an Exit Gateway with a different source IP.
- The same client can exchange messages with a pure mixnet service by Nym address, using SURBs for replies.
- A service can be hosted with no inbound ports, with a stable Nym address, and with clear operational docs.
- Security analysis and a threat model are written down and reviewed.
⚠️ Experimental / pre-audit. This repository is under active development and has not had an independent security audit. The Sphinx core incrates/is a reference implementation, never production crypto. Do not rely on it for high-stakes anonymity yet — see the threat model. Apache-2.0 © 2026 odelyzid (tribewarez). Report a security issue.
Nysiris docs
- Home
- 1. High-Level Architecture
- 2. Addressing & Routing Deep-Dive: how "DNS" works in Sphinx/Nym
- 3. Browser & Mobile Client (Web, Android, Desktop)
- 4. Hosting a Web Server / Service Reachable via the Nym Mixnet
- 5. Security Analysis & Recommendations
- 6. Implementation Roadmap
- 7. Desktop on Linux Mint / Debian
- 8. Hidden-Service Abstraction
- 9. nysiris-social: Metadata-Minimal Microblog + Encrypted DMs
- 10. Portal Layers: Data, Replication, Discovery, Reputation
- 11. UX Redesign — Calm, Private-by-Default Client
- 12. Windows build (MSYS2 / MSVC)
- 13. Hosting SDK &
nysirisCLI