The problem it solves #
Most developers have more than one machine and are still one person. A desktop that never sleeps, a laptop that leaves the house, maybe a build box. Whatever you taught one of them stays on that one. The others start from nothing.
Some of the obvious fixes mean using somebody else's product. Sync the database file through a shared folder and two writers corrupt it. Put it on a cloud you rent and your memory is now their asset.
A mesh VPN is a real answer and we use one ourselves. If you already run a tailnet, or are happy to, that is the shorter route and the phone connector is built on it. The rest of this page is for when you are not: no TUN device on every machine, no admin rights, nothing from a second company. The brain does it itself with the same binary and the machine that holds your memory is one you own. The first setup takes a few steps, all of them in the walkthrough below.
How a machine reaches home #
A machine at home has no address anybody can dial. It sits behind NAT on a router you did not set up. The laptop trying to reach it is behind a different one, often carrier NAT with no public address at all. Neither can accept a connection. Both can make one.
That is the whole trick. Every leg dials out to a relay you run on a cheap VPS. The machine holding the brain keeps one connection open to it. Your laptop dials the same relay and asks for that machine by name. The relay joins the two connections and copies bytes between them.
laptop --- dials out --> relay <-- dials out --- the brain, at home | | └──── TLS, end to end, the relay holds no key ────┘
The relay never opens that TLS, so it copies traffic it cannot read. It has no key that would let it and it cannot make one. Whoever runs the relay, you included, sees encrypted bytes plus which of your machines connect and when. Nothing more.
That session is TLS 1.3. The client checks the brain's certificate against your own private authority instead of the public ones, so a certificate from a public CA cannot pass as one of your machines. The relay only lets in a machine with a certificate from that same authority. The brain then checks the machine's credential on every request. Nothing travels between machines unencrypted, on your home network either. A LAN is a network too and the client refuses to send its credential over plain http to anything but loopback.
No inbound port is opened on your home network. No router setting changes. There is nothing new to install: it is the same self-contained binary, with a subcommand. That is the trade against a tailnet, which asks you to run one more thing on every machine and gives you a name for each of them in return.
Two machines, step by step #
A laptop and a desktop sharing one brain. This is every step, once, in the order it has to happen. Steps 5 to 9 only matter if the laptop leaves the house.
The short route is a hosted brain. Hive Personal already has a public address, so there is no server, no authority and no relay to run. Sign up, then run hive login on each machine and hive join --apply once in each project (steps 2 and 3 below) against https://hive.fightclub.pro. The first six months need no card. The rest of this page is for running it all yourself, for free.
The server, on the machine that keeps the brain. It is
ns-brain hive serveon Postgres, with a file holding the master key. Copy that key somewhere off the machine before the server holds anything real. Lose it and nobody reads those memories again. Create your organisation once, then serve it over TLS.$ ns-brain hive serve --dsn "$HIVE_DSN" --master-key /etc/ns-brain/master.key \ --init-org you --init-owner you@example.com $ ns-brain hive serve --dsn "$HIVE_DSN" --master-key /etc/ns-brain/master.key \ --addr 0.0.0.0:7799 --tls-cert cert.pem --tls-key key.pem
Or leave
--addron its loopback default and put a TLS terminator in front of it on the same host. The server flags are on the setup page.Sign in from each machine. Step 1 printed the root node id and a token that belongs to you as owner. The token is shown only once. The desktop signs in with it. The laptop signs in with the device flow, which prints a code for the desktop to approve.
$ ns-brain hive login --server https://brain.example.com --token hive_... # desktop $ ns-brain hive login --server https://brain.example.com # laptop; prints a code $ ns-brain hive approve WXYZ-1234 --email you@example.com --node <root node> # desktop
Attach each project. Do this in the project root, on one machine. It is a dry run until
--applyand a local brain is copied up first.$ ns-brain hive join $ ns-brain hive join --apply
On the other machine, a checkout whose
brain.jsonalready names the server needs nothing more than the login in step 2. A project that does not name it takesns-brain init --hive https://brain.example.com.Check it.
ns-brain hive statuson both machines names the same server and the same you. Save something on one and recall it on the other.Your own certificate authority, if the laptop leaves home. Generate it on a machine that is not the server, because the root key belongs offline. The org label is the organisation slug from step 1.
$ ns-brain axon init --dir ~/axon-ca --org you $ ns-brain axon issue --dir ~/axon-ca --machine relay $ ns-brain axon issue --dir ~/axon-ca --machine desktop $ ns-brain hive serve --dsn "$HIVE_DSN" --master-key /etc/ns-brain/master.key \ --adopt-axon ~/axon-ca --adopt-org you # on the server: the issuing half only $ ns-brain hive serve --dsn "$HIVE_DSN" --master-key /etc/ns-brain/master.key \ --adopt-machine relay.you.axon.internal $ ns-brain hive serve --dsn "$HIVE_DSN" --master-key /etc/ns-brain/master.key \ --adopt-machine desktop.you.axon.internal
The last three commands run on the server and exit. Copy
root.crt,issuing.crtandissuing.keyacross for--adopt-axonand leaveroot.keywhere it is.--adopt-machineadds the two machines you issued by hand to the brain's register. Without it neither of them can renew. The issuing half lasts a year and the server cannot sign the next one without the root key, so it warns four months ahead. If you would rather it rotated by itself, hand it the root key with--adopt-axon-rootbefore then.The relay, on the cheapest machine you have with a public address. It stores nothing and sees only encrypted bytes. Its starting list names the machine that holds the brain. After that the brain pushes the list itself.
$ ns-brain axon install --from ./relay --dir /etc/axon --relay 127.0.0.1:7800 \ --hive desktop.you.axon.internal $ printf '%s\n' desktop.you.axon.internal > /etc/axon/admit $ ns-brain axon relay --addr 0.0.0.0:7800 --dir /etc/axon \ --admit /etc/axon/admit --hive desktop.you.axon.internal --enrol
Put the server on the relay. Install its identity, then add
--axonto the serve command from step 1.$ ns-brain axon install --from ./desktop --relay relay.example.com:7800 \ --hive desktop.you.axon.internal $ ns-brain hive serve ... --axon
Enrol the laptop and approve it from a machine already on the brain. The next section explains why an approved machine is permanent and a password one is not.
$ ns-brain axon enrol --relay relay.example.com:7800 # on the laptop; prints a code $ ns-brain hive approve-machine FV7F-QVD2 # on the desktop
Enrolment prints
https://desktop.you.axon.internalas the address the laptop now uses to reach the brain and stores a credential for it. A project only goes through the relay when itsbrain.jsonnames that address. So runns-brain init --hive https://desktop.you.axon.internalin each project the laptop takes out of the house.Put
axon renewon a timer, on every machine, relay first. Certificates last ninety days and renewal is not automatic until you schedule it.axon renewdoes nothing until a certificate is in its last thirty days, so a daily timer is enough. A relay or server loads its certificate when it starts, so restart it after a renewal.ns-brain axon statusshows when each one expires.
ns-brain axon status on the relay machine.
Getting a machine on it #
Once the relay is up, a machine joins with one command and its private key never leaves it. Only a certificate request is sent.
$ ns-brain axon enrol --email you@example.com --relay relay.example.com:7800 password: joined the brain at you machine buildbox.you.axon.internal identity /home/you/.config/ns-brain/axon relay relay.example.com:7800 brain https://desktop.you.axon.internal This machine is TEMPORARY: its certificate expires, and it cannot renew itself. That is deliberate. A password works from a machine you will never see again, so enrolling with one buys a device that dies on its own rather than one that lives for ever. Make it permanent from a machine you already hold. Attach a project to it: ns-brain init --hive https://desktop.you.axon.internal
If the server has not seen the email before, it registers a new brain. If it knows the email, it adds this machine to the brain you already have, using the password you set once with ns-brain hive password. An owner created with --init-org has no password until then. After that, in a project whose brain.json names that address, every ordinary command works exactly as before: recall, remember, brief and the session hooks you already wired. Nothing above the connection itself knows a relay exists.
A machine enrolled with a password is temporary and that is on purpose. A password works from a machine you will never see again, so what you get is a device that expires by itself after thirty days. For a machine you keep, approve it from one you already have:
$ ns-brain axon enrol --relay relay.example.com:7800 # on the new machine This machine is asking to join, as "laptop". FV7F-QVD2 Type that on a machine that is already on this brain: ns-brain hive approve-machine FV7F-QVD2 Waiting. The code expires in ten minutes, and it admits nobody on its own. $ ns-brain hive approve-machine FV7F-QVD2 # on a machine already on the brain admitted laptop.you.axon.internal, permanently. You approved it from a machine you already hold, so it does not expire the way a password enrolment does. ns-brain hive logout --machine <label> revokes it
The code is short because you read it off one screen and type it on another. It is safe to keep it short because it lets nobody in by itself. It points at a waiting request and the real authority is the credential of whoever approves it.
What the relay can see #
Machines are named <machine>.<org>.axon.internal and a client checks the name it asked for, not just that the certificate chain is valid. That difference is the one that matters. Every machine of yours has a certificate from the same private authority, so the chain always checks out. A client that stopped there could be connected to a different machine in its own org by a relay someone had taken over. Checking the name closes that hole.
Those names are never looked up in DNS. There is nothing to publish, no record to look up and no list of your machines for anyone to collect. When enrolment creates a brain it generates the org id instead of letting you pick one, so nobody can guess it or grab it first. Generated or chosen, the id is an address and not a credential: knowing it lets nobody in.
The relay lets machines in from a list copied from the brain's own register. The brain pushes it on every change and again every minute. We deliberately keep no second register, so nobody can revoke a machine in one and forget the other.
Losing a laptop #
The question to ask of any setup like this is what happens the day a machine is stolen. Deleting the credential on a machine you no longer have does nothing for you. So you revoke on the brain, from a machine you still have.
$ ns-brain hive machines # what is enrolled $ ns-brain hive logout --server <url> --machine laptop # revoke there, forget here
The relay refuses the revoked machine within a minute and drops any session it holds open straight away instead of letting it finish. Its name is then retired for good. Machines are let in by name and the certificate it holds stays valid until it expires, so if the name came back the certificate would come back with it.
Revoking another machine leaves the one you are sitting at signed in, as long as that one has its own axon identity. That way you can log out a lost laptop from a machine you still have. Run the same command from a machine with no axon identity and it also removes that machine's own credential for the server, so sign it back in afterwards.
What it does not do #
It does not copy your memories to each machine. They live on the machine that holds them, so a machine that cannot reach it has no brain. The session opens with the brief it cached and then refuses, instead of answering confidently from an old local copy. That refusal is on purpose. A brain that quietly answers from a file nobody has written to in a month is worse than one that says it cannot reach the server.
Every command also makes a network round trip. On a home LAN that is a few milliseconds. Through a relay in another country it is closer to four hundred and on mobile data closer to six hundred. That is fast enough for the session brief to fit in its time budget and slow enough that you would notice it in a tight loop.
Certificates last ninety days on a machine allowed to renew. Renewal is a command plus a timer and the machine proves who it is with the certificate it is replacing. A temporary machine is refused, because renewing it would turn a device meant to expire into a permanent one.
What it costs #
Nothing extra. The relay is part of the same binary and costs nothing on top of the edition you use.
The relay is the only piece that needs a public address and the cheapest VPS you can find is enough, because it copies bytes and stores nothing. How to set one up.