Firezone's sanstun Replaces Its BoringTun Fork After 70 Patches, and Ships Unaudited
Software / explainer
Firezone's sanstun Replaces Its BoringTun Fork After 70 Patches, and Ships Unaudited
The Rust WireGuard state machine does no I/O and no buffering, which hands the caller four jobs the README spells out.
Firezone has released sanstun, a Rust implementation of the WireGuard state machine that performs no network or file I/O, and has deprecated its own fork of Cloudflare's BoringTun in its favour. Thomas Eizinger announced it on Firezone's blog on Oct. 31. The repository is Apache 2.0 and had 27 stars when I read it.
The post gives the reason in a number: Firezone had landed more than 70 pull requests of fixes and API additions on its BoringTun fork. Staying API-compatible with upstream kept getting harder as product needs moved.
What sans-IO means for a VPN library
The post defines the term in one line: "sans-IO is the idea that you design your system such that IO and side-effects are cleanly separated." It adds that time and randomness count as side effects too.
In sanstun that means the caller passes in the clock and the random seeds. The library hands back bytes to send. It never opens a socket, reads a TUN device or starts a timer.
The README's scope section lists what follows from that: no internal buffering, no locks or atomic counters in the protocol state, and an API built so encryption can be deferred and batched across threads. Eizinger puts the buffering rule bluntly: "Just don't buffer in the library."
The four jobs left to the caller
This is the part a reader should check before adopting it. The README's out-of-scope list is a to-do list for whoever embeds the crate.
| Job the caller owns | What goes wrong if skipped |
|---|---|
| Run the event loop for TUN and UDP | Nothing moves: the crate does no I/O |
| Hold packets until a handshake completes | Packets sent with no session are not queued for you |
| Route and validate decrypted packets | A decrypted packet only proves which peer sent it |
| Supply entropy and a monotonic clock | Identical seeds give identical keys and nonces; a clock that steps back can make peers reject handshakes as replays |
The README states the seed risk in bold: "Supplying identical seeds will produce the same keys, nonces, cookies etc." In a library that owns its own randomness that mistake cannot happen. Here it can, and the compiler will not catch it.
What the benchmarks say, and do not
The post reports per-operation timings from its own benchmarks. These are Firezone's figures; I have no independent run.
- encrypt, 64 bytes226 ns
- decrypt, 64 bytes206 ns
- encrypt, 1280 bytes933 ns
- decrypt, 1280 bytes915 ns
Source: Firezone blog post introducing sanstun, accessed 2026-10-31 (vendor-run)
At 64 bytes the protocol bookkeeping is small: about 21 ns for begin_encapsulate, 38 ns for begin_decapsulate and 18 ns for commit_decapsulate. At 1,280 bytes the post says bookkeeping is about 2% of the encryption cost.
The post also estimates a speedup of "more than 45x" by moving encryption to worker threads. It calls this idealised and ignores threading overhead. Treat it as a ceiling, not a result.
Where it sits against BoringTun
Cloudflare's BoringTun repository is BSD 3-Clause, has 7.2k stars, and carries a warning that it "is currently undergoing a restructuring" and that users "should probably not rely on or link to the master branch right now." The README points users to crates.io instead. sanstun began as a fork of it, and its NOTICE file carries the BoringTun licence.
Firezone is not claiming sanstun is a general replacement. It is a library for people who want to own their event loop, which is how Firezone's own product is built. Another Apache 2.0 tool that fits a narrow job is JetBrains' ThinkRail, and the same habit applies there: read the scope section first.
What is still open
The README says sanstun "has not received a formal security audit." For a crypto-adjacent crate with 27 stars and no listed releases, that matters more than any nanosecond figure. The "Used by" section was empty when I read it, so Firezone's own deployment is the only production use I could see.
Small tools that state their limits plainly are worth noting, and MiniLake did the same when it said outright that its Databricks emulator accepts any token. sanstun's README earns the same credit.
The next thing to watch is whether an audit or a tagged release follows. Neither has been announced.
Sources
More in Software
- 01Python 3.15 Ships a Built-In sentinel After Five Years of PEP 661The new type replaces the object() idiom with a one-line constructor that survives copying, pickling and type checking, but a Python 3.15 floor is the price of using it.
- 02Lightpanda 1.0 Passes 80% of Chrome's Web Tests, by Its Own CountThe Zig-built headless browser left beta on Oct. 2, and its own benchmarks put it ahead of two Rust rivals on a 940-page crawl, with no hardware listed.
- 03Claude-Mem Hits 107,900 Stars, and Its Own Pages Disagree on LicenceThe Claude Code memory plugin has gained about 35,500 stars since May, but a May write-up says AGPL-3.0, the repository now says Apache-2.0, and the README describes an optional cloud sync that earlier coverage did not.
- 04Jepsen Found 96 Issues in ParticleDB 1.1.4 and Tells Users to Halt DeploymentKyle Kingsbury’s 31 October report, funded by vendor Orkes, finds lost writes and ignored constraints in healthy single-node runs.