OpenClaw shipped 512 vulnerabilities in early 2026 and 21,000+ instances were exposed on the public internet leaking API keys. We watched that happen and took notes. MasterMode's design choices are largely a reaction to that incident.
- No skill marketplace. OpenClaw's biggest blast-radius vector was user-installed third-party "skills" — over 800 of which turned out to be malicious. MasterMode has no plugin system and no remote-fetched code execution. All extension points (LLM provider, embedding provider, search provider) are pinned at install time via env vars.
- No remote code loading. The chat agent's tools are a fixed list
in
lifeos/ai/tool_defs.py. The agent cannot install new tools, run shell commands, or write files outside the database directory. - No public-internet default binding.
mastermode servebinds to127.0.0.1by default. To expose the API to other devices on a network, you have to explicitly pass--host 0.0.0.0. Even then we recommend Tailscale or a reverse proxy with auth — not direct exposure. - No global key store. Secrets live in the user's environment or in
~/.lifeos/mastermode.env(mode 0600 written bymastermode setup). Nothing writes API keys to the database, the audit log, or any user-facing payload. - No telemetry. No analytics, no crash reporting, no "anonymous usage statistics" beacons. The only network calls are to the LLM provider you configured, the embedding provider you configured, and any web search/fetch you explicitly asked the chat agent to do.
- Audit log on every merge.
lifeos/db/migrations/001_embeddings.sqlcreates anaudit_logtable. The dedup adjudicator writes a before/after payload there for every merge, with the actor (user/dedup_daemon/llm). Reversibility is by design: a tombstone of the loser is kept withcanonical_idpointing at the winner. - Provenance on every fact. Each entity row carries a
sourcecolumn tracing the origin (user,llm,shivampkumar.com,voice:memo_2026-05-09.m4a, etc.). The chat path renders this inline so the LLM cites its source, and a user can audit the graph by source. - Pinning.
mastermode pin <name>locks an entity. Pinned entities are never auto-merged or auto-edited. Use this for facts you've manually verified. - Local-first by default. The default embedding provider is
BAAI/bge-small-en-v1.5running locally viasentence-transformers. Combined with Ollama or a local LLM via LiteLLM, no embeddings or conversation text leave the user's machine. - Defensive deserialization. All LLM responses are parsed with bounded JSON extraction; malformed responses degrade to "no facts recovered" rather than executing anything.
- Human-gate dedup. Cosine ≥ 0.97 → auto-merge with audit; cosine
0.88-0.97 → LLM adjudicator decides; user can flag a pair as
permanently distinct via
mastermode dedup distinct <a> <b>. The Java/JavaScript false-positive at 0.911 cosine demonstrates that naive auto-merge would corrupt the graph.
- Prompt injection through the web tools.
web_fetchreturns page content to the LLM. A malicious page could attempt to instruct the LLM to call other tools or leak data. Our guardrail is the Anthropic-style tool list (no shell, no fs writes outside DB), but we welcome a tighter audit. - iOS Shortcut → /api/capture. The HTTP endpoint trusts whatever
POSTs to it. If you expose
serveover a network, anyone on it can add facts to your graph. We document Tailscale + auth-token patterns in the README; a hosted-mode deployment will need its own per-user auth model that we haven't built yet. - Document chunking. Not yet implemented. When it lands, large PDFs and emails become attack surfaces; we'll harden the parser before that ships.
Email shivampkumar [at] gmail [dot] com with details. We'll
acknowledge within 72 hours and won't disclose specifics until a fix
ships. No bounty program yet — but credit is offered.
- No SBOM yet. We pin major versions in
pyproject.toml; full reproducible builds viauv lockare on the roadmap. - No signed releases yet.
- No content-security-policy on the React frontend's chat panel. Locally only it's low-risk; we'll fix before any hosted version.