Least privilege for credentials is necessary, but incomplete. If the MCP process can read arbitrary files, open arbitrary sockets, or escape to the host, a bug or a poisoned dependency still wins. Sandbox isolation is how you make "compromise the server" mean "compromise a small box," not "compromise the laptop or cluster."
This article covers practical permission boundaries for MCP servers: process identity, filesystem posture, network egress, and stronger isolation tiers.
What you are isolating
An MCP server typically needs:
- Read access to its own code and config (not the host home directory).
- Outbound access to a small set of APIs or databases.
- Maybe a writable temp directory for short-lived artifacts.
- No inbound ports except the MCP transport you intend (stdio, or a bound local/remote HTTP port).
Everything else should be denied by default.
Process boundaries
Run as a dedicated non-root user. Drop Linux capabilities (CAP_NET_ADMIN, CAP_SYS_ADMIN, and friends). Enable a seccomp profile that blocks rare syscalls. On Kubernetes, set runAsNonRoot, readOnlyRootFilesystem, and drop ALL capabilities, then add back only what you prove you need.
Do not mount the Docker socket, host PID namespace, or host network into the MCP container. Those shortcuts turn a sandbox into a root shell.
Filesystem lockdown
- Read-only root filesystem. Write only to an explicit
/tmpor volume with size quotas. - No host home mounts. Avoid bind-mounting
$HOME, SSH keys, cloud credential files, or your source monorepo "for convenience." - Narrow data mounts. If a tool must read a docs folder, mount that folder read-only, nothing else.
- Secret injection at runtime. Prefer environment variables from a secret store or a mounted tmpfs with tight permissions—not secrets baked into the image.
If you expose a "read file" tool, implement it inside the app with a hard root directory and path canonicalization checks. Do not shell out to cat on user-controlled paths.
Network lockdown
Default-deny egress:
- Allow DNS and HTTPS only to named hosts (your IdP, one API, one database proxy).
- Block link-local and cloud metadata endpoints (
169.254.169.254and equivalents) so a process cannot steal instance roles. - Prefer private networking / VNet integration over public internet when calling internal APIs.
- For stdio-based local MCP servers, still restrict what child processes can open; "local" does not mean "safe."
Ingress should be loopback or a private listener behind your agent host, with authentication on every remote transport.
Isolation tiers
|| Level | What you get | Typical use |
|| --- | --- | --- |
|| Process user + chroot | Mild separation | Dev only |
|| Container + seccomp + non-root | Good default | Most team MCP servers |
|| gVisor / Firecracker / micro-VM | Stronger kernel boundary | Multi-tenant or untrusted tools |
|| Separate cloud account + network ACL | Organizational blast-radius limit | Production agents with secrets |
Move up a tier when tools execute untrusted code, fetch arbitrary URLs, or run in a multi-tenant product.
Pair sandboxing with application controls
Sandboxing limits damage; it does not replace:
- Allowlisted tools and argument validation.
- Human approval for writes and sends.
- Short-lived, audience-bound tokens (see the OAuth article in this series).
- Supply-chain pinning so you are not routinely running strangers'
postinstallscripts.
Defense in depth means a failed prompt injection or a leaked dependency still hits a wall at the filesystem and the firewall.
Quick checklist
- Non-root, capabilities dropped, seccomp on.
- Read-only root FS; small writable tmp only.
- No Docker socket, no host mounts of secrets or home.
- Egress allowlist; metadata endpoints blocked.
- Stronger isolation (gVisor/VM) for untrusted or multi-tenant workloads.
- Image is scanned and immutable; no runtime package installs.
Assume the MCP process will eventually run hostile code. Build the box so that day is an incident you contain, not a breach of everything the host can touch.
Related reading
- Securing MCP Server Database Connections: Direct, API, and Beyond: combine sandbox isolation with least-privilege database roles and API layers so a breakout still cannot see or change more data than intended.
About the author
I write about Applied AI, MCP, Azure AI Search, and RAG. Follow me on Dev.to and Hashnode for more.





