Fuse
Internals & Extending

Host RPC Threat Model

Trust boundaries, transport security, and exposure for the fuse host JSON-RPC endpoint used by the VS Code extension.

The fuse host command runs a long-lived process that serves the warm fusion engine to the VS Code extension over JSON-RPC. The transport is a named pipe on Windows and a Unix domain socket elsewhere. This page states what the endpoint exposes, who can reach it on a typical developer machine, and the security assumptions the design makes today.

This page is for engineers operating or extending the host, security reviewers assessing local exposure, and contributors implementing hardening work. It does not replace the VS Code extension setup guide; see Connect to your AI for MCP wiring and the extension readme in the repository for fuse host launch details.

Role In The Product

The host is the UI twin of fuse mcp serve. The MCP server exposes the same warm engine to an agent over stdio; the host exposes it to editor panels (index status, dependency graph, scope results, diagnostics) over a local IPC transport. Both surfaces share the same dependency graph, SQLite cache, and orchestrator path, so a scope the extension runs is the same scope an agent would get for the same options.

The endpoint address is derived from the repository root, not passed out of band. Given an absolute root path, the host and extension compute the same address: on Windows a pipe named fuse-host-{hash}, elsewhere a socket file {temp}/fuse-host-{hash}.sock, where {hash} is the first eight bytes of SHA-256 over the normalized root path. A second editor window for the same repository connects to the already-running host; two different repositories stay on distinct endpoints.

Transport And Wire Protocol

Connections use Content-Length framed JSON-RPC (the same framing VS Code language servers use). Methods are namespaced under fuse/:

MethodEffect
fuse/handshakeReturns host and protocol versions for compatibility checks
fuse/statsReturns process id, uptime, and working-set size
fuse/indexWarms the analysis index and dependency graph for a root
fuse/graphProjects the dependency graph (optionally scoped)
fuse/scopeRuns a scoped fusion and writes the emitted payload to a temp file
fuse/explainReturns the context plan without writing a payload
fuse/diagnosticsReturns secret spans, token hotspots, graph gaps, and generated-file hints
fuse/shutdownStops the host
fuse/invalidatedServer push when watched files change (notification, not a request)

Logging goes to stderr only; the transport carries RPC traffic and notifications, not log lines.

Trust Boundary

Fuse treats the host as a local development tool, not a network service.

AssumptionImplication
The machine is a single-user developer workstationAny process running as the same OS user can open local pipes and Unix sockets
The repository root is not a secretThe pipe or socket name is a deterministic function of the root path
The VS Code extension is the intended clientNo caller identity is checked today
Co-tenants on the machine are out of scopeShared CI agents, remote desktops with untrusted peers, and multi-user servers are unsupported

There is no authentication on the wire today. The first RPC method a client typically calls is fuse/handshake, which returns version metadata only and does not issue a credential. Every other method accepts any connected peer with equal privilege: index, scope, diagnostics, and shutdown are all callable without proof that the caller is the extension.

On Windows, named pipes are reachable by local processes subject to the pipe's security descriptor (the default host uses the platform default for user-created pipes). On Linux and macOS, Unix domain socket files live under the system temp directory with permissions inherited from the creating process; any same-user process that knows the path can connect.

Threats And Exposure

The table below lists realistic local threats given the current design. Severity assumes a compromised or curious same-user process, not a remote attacker over the network (the host does not listen on TCP).

ThreatWhat an attacker gainsCurrent control
Connect without being the extensionFull RPC surfaceNone
Derive the endpoint from a known repo pathConnection targetEndpoint is public given the root
Call fuse/scopeReduced source for arbitrary focus, search, or change scopes; path to a temp payload fileSecret redaction in emitted output is heuristic (see Keep Secrets Out)
Call fuse/diagnosticsPrecise file locations and kinds of detected secrets (not the secret values in the DTO, but enough to locate them in the tree)None
Call fuse/index or fuse/graphCPU and disk load; reads the working treeNone
Call fuse/shutdownDenial of service for connected editor windowsNone
Read scope payload filesCopy of a recent emitted fusion from the temp payloads directoryOS temp-directory permissions; see payload lifecycle below
Hold multiple connectionsSame as a single connection; the host accepts several clientsNone

Scope responses write the emitted payload under {temp}/fuse-host-payloads/ with a unique name per call. The extension opens that file read-only immediately after the RPC returns. Until the OS reclaims temp files, another same-user process that guesses or enumerates names could read a payload. Payload placement and cleanup are tightened separately (private application data and delete-on-shutdown); this page records the exposure either way.

The host watches the source tree and broadcasts fuse/invalidated to every connected client when files change. A rogue client can subscribe to the same stream of notifications if it keeps a connection open; it does not need to be the extension.

What This Design Does Not Protect

The host RPC surface is not a substitute for:

  • Network isolation. Nothing in the protocol encrypts or authenticates traffic; it is not exposed on a network port by design.
  • Multi-tenant hosts. Do not run fuse host on a shared machine where untrusted users share the same OS account.
  • Malware resistance. Malware with user privileges can connect, scope the repository, and shut the host down.
  • Compliance-grade secret scanning. Diagnostics and scope output use the same heuristic redactor as fusion; they reduce accidental exposure but do not guarantee removal.

Fuse does not sandbox repository access: a caller that can connect can ask the host to fuse any root path the host process can read. The host does not re-verify that the caller owns the workspace VS Code opened.

Planned Hardening (Session Token)

Remediation work adds a session token issued at host start and returned in the fuse/handshake response. Subsequent RPC methods will require that token (for example in an Authorization header or a required JSON-RPC parameter). The extension will store the token from its handshake and attach it to later calls.

That change raises the bar from "know the pipe name" to "observe the handshake or win a race against the legitimate client." It remains local IPC security: it blocks casual cross-process snooping and scripted port scanning of predictable pipe names, but it does not defend against a determined same-user attacker who can read the extension process memory or intercept the handshake on the same machine. The token is not a substitute for network TLS or user login.

Document this threat model before shipping the token so operators know what improved and what did not.

Operational Guidance

  • Run fuse host only on machines you trust, under your own user account, for local editing.
  • Do not forward the pipe or socket over SSH remote development unless you accept that anyone with access to the remote user session can call the RPC surface.
  • Treat scope payloads and diagnostics as sensitive: they can summarize secret locations and reduced source from the repository.
  • Prefer shutting down the host when not using the extension (fuse/shutdown or stopping the process) on shared workstations.
  • For agent workflows, use fuse mcp serve over stdio with your editor's MCP client configuration; the MCP server has its own trust model (parent process owns the stdio pipe).
SurfaceTransportCaller identity
fuse hostNamed pipe or Unix socketNone today; session token planned
fuse mcp servestdio to parent MCP clientParent process spawns the server
One-shot fuse CLIIn-processShell user

Cache and index data written while serving live in .fuse/fuse.db at the repository root; see Operator guide and Caching Internals.

What This Page Does Not Cover

This page does not document DTO field shapes (the wire contract is pinned by host and extension contract tests in the repository), VS Code extension packaging, or MCP tool semantics. It does not describe directory-walk path confinement or symlink handling in collection; those are separate hardening items for filesystem access during fusion.

Next

See The Fusion Pipeline for what scope and index calls run internally, Operator guide for cache lifecycle and environment variables, and Keep Secrets Out for redaction limits on emitted output.

On this page