claude-in-mobile runs locally under the user's account and drives interactive sources (Android, iOS, desktop, browser, terminal REPL). Because it is granted the trust of the user it impersonates, any input flowing through it is sensitive — including, in particular, the output of REPL sessions, which is the most likely place developer credentials surface.
This document is the baseline the 3.11.0 release commits to. It is not the final permission model — third-party plugin loading and capability-based sandboxing arrive in 4.0 with their own ADR.
- Local user trust boundary. Anything Claude does locally inherits the user's filesystem, env, and network access. We do not attempt to defend against the user attacking themselves; we defend against unintentional leakage to MCP clients and downstream LLM transcripts.
- Two material risks:
- Credential exfiltration through MCP responses. A REPL session prints a token; the LLM reads it; the transcript persists it.
- Arbitrary command execution.
repl_spawnaccepts a free-form command. Equivalent tosystem_shell; same trust posture.
- Redaction layer on plugin output. All
repl_snapshotresponses pass throughsrc/plugins/repl/redaction.tsbefore leaving the plugin. The patterns cover AWS keys, GitHub PATs, OpenAI/Anthropic keys, Bearer headers, JWTs, Google API keys, Slack tokens. False positives are acceptable; false negatives are not. Update the pattern list whenever a new credential shape appears in incident reports. - ENV allowlist. The REPL supervisor process inherits only
PATH,HOME,LANG,LC_ALL,TZfrom the MCP server (seeminimalEnv()insrc/plugins/repl/client.ts). Per-session environment is passed explicitly throughrepl_spawn.envand never sourced fromprocess.env. - In-process REPL state. Session scrollback is never persisted to disk. The supervisor process dies with the MCP server (parent close → child reader EOF → exit), so secrets cannot linger across restarts.
- No third-party plugins. Plugins are in-tree only. There is no plugin
loader for arbitrary directories; manifests are not consumed from
userland. The runtime contract is published as a separate package
(
@claude-in-mobile/plugin-api) so out-of-tree plugins can be developed, but registering them requires changes tosrc/runtime/bootstrap.ts. - Audited dependency graph.
ci.ymlrunsnpm audit --omit=dev --audit-level=highandcargo audit --deny warningson every push. A high or critical advisory in production deps fails the build. - Architecture isolation tests.
src/architecture.test.tsblocks cross-plugin imports and protects the kernel from picking up plugin knowledge. Reduces blast radius if a plugin needs urgent removal.
- Per-plugin permission grants (
requires: ["subprocess:bash"], etc.). plugins.lockwith sha256-pinned third-party plugins.- Sandboxing / WASM isolation for plugins.
- Signature verification (Sigstore / minisign).
These are tracked under the v4 security ADR.
Security issues — please report to alex@gladkov.dev rather than filing a public GitHub issue. Acknowledgement within 48 hours, fix or mitigation within two business weeks for high severity.