Download Cloak
One app for every person, one small server for all of them. Run it for yourself on your own machine, or for your whole team on a host you control — either way the database and every key stay with you.
Released Sep 16, 2026 · Release notes
Cloak Server
The backend every app connects to. Runs with Docker or Node.js on any machine you control — one for your whole team, or one just for you.
cloak-server-v0.3.0.zip · 280.6 KB
Installers are not code-signed yet, so Windows and macOS will ask you to confirm the publisher — the setup guide below shows how. Every asset is also listed, with its checksum, on the releases page.
Before you start
What you need
The app runs on any current desktop. The server is a small Node.js process and a MongoDB — a laptop, a Raspberry Pi or a $5 VPS all do.
Desktop app
- Windows
- 10 or 11, x64
- macOS
- Intel or Apple Silicon
- Linux
- x64 — AppImage, .deb or .rpm
Server
- Runtime
- Docker, or Node.js 22+
- Database
- MongoDB Atlas or v7 (bundled with Docker)
- Resend API key (optional)
Running it well
- Back up MongoDB
- It holds the only copy of every wrapped key. Lose it and every vault is gone — no support path can bring it back. That is the design.
- Run one API instance
- Rate limits live in process memory, so a second worker quietly doubles every limit. The pm2 config pins one instance for this reason.
- Rotating JWT secrets
- Changing JWT_SECRET or REFRESH_SECRET signs everyone out. Nothing is lost; everyone signs in again.
- Removing a member
- They lose server access immediately, but anything already decrypted on their device stays readable. The organization key is not rotated.
Prefer to build it yourself? Development setup covers the repository, and the architecture notes explain how team keys work.
Setup guide
From download to unlocked
The same server and the same app either way. Pick who it is for and the steps adjust.
- 01
Install the app
- Run the .exe installer, or the .msi if you deploy software with Group Policy or Intune.
- Windows SmartScreen may stop an unsigned installer. Choose More info, then Run anyway.
- 02
Start your server
On any machine your team can reach — a cloud VM, a droplet, a box in the office. You need Docker, or Node.js 22 and a MongoDB you control. Unpack the server bundle and generate its secrets:
Unpack and configureunzip cloak-server-v0.3.0.zip && cd cloak-server-v0.3.0 ./setup.shCheck the download first, if you like:
sha256sum -c cloak-server-v0.3.0.zip.sha256setup.sh writes .env with JWT_SECRET, REFRESH_SECRET, OWNERSHIP_KEY and HEALTH_TOKEN already filled in — 384 bits each from the system's secure random source — and prints the ownership key once. Copy it somewhere safe now: it is how you prove the server is yours.Then fill in .env
MONGODB_URISet- Your database. Leave it blank with Docker, which runs MongoDB alongside the API.
PUBLIC_URLSet- The address teammates reach this server on, exactly as they would type it. It is written into every join key, so a wrong value means nobody can connect.
RESEND_API_KEY- Optional, with RESEND_FROM_EMAIL. Without it, codes and invitations go to the server log and the app hands you join keys to pass on yourself.
And start it
API + MongoDBdocker compose up -dStarts the API and its own MongoDB, bound to this machine only. Data lives in a Docker volume and survives restarts.
- 03
Put TLS in front
For a server your team reaches over the internet, the bundle ships a Caddy overlay. Point DNS at the machine, then:
docker compose + CaddyCLOAK_DOMAIN=vault.example.com \ docker compose -f docker-compose.yml -f docker-compose.tls.yml up -dThe Caddy overlay gets and renews a certificate by itself once DNS points at the machine. The desktop app refuses plain http:// except on loopback, private LAN ranges and Tailscale, because vault contents are encrypted on each device but session tokens are not. - 04
Check it
Status page
Open PUBLIC_URL in a browser for a status page that refreshes itself: is the server up, which version it runs, and does anyone own it yet.
Detailed view
Append ?key=<HEALTH_TOKEN> for the database, record counts, the Resend key (masked), uptime and memory.
For monitoring
GET /status.json serves both tiers as JSON for uptime checks and dashboards.
- 05
Take ownership
- 1Open Cloak. Its first screen asks which server — enter your PUBLIC_URL.
- 2The app checks the server, its version, database and mail, and says exactly what to fix if something is off.
- 3Enter the ownership key from setup.sh, then sign up as normal. You become the owner.
- 4The key is spent atomically with your account and the server becomes invite-only. Remove OWNERSHIP_KEY from .env.
- 06
Add your team
01Invite
Team → Invite creates a join key: one string that names your server and carries the invitation. It is tied to one email address and expires.
02Join
The new member installs Cloak and pastes the join key into the first screen. The app finds your server and redeems the invitation in one step.
03Grant
Joining grants nothing. An existing member seals the organization's key to the new device, on their own machine, with a key the server never holds.
04Verify
Before granting, read the member's key fingerprint back to them on a call. It is the defence against a compromised server swapping in its own key.
- 07
Keep it current
The app updates itself. It checks when it starts and every few hours, and Settings → Updates shows what is new and installs it with one restart. Everyone updates their own copy.
The server is released separately and never updates itself. When a newer one is out, owners and admins see a notice in the app's organization settings. Read its release notes first: if they say the apps need a newer version, have everyone update before you upgrade.
Replace the server files, keeping .envcd /path/to/your/cloak-server unzip -q ~/Downloads/cloak-server-v0.3.0.zip -d /tmp/cloak-upgrade rsync -a --delete --exclude .env --exclude node_modules \ /tmp/cloak-upgrade/cloak-server-v0.3.0/ ./Restart with Dockerdocker compose up -d --buildUpgrade in the directory the server already runs from, not a freshly unzipped one. Docker names the database volume after the directory, so starting from a new folder starts an empty, unclaimed server while your data sits untouched in the old volume. Back up MongoDB first; any database changes run by themselves on start.