OpenShell: El Entorno de Ejecución de Seguridad Detrás de NemoClaw
Si NemoClaw es el stack de seguridad, OpenShell es su base. Desarrollado por el equipo de ingeniería de seguridad de NVIDIA durante los últimos 18 meses, OpenShell proporciona sandboxing a nivel de kernel para la ejecución de agentes de IA — asegurando que incluso un agente completamente comprometido no pueda acceder a recursos fuera de su límite de seguridad definido.
Este artículo es una inmersión técnica profunda en la arquitectura de OpenShell, sus mecanismos de aislamiento y cómo aplica las políticas de seguridad con una sobrecarga mínima de rendimiento.
¿Por Qué Aislamiento a Nivel de Kernel?
El sandboxing tradicional de aplicaciones — contenedores, VMs, aislamiento a nivel de proceso — fue diseñado para software que se comporta de manera predecible. Los agentes de IA son fundamentalmente diferentes. Generan sus propios planes de ejecución en tiempo real, realizan llamadas a herramientas que interactúan con sistemas externos y pueden producir comportamientos novedosos que ningún conjunto de pruebas anticipó.
Esta imprevisibilidad exige un modelo de seguridad que opere al nivel más bajo posible: el kernel. OpenShell intercepta cada llamada al sistema que realiza un proceso de agente, la clasifica según la política de seguridad activa y toma una decisión de permitir/denegar antes de que la llamada llegue al kernel.
Agent Process
│
▼
OpenShell eBPF Layer ←── Policy Engine
│
├── ALLOW → System Call → Kernel
│
├── DENY → Error returned to agent
│
└── ESCALATE → Human approval queue
eBPF: La Tecnología Detrás de OpenShell
OpenShell está construido sobre eBPF (extended Berkeley Packet Filter), una tecnología del kernel de Linux que permite ejecutar programas personalizados en el espacio del kernel sin modificar el propio kernel. El equipo de NVIDIA escribió un conjunto de programas eBPF específicamente optimizados para cargas de trabajo de agentes de IA:
Interceptor de Llamadas al Sistema
El interceptor de llamadas al sistema se conecta al tracepoint sys_enter y evalúa cada llamada al sistema contra la política activa:
// Simplified OpenShell eBPF syscall interceptor
SEC("tracepoint/raw_syscalls/sys_enter")
int openshell_syscall_enter(struct trace_event_raw_sys_enter *ctx) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
struct sandbox_policy *policy = bpf_map_lookup_elem(&sandbox_policies, &pid);
if (!policy)
return 0; // Not a sandboxed process
long syscall_nr = ctx->id;
int decision = evaluate_policy(policy, syscall_nr, ctx->args);
if (decision == DENY) {
// Send event to userspace audit log
emit_security_event(pid, syscall_nr, DENY);
// Override return value to -EPERM
bpf_override_return(ctx, -EPERM);
} else if (decision == ESCALATE) {
// Pause the process and notify approval queue
emit_approval_request(pid, syscall_nr, ctx->args);
send_signal(pid, SIGSTOP);
}
return 0;
}
Guardián del Sistema de Archivos
El guardián del sistema de archivos restringe qué archivos y directorios puede acceder un agente. Opera sobre operaciones VFS (Sistema de Archivos Virtual), interceptando llamadas open, read, write, unlink y rename:
# Filesystem policy for a customer support agent
filesystem:
# Agent can read its own configuration
- path: "/etc/nemoclaw/agent.yaml"
permissions: [read]
# Agent can read/write to its workspace
- path: "/var/nemoclaw/workspace/**"
permissions: [read, write, create]
# Agent can read shared data
- path: "/var/nemoclaw/shared/**"
permissions: [read]
# Everything else is denied by default
defaultAction: deny
Centinela de Red
El centinela de red se engancha a las operaciones de socket para controlar el acceso a la red del agente a nivel de conexión:
SEC("cgroup/connect4")
int openshell_connect4(struct bpf_sock_addr *ctx) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
struct network_policy *policy = bpf_map_lookup_elem(&net_policies, &pid);
if (!policy)
return 1; // Allow non-sandboxed processes
__be32 dst_ip = ctx->user_ip4;
__be16 dst_port = ctx->user_port;
if (!is_allowed_destination(policy, dst_ip, dst_port)) {
emit_security_event(pid, NETWORK_BLOCKED, dst_ip, dst_port);
return 0; // Block connection
}
return 1; // Allow connection
}
Arquitectura de Aplicación de Políticas
Las políticas de OpenShell se compilan en bytecode eBPF para la máxima velocidad de aplicación. El proceso de compilación funciona de la siguiente manera:
- 1.Los archivos de política YAML son escritos por los equipos de seguridad en un formato legible para humanos
- 2.El compilador de políticas convierte el YAML a una representación intermedia (IR)
- 3.El validador de políticas Nemotron verifica la IR en busca de consistencia lógica y conflictos
- 4.El compilador eBPF genera bytecode verificado que se carga en el kernel
- 5.El verificador en tiempo de ejecución asegura que los programas eBPF terminen y sean seguros en memoria
Todo el proceso de compilación se ejecuta en menos de 2 segundos para conjuntos de políticas típicos, y las políticas pueden recargarse en caliente sin reiniciar el agente.
# Compile and load a policy
nemoclaw policy compile policies/customer-support.yaml
nemoclaw policy load customer-support
# Hot-reload a modified policy (no agent restart required)
nemoclaw policy reload customer-support
# Verify policy is active
nemoclaw policy status
# Output:
# POLICY STATUS LOADED AT RULES
# customer-support active 2026-03-19 14:30:01 47
# network-default active 2026-03-19 14:30:01 12
# filesystem-strict active 2026-03-19 14:30:01 23
Flujos de Aprobación del Operador
Una de las características más distintivas de OpenShell es su sistema de aprobación del operador integrado. Cuando un agente intenta una acción clasificada como de alto riesgo, OpenShell pausa la ejecución del agente y enruta la solicitud de aprobación a un operador humano.
Cómo Funciona la Aprobación
- 1.El agente intenta una llamada al sistema de alto riesgo (p. ej., escribir en un archivo protegido, conectarse a un endpoint no aprobado)
- 2.El programa eBPF de OpenShell envía SIGSTOP al proceso del agente
- 3.Se genera una solicitud de aprobación y se envía a través del canal configurado (Slack, Teams, PagerDuty, correo electrónico)
- 4.El operador revisa el contexto de la solicitud y aprueba o deniega
- 5.Si se aprueba, OpenShell envía SIGCONT para reanudar el agente; si se deniega, devuelve EPERM
La solicitud de aprobación incluye el contexto completo:
{
"request_id": "apr-2026031914-00042",
"agent": "customer-support-agent-01",
"action": "email.send",
"target": "[email protected]",
"context": {
"ticket_id": "TKT-12345",
"customer_name": "[REDACTED]",
"reason": "Agent wants to send a follow-up email to the customer regarding their refund request",
"email_preview": "Dear Customer, your refund of $250 has been processed..."
},
"risk_level": "medium",
"policy_rule": "external-communication-requires-approval",
"timestamp": "2026-03-19T14:30:42Z"
}
Tiempo de Espera y Acciones Predeterminadas de Aprobación
Los operadores pueden configurar qué sucede cuando una aprobación expira:
approvalConfig:
timeout: 15m
onTimeout: deny # deny | allow | escalate
onEscalate:
target: security-team
channel: pagerduty
maxPendingApprovals: 10 # Queue limit per agent
autoApprove:
# Automatically approve if the same action was approved
# 3 times in the past 24 hours for this agent
repeatThreshold: 3
repeatWindow: 24h
Características de Rendimiento
OpenShell está diseñado para cargas de trabajo en producción donde la latencia importa. Estas son las sobrecargas medidas en un DGX Spark:
| Operación | Sobrecarga |
|---|---|
| Interceptación de llamada al sistema (permitir) | 8 microsegundos |
| Interceptación de llamada al sistema (denegar) | 12 microsegundos |
| Verificación del sistema de archivos | 15 microsegundos |
| Verificación de conexión de red | 20 microsegundos |
| Recarga de política en caliente | < 500 milisegundos |
| Ida y vuelta de aprobación (Slack) | 2-30 segundos (depende del humano) |
A modo de comparación, una llamada típica de inferencia LLM toma entre 500ms y 5000ms, por lo que la sobrecarga de OpenShell es despreciable en el contexto de cargas de trabajo de agentes.
Comparación con Sandboxing Existente
| Característica | OpenShell | Docker/OCI | gVisor | Firecracker |
|---|---|---|---|---|
| Nivel de aislamiento | Kernel (eBPF) | Namespace | User-space kernel | microVM |
| Filtrado de llamadas al sistema | Por política, recarga en caliente | seccomp estático | Interposición completa | Aislamiento completo |
| Política de red | Por agente, consciente de L7 | iptables | iptables | iptables |
| Aprobación humana | Integrada | Ninguna | Ninguna | Ninguna |
| Políticas conscientes de IA | Sí (Nemotron) | No | No | No |
| Sobrecarga | ~10 microsegundos | ~5 microsegundos | ~50 microsegundos | ~100ms inicio |
| Passthrough de GPU | Nativo | NVIDIA CTK | Limitado | Limitado |
El diferenciador clave de OpenShell es que fue diseñado desde cero para cargas de trabajo de agentes de IA, con soporte integrado para políticas en lenguaje natural, flujos de aprobación humana y evaluación de políticas acelerada por GPU.
Primeros Pasos con OpenShell
OpenShell puede usarse de forma independiente, sin el resto del stack de NemoClaw:
# Install OpenShell standalone
curl -fsSL https://github.com/NVIDIA/OpenShell | bash
# Create a minimal sandbox policy
cat > my-policy.yaml << 'EOF'
apiVersion: openshell.nvidia.com/v1
kind: SandboxPolicy
metadata:
name: my-first-sandbox
spec:
isolation:
network: restricted
filesystem: workspace-only
syscalls: minimal
EOF
# Run any process inside the sandbox
openshell run --policy my-policy.yaml -- python my_agent.py
OpenShell es de código abierto bajo Apache 2.0 y está disponible en nvidia/openshell en GitHub. En el próximo artículo, exploraremos escenarios reales de despliegue empresarial para el stack completo de NemoClaw.