What it is #
Every brain on Hive is readable by default. We hold the keys and the server can decrypt what it stores. That is what lets it search for you, show memories in the dashboard and connect your phone. The security page explains that choice.
A zero-knowledge brain makes the other choice. Each memory is sealed on your device before it leaves. The server keeps an append-only log of signed, encrypted entries and passes them between your devices. Each enrolled device holds the brain's key and a full local copy, called the replica. Reads and searches run against that copy. The server never sees a title, a body or a project name inside the brain.
- Chosen per brain. An owner or admin of the organisation creates one. Readable brains in the same organisation keep working as they do today.
- A brain is its own wall. Every device enrolled in it reads all of it. Grants inside the brain are not a confidentiality boundary, because the server that would enforce them is the party we are keeping out. If two groups must not read each other, make two brains.
- New brains only, for now. You cannot yet turn an existing readable brain blind.
zk create --adopt-unitrefuses, because nothing yet re-seals the old content. Create a new blind brain and store what you need in it withremember.
Readable and blind, side by side #
| Readable brain (default) | Zero-knowledge brain | |
|---|---|---|
| Who can read the content | Your members. We can decrypt it | Every device enrolled in this brain. Nobody else |
| Compartments inside the brain | Enforced by the server | None. Split into separate brains |
| Somebody with the server's database or backups | Can read it with the keys | Ciphertext and metadata only |
| Root on the server | Reads everything | Cannot read or alter content on devices that have synced. Can see metadata, withhold or delete entries |
| Search | On the server | On each device. Words only, no matching by meaning |
| Web dashboard | Shows content | Shows that the brain exists. Never decrypts, never takes a paper or a code |
| Phone, claude.ai connector, remote MCP, the web UI | Work | Refused |
| CI, scripts and token-only agents writing | Yes | No. Only enrolled devices write |
| Adding a member | Approve in the dashboard or with hive approve | An enrolled admin device approves and both people compare codes |
| Retention, holds and erasure | Set in the dashboard | Signed from an enrolled admin device |
| Read audit | Who read what | Only which device synced when |
| Support | Can look and can recover | Cannot look, cannot recover. Can confirm who is calling and cut a device off the server |
| Every key lost | We can recover | Gone, for you and for us |
| Plaintext on your machines | What hooks show the agent | The whole brain in each replica, plus agent transcripts |
| FIPS 140-3 | Not applicable | Not compliant |
What you give up #
When you create one, the client shows you this list and makes you type I understand before it goes further:
Making this brain zero-knowledge is a one-way door. You give up:
- the phone and the remote MCP connector
- CI jobs, scripts and token-only writers
- content in the web dashboard
- server-side search
- suspended-org export
- support-assisted recovery: if every device AND every copy of the paper are lost,
the brain is gone, for you and for us.
Those are the headline costs. The rest, stated plainly:
- Search is local and lexical. It runs on each device and matches words. There is no server search and no semantic search, because neither works on ciphertext.
- Every client in the organisation must be current. Once an organisation holds a blind brain, the server refuses any client too old to know about one and tells it how to upgrade. This covers every device in the organisation, not only the ones in the blind brain. An old client names projects by name and could file the brain's text where the server can read it.
- No automatic copies.
backupandsnapshotare refused and the brief keeps no daily safety copy. The other enrolled devices are the copies. For a spare, enrol a device and keep it powered off somewhere safe. - Ceremonies need a person. Creating a brain, approving a device, replacing the paper, recovery and deletion run only at a terminal a person opened. An agent cannot run them, by design.
- No cloud sessions. Creating, enrolling and binding are refused in a cloud agent session. Its transcript stays with the vendor and would hold the whole brain.
- Your model provider still sees what the agent reads. Encryption at rest on our side does not change what your agent sends to its model. That includes us if your agent's model goes through our gateway.
- Not FIPS 140-3 compliant. If your policy requires it, this is not the product for that brain.
What we can still see #
Encrypting the content does not hide its shape. For a blind brain the server can still see:
- That the brain exists, its label and the shape of its project tree. Project names inside are sealed. The label is not, so pick a neutral one.
- Who is enrolled, with their email and role. Who is enrolled in your HR brain can be sensitive on its own.
- Device labels. The default is the operating system and a random tag, never the hostname.
NS_BRAIN_DEVICE_LABELorzk enrol --labelsets one. - When each device syncs, how many entries it sends and their sizes, which are padded.
- The kind of each entry, such as a memory written, a task written or a memory forgotten. Not its content, title or project.
- Note routing and receipt times, that a legal hold exists and that a mass delete was proposed and approved.
- A hash of each project name, so the server can refuse a readable project with the same name. Someone holding the server could test a guessed name against it. Give a sensitive project a neutral name.
If you lose the keys #
- The paper. When you create the brain the client shows a recovery paper once, on the terminal. You write it down by hand with its label, the screen clears and you type it back. It is never stored, printed or sent anywhere. Keep a second copy in a second place.
- Owner devices of two people. A new brain accepts no content until a second owner device is enrolled. While you are its only member, your own second device counts. Once it has other members, it needs owner devices held by two different people.
- A spare device. The best copy for a disaster is a third enrolled device kept powered off in a safe. If it is stolen, treat it like any lost device.
Be clear about what a stolen paper means. The paper can decrypt the brain's keys. Against an honest server, using it to take over the brain waits 72 hours and any owner device can veto it in that time. But a thief who also has a copy of the server's data, such as an old backup, can read the content at once. Replace the paper the moment you doubt it.
A lost enrolled laptop is a breach of everything its replica held. Revoking it and rotating the key protects what you write afterwards, not what it already had. Full-disk encryption on every enrolled machine is your protection until you revoke it.
Before you start #
- Each machine is signed in to the organisation as a person, with
ns-brain hive login. A token for CI or an agent cannot create or enrol. Setup covers signing in. - Creating a brain needs owner or admin on the organisation.
- Run every ceremony yourself, in a terminal you opened. From inside an agent session the client refuses with a message like this:
$ ns-brain zk create people-ops
creating a zero-knowledge brain needs a person at a controlling terminal, and this
process runs under an agent's session or was taken out of one (a pty from `script`,
`setsid`, a double fork). Run it yourself, in a terminal you opened.
- Keys live in a fixed directory under your account's home. The client refuses if that directory is in a folder a sync client mirrors or on a network filesystem, because the keys would then be copied wherever that folder goes.
Create a brain #
$ ns-brain zk create people-ops --server https://hive.fightclub.pro
The label is the one thing about the brain the server can read, so keep it short and neutral. The command then:
- Shows the list of what you give up and waits for you to type
I understand. - Shows the recovery paper and its label. Write both down. Press Enter, the screen clears and you type the paper back from what you wrote. A typo that breaks its checksum is caught and you try again.
- Creates the brain with this device as its first owner and prints the brain's uid, its genesis fingerprint and a join instruction for the second device.
Send the join instruction to the second device over a channel the server does not carry. It looks like this:
ns-brain zk enrol --brain <brain uid> --genesis <genesis fingerprint> --server https://hive.fightclub.pro
Until a second owner device is enrolled the brain accepts no content and an alert stays open on this device.
Enrol a second device #
On the new device, signed in to the same organisation:
$ ns-brain zk enrol --brain <uid> --genesis <fp> --server https://hive.fightclub.pro
It prints a request id and this device's fingerprint, then waits up to ten minutes for approval (--wait changes that). --no-wait returns at once and zk enrol --brain <uid> --finish picks it up later. A request expires after a day.
On an admin or owner device of the brain:
$ ns-brain zk pending --brain <uid> $ ns-brain zk approve <request_id> --role owner --paper --brain <uid>
The approver types the fingerprint the new device shows. The terminal then shows a confirmation code and the new device's person types it in. Read both codes over voice or video, never through the server. A code that does not match ends the attempt, because that mismatch is exactly the substitution the codes are there to catch.
Approving hands over the brain's keys, so it needs proof a person is present. --paper asks you to type the recovery paper. --approval <code> takes an approval from a second owner device instead (see approvals). A brand new brain has only one device, so its first enrolment takes the paper.
The roles are reader, contributor, curator, admin and owner. Only owners act on owners: an admin cannot grant, demote or revoke one. When enrolment finishes, the new device prints the genesis fingerprint and the head fingerprint. Compare them with the first device.
Bind a project #
In the project's repository, on an enrolled device:
$ ns-brain init --brain <uid>
This does three things. It writes a marker into the project's brain.json naming the brain, so every clone carries it. It binds the directory to the brain on this device. It creates the project inside the brain, as a signed entry in the brain's own log. Commit brain.json.
It does not wire the hooks yet. Once they are wired, every agent session started there receives the brain's content. So the client first prints where that content will then live and asks for an approval from a second owner device. With the code from that device:
$ ns-brain init --brain <uid> --approval <code>
The per-prompt recall hook stays off unless you add --auto-recall. That hook sends prompt-matched memories to the model provider with every message, which is most of how a brain's content leaves your machine.
On another device, or in another clone, the marker is already there but it never binds a directory by itself. Anybody can ship a brain.json and the uid in it is not secret. Bind it on each device:
$ ns-brain zk bind --brain <uid> # or run init --brain again $ ns-brain zk status # what the boundary decides here
A worktree, a second clone, a moved repository or rewritten history is a partial match. The client refuses and prints the command that completes the binding. A clone without the binding refuses every ordinary command and sends nothing in plaintext, on any client that knows the marker.
Working in it #
Inside a bound directory the commands you already know work against the replica: recall, remember, update, forget, log, task, brief and the session hooks. Writes are sealed on the device and sent to the server. Reads never touch the server.
$ ns-brain zk sync # pull, apply and push now $ ns-brain zk sync --status # cursors, unsent, buffered, conflicts $ ns-brain zk sync --conflicts # edits from two devices waiting on a person $ ns-brain zk sync --resolve <uid> --keep a
The session is bound as well as the directory. A session that started in the bound directory reads it and cannot write anywhere else, even after a cd. A session that started somewhere else and then reaches the brain is refused, reads and writes alike. Inside a bound directory BRAIN_HOME, BRAIN_PROJECT and the hive fields of brain.json are ignored.
Agents should use MCP over stdio on an enrolled device. It binds from the roots the host reports. MCP over HTTP and ns-brain ui are refused for a blind brain on any address.
Status and doctor #
$ ns-brain zk status # what the boundary decides here, the replica and alerts $ ns-brain zk doctor # keys, key version, the paper, alerts and each device's chain $ ns-brain zk list # the blind brains this device can see $ ns-brain zk alerts # open alerts
None of them print content. In a directory that is not bound, zk status says so:
$ ns-brain zk status
not a zero-knowledge brain here: calls from this directory and session go to the readable store
Alerts go to the operating system's notifications, because a hook's output is not reliably shown to you. Clearing one takes the code from the notification and the paper or a second owner device: zk ack <id> --paper. An alert can say a device was lost or a history was forked, so it does not go away on an agent's say-so.
Projects inside the brain #
$ ns-brain zk node list $ ns-brain zk node create payroll # a project, under the brain's top $ ns-brain zk node create finance --kind team $ ns-brain zk node create payroll --parent <uid> $ ns-brain zk node rename <uid> <name> $ ns-brain zk node delete <uid>
A node is a signed entry in the brain's own log, so every device can prove which brain it belongs to. The server cannot move, rename or delete a node inside a blind brain. init --brain creates the project node for you. You need contributor or above to create one. Deleting one needs a person at a terminal and a binding to a deleted node refuses with the reason.
Second-device approvals #
Some actions move content out of the brain or change who holds it. Each needs an approval from a second enrolled owner device, which shows exactly what leaves and where. Run the command. It refuses and prints a command to run on the other device:
# on the second owner device $ ns-brain zk declassify approve <token> # back on the first, with the code it showed $ ns-brain zk unbind --approval <code>
An approval is good once, for that content and that destination, for an hour. The code travels from the approver to the requester, never the other way. zk declassify request <content> --to <dest> and zk declassify confirm <token> --code <code> do the same steps by hand.
Two devices are what makes this hold. An agent on one device cannot complete an approval. Agents on two enrolled devices could, so keep approval in a person's hands.
A lost or retired device #
From any other admin device:
$ ns-brain zk revoke <device> --lost --brain <uid> $ ns-brain zk paper replace --paper --brain <uid> # on an owner device $ ns-brain zk paper verify --brain <uid>
--lost revokes the device, asks the server to cut its access at once and rotates the brain's key straight away. It then lists every other brain the server says that machine was in. It revokes the ones this device holds keys for, asking you to confirm each one. For the rest it prints the command their admins run. It does not report done until no brain still holds the machine. Then replace the paper, because the lost device may have had what it needs to help forge a recovery.
--retired is for a device you decommissioned. It asks whether any backup or copy of it exists. Any answer but no is treated as lost. Run on the device itself, it wipes that device's keys and replica for the brain.
zk quarantine <device> holds a device's new entries on every device while you find out what happened. zk unquarantine lifts it. zk rotate issues a new data key on its own.
The recovery paper #
$ ns-brain zk paper verify # does the paper still open this brain $ ns-brain zk paper replace --paper # or --approval <code>
Check the paper now and then. verify changes nothing. replace rotates the key, shows a new paper the same way create did and makes you type it back. Destroy the old one afterwards. Replacing it needs the current paper or a second owner device, because whoever reads the new one holds the brain's recovery.
Recovery #
Every owner device lost, another device still enrolled, paper held. On that device:
$ ns-brain zk recovery --break-glass <device> --brain <uid>
Signed with the paper, it makes that device an owner after 72 hours unless an owner device vetoes it. Every device is alerted. Then revoke the lost owner devices and replace the paper.
No enrolled device left, paper held. On a fresh device signed in to the organisation:
$ ns-brain zk recovery --brain <uid> # 72 hours later $ ns-brain zk recovery finish --brain <uid>
For the 72 hours the device holds no key and the server sends it no content. finish asks for the paper again, revokes every earlier device, rotates the key and issues a new paper.
Paper and every owner device lost, two admins of different people left.
$ ns-brain zk paper replace --two-admin # first admin $ ns-brain zk paper approve <proposal> # an admin who is a different person $ ns-brain zk paper finish # after 72 hours
The holder of the new paper then uses break-glass to restore an owner. Without two admins who are different people, the brain carries on without a way to recover until there are.
Any owner device can stop a pending recovery, break-glass or paper replacement with zk veto <op>. If one of these appears and nobody on your side started it, veto it and treat the device that started it as compromised.
Delete and undelete #
$ ns-brain zk delete --brain <uid> $ ns-brain zk undelete --brain <uid>
Deleting takes a person at a terminal who types the brain's id back. The brain is soft-deleted for 30 days. Every device is told who deleted it and how to undo it, again each day of the window. Any owner device can undelete within it. The organisation's owner can also soft-delete a brain without being enrolled, for the case where every device and paper is gone. A brain under a legal hold cannot be deleted.
After 30 days it is deleted for good and the server keeps a record that it was. That record stops the same brain being created again on the server. Copies in people's replicas are theirs to wipe.
What a bound directory refuses #
A bound directory and a session that started in it refuse anything that would carry content out of the brain. Each refusal says why and names the command to run instead, if there is one.
| Command | Why | What happens |
|---|---|---|
export, zk dsar export | Writes the brain's content to a file in plaintext | Needs a second-device approval. The file carries the brain's header |
import of a file exported from a blind brain | Reads that brain's content into somewhere else | Needs a second-device approval, wherever it is run |
zk unbind, zk bind --rebind, uninstall | Would let the directory send content elsewhere | Needs a second-device approval |
remember --everywhere | Stores at the organisation, outside the brain | Refused |
note or dm to another project or session | Carries text out of the brain | Refused |
axiom, standard, publish, release | Write to the spine every project reads | Refused. Org rules reach the brain only through its own signed manifest (zk manifest) |
describe, bootstrap, feedback, whoami, sessions, global | Reach the shared index, other sessions, the spine or the vendor in plaintext | Refused |
share, private, absorb, relabel, promote | Move rows between stores or projects in plaintext | Refused |
backup, snapshot, prune | Write a plaintext copy of the whole brain | Refused. Keep a spare enrolled device instead |
import into the brain | A file of rows skips the replica's write guards | Refused. Use remember |
hive commands | Talk to the server in plaintext | Refused. Use ns-brain zk |
Plain init, upgrade | Would wire the brain as a readable one | Refused. Use init --brain <uid> |
ns-brain ui, MCP over HTTP | Cannot tell a local caller from a relayed one | Refused on every address |
| Any request naming no project | The server would file it at the organisation | Refused |
What the client cannot stop #
Server-blind moves the place your data is exposed from our servers to your machines. Before the hooks are wired the client makes you acknowledge where the content will then live:
- The replica on each device, every backup of that device, swap and hibernation files.
- The agent's transcripts, compaction summaries and auto-memory. A cloud session's transcript stays with the vendor.
- The model provider's logs, ours included if the agent's model goes through our gateway.
- Every file, commit, pull request and message the agent writes.
- Any committed hook or
CLAUDE.mdin the repository, which run in the same session. A bound directory warns at session start when its hooks differ from whatinitwrote.
The agent runs as you. It can read the replica, the keys and the credential file. Every refusal on this page stops an agent that is confused or prompt-injected and goes through ns-brain. None of them stops a compromised one. That is why no approval can be given by a single device and why full-disk encryption on every enrolled machine matters.
For the other two arrangements where we cannot read your data, the free local edition and Enterprise, see the security page.