Security Model
ServerFS is designed around narrow capabilities and independent enforcement layers.
Core properties
Section titled “Core properties”- Read-only by default.
- Per-workdir mutation opt-in.
- No shell or generic command execution.
- No generic
write_file. - No recursive delete or force mode.
- Revision-guarded destructive operations.
- FD-based path traversal with symlink rejection.
- Built-in credential deny rules.
- Read/write/search/binary size limits.
- Structured audit logging without file contents.
- Read-only container root filesystem.
- Non-root container user, dropped capabilities, and no-new-privileges.
- Internal-only MCP networks with no published ports or Internet egress.
- Optional ChatGPT file ingress is isolated in a separate sidecar with no workdir mounts or OpenAI credentials.
File-ingress boundary
Section titled “File-ingress boundary”v0.5.0 keeps Internet egress out of the ServerFS MCP container. When explicitly enabled, serverfs-file-ingress receives a dedicated egress network and a separate internal network shared only with the MCP service. The tunnel is not attached to that ingress network.
The MCP-to-sidecar endpoint is fixed to the internal Compose service and the MCP client does not follow redirects. The sidecar accepts HTTPS on port 443 only. Host authorization is either an exact administrator-configured hostname or the explicit constrained OpenAI Azure Blob family measured from real ChatGPT fileParams (oaisdmntpr storage-account prefix, lowercase ASCII letters/digits only, Azure account-length limit, exact .blob.core.windows.net suffix). Generic host wildcards are rejected. After host authorization, the sidecar rejects any DNS answer that is not globally routable, pins the connection to the validated address while verifying TLS for the original hostname, revalidates every upstream redirect, and enforces independent byte and timeout ceilings. It is not a generic URL proxy.
Transport hardening
Section titled “Transport hardening”v0.4.0 introduced MCP Streamable HTTP DNS-rebinding protection; v0.5.0 retains that transport boundary unchanged.
The transport accepts only the fixed internal authority serverfs-mcp:8000, rejects unexpected or missing Host values, and rejects non-empty unapproved Origin values before MCP dispatch.
Agent boundary
Section titled “Agent boundary”Agent support is opt-in and lives behind a host-side Unix socket. The MCP container receives structured Agent capabilities, not shell access to the host.
Jev advisor boundary
Section titled “Jev advisor boundary”Jev is optional and runs only from the host Agent Bridge. It is not part of the MCP authorization path, runtime allowlist, writer lease, or native provider approval authority. A missing/failed Jev call removes advisory context only; it never grants additional capability.
The TypeSafe API key is rendered only into the user-owned Bridge config and is never passed to the MCP container. Approval Advisor sends a minimized, redacted approval state and applies an additional secret/token/password sanitizer before the external request. Identical approval advice may be cached only within the same task and never resolves the approval automatically.
See Jev Advisors for the complete advisory contract.
For the full threat model and implementation details, see the repository Security Model.