What we collect, and what we don't.
A "no-logs VPN" claim is meaningless without specifics. Here are ours. The full machine-checkable audit pack and verification matrix is linked at the bottom — this page is the customer-friendly version of the same document.
Where the servers are
Three countries, all outside any Eyes alliance
switzerland iceland romania
Zurich, Reykjavik, Bucharest. Each box is a RAM-only ephemeral instance — disk is tmpfs, swap is disabled, WireGuard keys regenerate on every reboot. A seized machine reveals the base OS and nothing operational.
Not in the United States, United Kingdom, Canada, Australia, New Zealand (Five Eyes), nor Denmark, France, Netherlands, Norway (Nine Eyes), nor Germany, Belgium, Italy, Spain, Sweden (Fourteen Eyes). Not for latency. Not for redundancy. Not for any reason.
The short version
What we store
stored SHA-256 hashes of account tokens, device WireGuard pubkeys, your chosen mesh region(s), invoice amounts, and 2 days of nginx access logs anonymized to the /24 (or /48 for IPv6).
That's the complete list. Anything not on it isn't kept.
What we don't store
not stored Your IP address. Your User-Agent. The destinations you visit. The bytes you transfer. The times you connect. The duration of your sessions. Your real name, email, or phone (we never ask). Your cryptocurrency wallet address (BTCPay knows it; we don't).
What we cannot store, by design
cannot Your private WireGuard key (generated on your device, never transmitted). Your traffic content on multi-hop routes that crosses an entry node (it's end-to-end encrypted to the exit). Your seed phrase / wallet keys for Bitcoin payments (you hold those; we only watch your xpub).
At each stage
Signup
| Field | Stored? | Why |
|---|---|---|
| Email address | NO | Not requested anywhere |
| Phone number | NO | Not requested |
| Real name | NO | Not requested |
| IP address | NO* | Only nginx /24-bucket, 2-day retention |
| User-Agent | NO | Stripped from nginx log_format |
| Account token | HASH | SHA-256 only; original is on your device |
| Subscription expiry | YES | Required to enforce duration |
Payment
| Field | Stored? | Why |
|---|---|---|
| Wallet address | NO | Lives only on BTCPay, never sent to control plane |
| Transaction ID | NO | Same |
| Invoice ID | YES | 30 days; needed for refund dispute window |
| Amount (USD) | YES | Same |
Connect
| Field | Stored? | Why |
|---|---|---|
| Your device pubkey | YES | Required for WireGuard peering |
| Mesh IP allocation | YES | Required to route packets to you |
| Your private key | NO | Lives only on your device |
| Your real IP | NO | Not recorded anywhere |
| Destination IPs | NO | WireGuard kernel module doesn't log; nftables has no log rules |
| Bandwidth counters | NO | Deliberately disabled |
| Connection start/end times | NO | Not recorded |
Known limitations we declare proactively
2 days of nginx access logs
Anonymized to /24 (IPv4) or /48 (IPv6). Used for DDoS forensics and 5xx incident triage. A /24 is one of ~4.3 million possible /24s — not a unique identifier, but not zero either. Auditor's call whether to recommend zero retention.
7 days of systemd journal on the control plane
Application errors, route exceptions. Tokens are hashed before
they hit any logger; pubkeys never appear. RAM-only ephemeral
mesh nodes have Storage=volatile so their journal
is gone on reboot.
24-hour multi-hop rotation
A motivated adversary observing 24h of traffic on one entry
can still attempt correlation. If you want tighter rotation,
run sudo 0trust rotate manually or set the timer to 1h.
Auditors and skeptics: the full machine-readable
audit pack is at docs/AUDIT.md
— 13 sections, every claim cross-referenced to verification commands.
The verification script scripts/audit-verify.sh runs the
full check matrix against the live host and exits non-zero if anything
fails. Both should be your starting point if you're commissioning a
third-party audit.