Local Capability Surfaces Need Defense in Depth

Local capability surfaces need defense in depth

Local is not the same thing as harmless. A local daemon usually has more authority than a normal app window: it can read a database, mutate state, open files, talk to providers, and sometimes run user-configured hooks. Once a client can reach that daemon, it is not "just localhost" anymore. It is a capability surface.

The mxr security pass made this concrete. The system was already local-first and basically sound, but several edges were relying on friendly defaults: Unix socket permissions inherited from umask, OpenAPI docs exposed without bridge auth, attachment destinations accepted from IPC, and remote image reads used response.bytes() without a hard cap.

None of those were dramatic by themselves. Together they were a smell: too much trust was implicit.

The pattern

Treat every local entrypoint as if a confused or malicious local client might reach it:

The point is not paranoia. The point is that local tools age. They gain a web UI, a CLI, an agent skill, a script ecosystem, then somebody binds a bridge through a tunnel. Explicit boundaries survive that growth better than "it only runs on my machine."

What changed in mxr

Validated against code on 2026-05-28:

Why this generalizes

Any local-first app with a daemon has the same shape: sensitive local state, multiple clients, and a bridge somewhere. Mxr is email, Lazydap is debugging, a future memory daemon would be personal knowledge. The domain changes. The capability-surface problem does not.

See also