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)
Email
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.

  1. 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.
  2. 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 configure
    unzip cloak-server-v0.3.0.zip && cd cloak-server-v0.3.0
    ./setup.sh

    Check the download first, if you like: sha256sum -c cloak-server-v0.3.0.zip.sha256

    setup.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 + MongoDB
    docker compose up -d

    Starts the API and its own MongoDB, bound to this machine only. Data lives in a Docker volume and survives restarts.

  3. 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 + Caddy
    CLOAK_DOMAIN=vault.example.com \
      docker compose -f docker-compose.yml -f docker-compose.tls.yml up -d
    The 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.
  4. 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.

  5. 05

    Take ownership

    1. 1Open Cloak. Its first screen asks which server — enter your PUBLIC_URL.
    2. 2The app checks the server, its version, database and mail, and says exactly what to fix if something is off.
    3. 3Enter the ownership key from setup.sh, then sign up as normal. You become the owner.
    4. 4The key is spent atomically with your account and the server becomes invite-only. Remove OWNERSHIP_KEY from .env.
  6. 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.

  7. 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 .env
    cd /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 Docker
    docker compose up -d --build
    Upgrade 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.