Security
Security notes
The trust model for the LogMotif desktop app and the attach SDK, stated plainly. Last updated 31 July 2026.
Threat model
LogMotif is a local developer tool for a single trusted user on their own machine. We do not claim isolation against a malicious process that can already run code as you. If your machine is compromised, LogMotif is compromised.
What stays local
- Runs, branches, events — SQLite at ~/Library/Application Support/com.logmotif.app/logmotif.db.
- API keys — macOS keychain, service com.logmotif.app.
- Settings — SQLite + keychain. Never uploaded by LogMotif.
Model and tool calls do leave your machine when mock mode is off — to OpenAI, Anthropic, Tavily, Ollama, or URLs you pass to http_get. That is provider traffic, not a LogMotif backend.
The attach listener is authenticated (since v0.2.0)
When LogMotif is running it listens on 127.0.0.1:7741 so your agents can stream events into it. From v0.2.0 that listener requires a token.
The app writes a random token to its application-support directory, readable only by your user account, and every connection must present it before any command is accepted. Your own agents pick it up automatically — no configuration. A web page cannot read a file on your disk, so it cannot forge the handshake.
This matters because "local" is broader than it sounds: a page you visit can issue a cross-origin request at that port. It cannot read the reply, but before v0.2.0 the side effects still landed. In v0.1.0, anything able to open a TCP connection to that port could:
- write events into your local database, including into existing runs;
- call the model and tool proxies — spending money on your configured API keys;
- end attach sessions for runs it can name.
Treat port 7741 the way you would treat an unauthenticated local database port. Concretely:
- Keep LogMotif up to date. The token protects the listener from v0.2.0 onward; earlier builds do not have it.
- Never expose 7741 beyond the machine — no SSH reverse tunnels, no Docker port publishing to a LAN, no reverse proxy.
- Prefer mock mode when you don't need live calls; it needs no keys, so there is nothing to spend.
If you are on v0.1.0, upgrade. That build has no attach authentication, and it also ships a shareable-tape export that could execute recorded content when opened. Both are fixed in v0.2.0.
Fork and spawn
Live re-execute of an attached Python agent spawns the interpreter and script recorded in the run config. Path validation is deliberately light, because fork re-runs your agent. Two consequences worth knowing:
- Imported JSON runs strip attachExecutable, so a run someone shares with you cannot plant a path that fork would execute.
- Runs created over the attach listener do not get that treatment in v0.1.0. Only click "re-execute live" on runs you recognise.
http_get guard
Live http_get refuses non-HTTP schemes, URLs with embedded credentials, and hosts that resolve to loopback, RFC1918, link-local, CGNAT, or cloud metadata addresses. The final URL after redirects is re-checked.
This is a guard, not a sandbox: it does not currently validate every intermediate redirect hop, and a hostile DNS server could in principle change its answer between the check and the request. Do not rely on it as a security boundary against URLs you already distrust.
What we do not promise
- Isolation between concurrent agents on one machine.
- Protection if malware already runs as your user.
- That a "prove-the-fix" verdict is correct — it is a heuristic signal, not a proof.
Reporting a vulnerability
Email hello@catalistclub.com with steps to reproduce. This is a solo-maintained beta: expect a human reply, not a triage SLA. Please allow a reasonable window for a fix before publishing.