Check it yourself
Written for desktop 0.1.91, 19 October 2026. Updated 23 October 2026.
We have run every command on this page, except the Windows connection check.
Installing an app means trusting it with your computer. You shouldn't have to take our word for what KithMoot does, so this page lists everything the desktop app connects to and everything it can touch, with a way to check each claim. If you find something we haven't listed, tell us: that's a bug in the app or in this page.
Not sure yet? KithMoot in your browser runs inside your browser's own sandbox and can't see your files at all. The desktop app adds area sharing, redaction and desktop notifications.
The short version
- No analytics, tracking or crash reporting.
- Camera and microphone only after you turn them on in a call. Your screen only after you pick what to share.
- Files only when you choose them, or choose where to save.
- The app can't read your clipboard, and location, USB and serial port requests are refused.
- Room messages and files are encrypted on your device before they leave it.
- All of the app's code is in the download. It never loads code from a server.
- Updates are installed only if they carry our signature.
- It connects only to the services listed below.
What it connects to
Every connection the app makes, when it makes it, and how to stop it.
- Your rooms' relays. While a room is open, the app talks to the Nostr relays that room uses. New rooms start on relay.primal.net, nostr.oxtr.dev and relay.ditto.pub, public relays we don't run. You can change them in Relay settings.
- Our server, kithmoot.forgesworn.dev. It checks here for updates, 30 seconds after it starts and then every 10 minutes on a Mac, or every hour on Windows and the Linux tar.gz. There's no switch for this yet. Each check fetches a static file, as any web page does. Up to 0.1.101, in a call it also asks our STUN server for your device's public address, which helps a direct connection through home routers; STUN carries no content. That public STUN listener stopped on 23 October 2026; an older installed app can still name it. We no longer run a public call relay (TURN): since 22 October 2026 a build that still asks this server for a call credential is told so. A separate authenticated private relay exists for an arranged call; it is not an app default or a public credential service.
- Cloudflare's STUN server, in a call, from 0.1.102. From 0.1.102, in a call the app asks stun.cloudflare.com instead of our server for your device's public address, which helps a direct connection through home routers. STUN carries no content. Cloudflare runs it, not us. To use your own instead, enter it under Settings, Connections, Your STUN server. A room whose link names its own call servers also uses those instead.
- GitHub, for the Debian and Ubuntu package. apt fetches KithMoot's updates from the project's GitHub releases, along with your other system updates.
- Public profile relays and picture hosts. With Show public profile pictures, names and Nostr addresses on, which it is unless you turn it off, the app looks up the people in your rooms, your private chats list and People, and the senders of invitations you already know, on purplepag.es, relay.damus.io and relay.primal.net, and also on the room's relays for the people in the room you have open. It loads each person's picture from wherever they host it. Turn it off under Settings, Privacy.
- The people on your call. Calls connect straight to the other people's devices where they can, so those people can see your IP address, as in any direct call. When a direct connection fails, the call can use a relay configured on your device or named by the room. ForgeSworn provides no public relay login; independently supplied and private relays see connection metadata and encrypted packets, as the privacy notice describes.
- Public call relays, only if you turn them on. In the web app, "Find public call relays on my Nostr relays" under Settings, Connections asks the Nostr relays in your Connections list (relay.primal.net, nostr.oxtr.dev and relay.ditto.pub unless you changed them) for adverts operators publish themselves; each learns your IP address, the time and that a search was made, but not which Nostr key searched. KithMoot runs no list of call relays and does not check, rank or vouch for anyone listed. A relay you choose and check or use learns your IP address, the time, the call's volume and which web app asked, over HTTPS to its own address and then TURN on port 3478, 5349 or 443. The request carries no cookies or referrer; the hour-long login it issues stays on your device for that call. That operator decides what it keeps.
- Only if you choose them. A file storage server, if you set one up for sharing files. The domain in someone's Nostr address, if you turn on Verify Nostr addresses. Your signer's relays, if you sign in with a remote signer. A link you click, which opens in your browser after you confirm.
Not Google. Before 0.1.91, the app downloaded a spelling dictionary from a Google server on Windows and Linux, through the spellchecker built into Electron, the framework it runs on. From 0.1.91 that download is switched off, so there's no spelling check on those systems for now. The Mac app uses macOS's own spellchecker, which downloads nothing. We started a fresh copy of 0.1.91 on Linux and logged every connection: the only server it contacted was ours, for the update check. Windows runs the same code, but we haven't watched its connections.
You may find walletofsatoshi.com in the app's code. It's there for a donor ring that is switched off, so the app never contacts it.
What it can touch on your computer
- Camera and microphone: only after you turn them on in a call. macOS asks your permission the first time. Windows and Linux may not ask, so on those KithMoot's own buttons are the only thing in the way.
- Your screen: only after you choose a screen, window or area to share. On a Mac, macOS asks for Screen Recording permission first. On Linux with Wayland, your system's own screen picker makes the choice. On Linux with X11, any app can read the screen; KithMoot captures only after you pick.
- Files: only the ones you choose in a file dialog or drop into a chat. Saving always goes through a save dialog.
- Clipboard: pasting works as usual, and the app can copy when you ask it to. It can't read the clipboard by itself.
- Your local network: the app asks before it connects to relays or services on your own network.
- Everything else is refused: location, USB, serial ports and any other permission not on its short list.
- Its own folder: settings and history live in
~/Library/Application Support/KithMooton a Mac,~/.config/KithMooton Linux and%APPDATA%\KithMooton Windows. Uninstalling leaves the folder in place; delete it to remove everything.
The limit we can't hide
Rooms, chat and calls run in a sandboxed part of the app with no access to your files or system, the same protection a browser tab has. Around it sits a small native part, about 2,000 lines you can read, which opens windows, shows file dialogs, picks screens and installs updates. Like most desktop apps, that native part runs as you and could read anything you can. It doesn't, and the next section shows how to check. The operating system doesn't sandbox the app yet: there's no macOS App Sandbox and no Flatpak.
How to check
That the download came from us
Download SHA256SUMS.txt into the same folder as your download, then run:
# Linux
sha256sum --check --ignore-missing SHA256SUMS.txt
# macOS
shasum -a 256 --check --ignore-missing SHA256SUMS.txt
# Windows (PowerShell): compare the result with SHA256SUMS.txt by eye
Get-FileHash KithMoot-0.1.91-windows-x64.zip -Algorithm SHA256
That proves the file wasn't damaged on the way, but it comes from the same server as the download. To check that we made it, verify our signed release list. The check uses the key built into the app, fetched from GitHub rather than from our server. You need Node.js:
curl -fsSO https://raw.githubusercontent.com/forgesworn/kithmoot/main/desktop/update-manifest.mjs
curl -fsSO https://kithmoot.forgesworn.dev/downloads/release.json
curl -fsSO https://kithmoot.forgesworn.dev/downloads/release.json.sig
node -e "import('./update-manifest.mjs').then(m => { const fs = require('fs'); console.log(m.verifyManifest(m.MANIFESTS.desktop, fs.readFileSync('release.json'), fs.readFileSync('release.json.sig', 'utf8')) ? 'Signature OK' : 'Signature FAILED') })"
If it prints Signature OK, compare your file's SHA-256 with the one listed for it in release.json. update-manifest.mjs is about 120 lines; read it first if you like. The Windows app and the Linux tar.gz use the same two keys to accept or refuse every update. A Mac update must carry the same Apple signature as the app you installed, and apt checks the Debian package's updates against the repository key.
On a Mac, check Apple's signature and notarisation:
codesign --verify --deep --strict /Applications/KithMoot.app
codesign -dv --verbose=2 /Applications/KithMoot.app
The first command prints nothing if the signature holds. The second should show a Developer ID Application authority and Notarization Ticket=stapled. Notarisation means Apple scanned the app for known malware. It doesn't mean Apple reviewed what the app does.
What it connects to
With KithMoot open, list its connections:
# Linux
ss -tunp | grep -i kithmoot
# macOS
lsof -nP -i -a -c KithMoot
# Windows (PowerShell)
Get-NetTCPConnection -OwningProcess (Get-Process KithMoot).Id
These show addresses, not names, and many relays sit behind Cloudflare, so most addresses will be Cloudflare's. To see names, and to approve or block each connection as it happens, use a firewall that asks: OpenSnitch on Linux, or LuLu or Little Snitch on a Mac. On a Mac you'll also see UDP port 5353. That's mDNS on your own network, which keeps your local address out of call connections.
What the Linux package runs as root
Installing any .deb runs its scripts as root. Read ours before you install, and list the files it marks setuid:
dpkg-deb -e kithmoot_0.1.91_amd64.deb kithmoot-scripts
cat kithmoot-scripts/postinst
dpkg-deb -c kithmoot_0.1.91_amd64.deb | grep '^-rws'
The one setuid file is chrome-sandbox, Chromium's own sandbox helper. The script installs an AppArmor rule at /etc/apparmor.d/kithmoot. The rule doesn't restrict the app; it lets Chromium's sandbox start on Ubuntu 23.10 and later. The script also removes an old menu entry, and only one that the tar.gz installer wrote. The tar.gz runs nothing as root: it installs into your home folder.
The app's code
The whole desktop app is one archive, app.asar. Unpack it with Electron's own tool:
npx @electron/asar@4.3.0 extract /Applications/KithMoot.app/Contents/Resources/app.asar kithmoot-code
On Linux it's /opt/KithMoot/resources/app.asar, or ~/.local/share/kithmoot-desktop/resources/app.asar for the tar.gz. On Windows it's resources\app.asar in the folder you extracted. Start with these files:
main.mjs, the native part;policy.mjs, the permission list and the only address the app serves its own pages from;preload.cjs, everything the sandboxed part can ask the native part to do;update-manifest.mjs, the update keys.
The rooms themselves are in web/. That code is built and minified; the readable source is on GitHub.
The permissions your system gave it
On a Mac, look in System Settings, under Privacy & Security: Camera, Microphone, Screen & System Audio Recording and Local Network. You can withdraw any of them. To see the special permissions the app was signed with, run:
codesign -d --entitlements - /Applications/KithMoot.app
There are three: camera, audio input, and allow-jit, which the JavaScript engine needs to run quickly.
Build it yourself
The source is on GitHub under the MIT licence, and desktop/README.md explains how to build it. Builds aren't reproducible byte for byte yet, so yours won't match ours exactly.
What we can't promise yet
- The operating system doesn't sandbox the app.
- The Windows build isn't signed, so Windows warns about it.
- Builds aren't reproducible, so you can't yet prove our download matches the source.
- The update check has no off switch.
- Linux doesn't ask before an app uses the camera or microphone, and on X11 any app can read the screen.
Found something we missed?
If the app does something this page doesn't say, or a command here gives a different answer, open an issue. We'll fix the app or the page.
If you've found a way to read what you shouldn't, run code on someone's computer or slip in a false update, please don't post it in public. Report it privately instead, so it can be fixed before anyone else learns of it. Only the project's maintainers see a private report. You need a GitHub account for either route.