two presets, one engine · pre-alpha
Install.
The shortest path is cox init with a preset flag
and one or two cloud VMs. coxswain stays on a private
box; every operational instruction to nodes is
mTLS gRPC, coxswain-initiated.
prerequisites
What you need before you start.
- A private machine to run
coxswainon — your laptop, a home server, a small private box. It needs outbound internet; it does not need a public IP or open ports. - One or more public VMs to run
nodeon, on any provider.coxswaindoesn't call cloud APIs; you create the VMs. - SSH access to those VMs from the machine running
coxswain.coxswaingenerates its own keypair on first run and prints the public key for you to add. - Go 1.22+ & Make to build the controller from source. (The clients ship as released binaries; the controller doesn't yet.)
preset · for one operator
cox init --personal
One operator, one or two nodes, sensible defaults, AmneziaWG by
default, the relay embedded in coxswain itself.
# 1. build coxswain on your private machine
git clone https://github.com/PharosVPN/coxswain
cd coxswain && make
# 2. first-run setup with the personal preset
./cox init --personal
# 3. create a VM on any cloud provider you like.
# add coxswain's SSH public key to that VM's authorized_keys:
./cox ssh-key
# 4. enroll the node — coxswain SSHes in, installs node, signs a CSR
./cox nodes add user@my-vm.example.net
# 5. issue yourself a device profile
./cox users add me
./cox devices enroll me --qr # scan with caravel
# ...or:
./cox devices enroll me --file me.pharos preset · for a fleet
cox init --enterprise
Multi-region, multi-admin, AmneziaWG and XRay both enabled,
remote relays optional, longer audit
retention. The presets only swap defaults — the engine is the
same.
# 1. build coxswain on a private box (laptop, home server, jump host)
git clone https://github.com/PharosVPN/coxswain
cd coxswain && make
# 2. first-run setup with the enterprise preset
./cox init --enterprise
# 3. enroll one or more nodes in each region you care about
./cox ssh-key
./cox nodes add ops@eu-frankfurt-1.example.net --region eu-fra
./cox nodes add ops@us-east-1.example.net --region us-east
# 4. (optional) deploy a remote relay — same SSH enrollment pattern
./cox relays add ops@relay-1.example.net
# 5. add admins; each gets their own device cert from the Device CA
./cox admins add alice
./cox admins add bob
# 6. roll out caravel via your MDM, or by handing out enrollment QR codes
./cox users add team-employee
./cox devices enroll team-employee --qr what happens after init
From here, every instruction is gRPC.
coxswain holds a long-lived outbound mTLS connection
open to each node. Pushes are applied live — adding
a peer doesn't restart the data plane. SSH was a deployment
channel only, used once at enrollment and again for agent
upgrades.
The admin UI is an SPA embedded in the
coxswain binary, served on localhost. Open
it from the machine that's running the controller. It surfaces the
fleet, paths, and profiles, plus live sessions, alerts, the audit
log, and API tokens — and the controller reconciles the fleet on an
interval, so a node that drifts is brought back automatically.