PharosVPN
PharosVPN · v0 · pre-alpha · Apache-2.0

Personal VPN.
Enterprise VPN.
The same VPN.

A fleet of VPN nodes you own, driven by a controller that never exposes a port. Traffic crosses two of your nodes before the internet, enters on a rotating pool of addresses, and rides profiles the controller can't read. Watch it move — that's a live fleet up there.

data plane
AmneziaWG · XRay/REALITY
port
443 (UDP+TCP)
controller
zero inbound ports
licence
Apache-2.0

§01 · the platform in one paragraph

PharosVPN is a self-hostable, open-source, dual-protocol (AmneziaWG + XRay / REALITY) VPN fleet platform. A private controller — coxswain — drives a fleet of dumb public VPN nodes over outbound mTLS, exposes end-users through an optional relay, and serves them a mobile client — caravel. One codebase, two postures: personal and enterprise.

02

four roles · one fleet

coxswain · node · relay · caravel

The controller stays hidden behind NAT and dials out to everything. Nodes are deliberately dumb. The relay is the only public ingress for clients.

read about each component →

PharosVPN — node and relay roles plus clients coxswain sits in private space behind NAT. It dials outbound mTLS to each public node, and a reverse tunnel out to a public relay. Clients reach the controller only through the relay. PRIVATE NETWORK · BEHIND NAT · ZERO INBOUND PORTS coxswain controller · CA · admin UI SOURCE OF TRUTH PUBLIC INTERNET node A awg udp 443 xray tcp 443 node B awg udp 443 xray tcp 443 node N awg udp 443 xray tcp 443 relay public CLIENT INGRESS caravel mobile client END USER END-USER TUNNELS · UDP/TCP 443 coxswain-initiated outbound mTLS tunnel / client connection private boundary
fig. 1 · roles & topology — coxswain dials out to everything

§03 · three things the topology gives you

The crypto is the table stakes.
The topology does the work.

A typical VPN routes you through one box, on one address, with a profile its server can read. PharosVPN takes a different shape on all three — and the panels below run on a live fleet.

i

multi-hop cascade

No single node sees both ends.

A tunnel crosses two of your nodes before the internet: client → entry → exit → internet. You hold one key and only handshake with the entry; the exit is a dial the controller turns — server-side, live, no reconnect.

how the cascade works →

PharosVPN multi-hop — entry node and exit node A client tunnels to an entry node, which forwards over an inner AmneziaWG link to an exit node, which reaches the internet. The entry node sees the client's address but not its destination; the exit node sees the destination but not the client. No single node sees both ends. The exit is chosen over the control channel and switched live by the controller. NO SINGLE NODE SEES BOTH ENDS caravel your device HOLDS 1 KEY node · entry your hop in node · exit your hop out node · another exit A DIFFERENT REGION internet EGRESS inner awg link live switch ↻ SEES · your address NEVER · your destination SEES · your destination NEVER · your address handshakes with the entry only 2 HOPS DEFAULT · 3 MAX · MTU-GATED ≥ 1280 EVERY NODE OPERATOR-OWNED

pick & switch

Switching exit is an instant route-flip on the entry — same profile, no re-handshake. Switching entry is the only move that re-establishes the tunnel.

split knowledge

One box that sees both who you are and where you go is the single point of correlation. Split the path across two nodes and it disappears.

yours, not Tor

Every hop is a node you run — full-throughput AmneziaWG, not a volunteer relay. Two hops by default, three max, gated on a computed MTU ≥ 1280.

ii

multi-IP entry pool

Your fleet isn't one address.

Most VPNs have everyone dial the same vpn.example.com:443 — a passive observer can cluster by employer without touching the crypto. Each node binds a set of public IPs; the client picks one at random and re-picks every interval ± jitter. The signature of "your VPN" becomes a moving cloud.

why enterprises want it →

PharosVPN multi-IP entry pool A single node binds a set of public IP-and-port doors. The client picks one at random and re-picks on an interval, so two sessions enter on two different addresses. The WireGuard peer roams, so the tunnel never drops. ONE NODE · A POOL OF ADDRESSES caravel your device one node one machine BINDS THE WHOLE POOL 198.51.100.7:51820 203.0.113.44:49221 198.51.100.91:60113 203.0.113.7:54002 198.51.100.7:51820 203.0.113.44:49221 198.51.100.91:60113 203.0.113.7:54002 PICKS ONE AT RANDOM RE-PICKS EVERY INTERVAL ± JITTER WIREGUARD PEERS ROAM — THE TUNNEL NEVER DROPS ON BY DEFAULT FOR --ENTERPRISE
iii

end-to-end profile sync

The controller holds no usable secret.

Your profile — keys, nodes, the whole config — is sealed on your device. The controller stores it, signs it, and hands it to your other devices, but it cannot open it. Seize the controller and you get ciphertext and a signature, never a profile.

the trust boundaries →

PharosVPN end-to-end profile sync A profile is encrypted on your device into a sealed bundle. The controller stores and signs it but cannot open it, then hands it to your other devices, which decrypt it with a key the controller never holds. THE CONTROLLER CARRIES IT · NEVER OPENS IT caravel · A seals the profile HOLDS THE KEY coxswain stores · signs CANNOT OPEN caravel · B opens the profile HOLDS THE KEY ✓ DECRYPTED LOCALLY SEES · ciphertext + a signature NEVER · your keys, your profile X25519 + Ed25519 + XCHACHA20-POLY1305 A COMPROMISED CONTROLLER LEAKS NO PROFILE
04

the controller · coxswain

An always-on controller that keeps the fleet correct.

The topology is the data plane. The control plane is coxswain — a single static binary that drives the fleet, reconciles drift on an interval, and surfaces what's happening in a self-hosted dashboard. The pillars above are pre-alpha; this part has shipped.

self-healing control plane

Provisioning a profile or device pushes to the affected nodes automatically. A reconcile sweep checks every node on an interval and re-applies config when one drifts or a data plane goes stale. Restart the controller and it re-reconciles the whole fleet.

monitoring & analytics

Live connect/disconnect events stream off each node over gRPC, with persisted session history. An in-process engine sweeps that history and raises alerts — leaked profile, impossible travel, off-hours, auth-failure spikes — with severity and evidence. Anomaly rules are best-effort and experimental.

tokens · audit · SIEM

A token-authenticated management API with scoped, expiring tokens. A hash-chained audit log of every action, so edits are detectable. A gRPC event stream for SIEM ingestion. SQLite by default; an optional pure-Go Postgres backend for scale.

what the controller does for a fleet →

“Dumb nodes. A compromised VPN node must not yield control of the fleet.”

— DESIGN.md, §1 goals

05

presets · not products

Same engine. Different defaults.

cox init --personal and cox init --enterprise only swap defaults. Nothing on this table is locked behind an edition.

full comparison →

Regions
1, nearest
operator picks
Idle nodes
none
pre-positioned
Admins
one (the operator)
core + UI-added
Audit retention
30 days
1 year
MDM-managed clients
off
supported
Price
your cloud bill
your cloud bill

pick a preset — both run the same binaries

06

the thirty-minute promise

Self-hostable in under thirty minutes.

Clone the repo, run cox init, point it at any cloud VM you own. The controller stays on your laptop or a tiny private box; only the VPN nodes live in public. No vendor account, no lock-in beyond whichever cloud you happen to be paying.

coxswain — zsh
$ git clone https://github.com/PharosVPN/coxswain
$ cd coxswain && make
$ ./cox init --personal
controller key generated · local CA ready
$ ./cox nodes add [email protected]
node up · awg udp/443 · profile issued
$ ./cox nodes endpoints node-ams 198.51.100.7,203.0.113.44
entry pool set · client picks one at random
$

pre-alpha · controller commands run today · expect rough edges

§07 · read the design

The architecture earns the trust.

Four trust boundaries, one CA, end-to-end-encrypted profiles, a controller that holds no usable user secrets. The design document is the single source of truth — every subproject defers to it.