technical openshell security kernel ebpf

OpenShell: Środowisko bezpieczeństwa stojące za NemoClaw

Eric Ericsson

Eric Ericsson

@eericsson

March 21, 2026

11 min czytania

OpenShell: Środowisko bezpieczeństwa stojące za NemoClaw

OpenShell: Środowisko bezpieczeństwa stojące za NemoClaw

Jeśli NemoClaw to stos bezpieczeństwa, to OpenShell jest jego fundamentem. Opracowany przez zespół inżynierów bezpieczeństwa NVIDIA w ciągu ostatnich 18 miesięcy, OpenShell zapewnia izolację na poziomie jądra dla wykonywania agentów AI — gwarantując, że nawet w pełni skompromitowany agent nie może uzyskać dostępu do zasobów poza zdefiniowanymi granicami bezpieczeństwa.

Ten wpis to techniczne głębokie zanurzenie w architekturę OpenShell, mechanizmy izolacji i sposób egzekwowania polityk bezpieczeństwa przy minimalnych narzutach wydajnościowych.

Dlaczego izolacja na poziomie jądra?

Tradycyjne sandboxowanie aplikacji — kontenery, maszyny wirtualne, izolacja na poziomie procesów — zostało zaprojektowane dla oprogramowania, które zachowuje się przewidywalnie. Agenci AI są fundamentalnie inni. Generują własne plany wykonania w czasie pracy, wykonują wywołania narzędzi wchodzące w interakcję z zewnętrznymi systemami i mogą wykazywać nowe zachowania, których żaden zestaw testów nie przewidział.

Ta nieprzewidywalność wymaga modelu bezpieczeństwa działającego na najniższym możliwym poziomie: jądrze. OpenShell przechwytuje każde wywołanie systemowe procesu agenta, klasyfikuje je zgodnie z aktywną polityką bezpieczeństwa i podejmuje decyzję o dopuszczeniu lub odrzuceniu zanim wywołanie dotrze do jądra.

Agent Process
     │
     ▼
OpenShell eBPF Layer  ←── Policy Engine
     │
     ├── ALLOW → System Call → Kernel
     │
     ├── DENY → Error returned to agent
     │
     └── ESCALATE → Human approval queue

eBPF: Technologia stojąca za OpenShell

OpenShell jest zbudowany na eBPF (extended Berkeley Packet Filter) — technologii jądra Linux, która pozwala na uruchamianie niestandardowych programów w przestrzeni jądra bez modyfikacji samego jądra. Zespół NVIDIA napisał zestaw programów eBPF specjalnie zoptymalizowanych pod kątem obciążeń agentów AI:

Przechwytywacz wywołań systemowych

Przechwytywacz wywołań systemowych podłącza się do punktu śledzenia sys_enter i ocenia każde wywołanie systemowe zgodnie z aktywną polityką:

c
// 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;
}

Ochrona systemu plików

Ochrona systemu plików ogranicza, do jakich plików i katalogów agent może uzyskać dostęp. Działa na operacjach VFS (Virtual Filesystem), przechwytując wywołania open, read, write, unlink i rename:

yaml
# 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

Strażnik sieciowy

Strażnik sieciowy podłącza się do operacji na gniazdach, aby kontrolować dostęp sieciowy agenta na poziomie połączeń:

c
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
}

Architektura egzekwowania polityk

Polityki OpenShell są kompilowane do bajtkodu eBPF w celu uzyskania maksymalnej szybkości egzekwowania. Potok kompilacji działa następująco:

  1. 1.Pliki polityk YAML są tworzone przez zespoły bezpieczeństwa w czytelnym dla człowieka formacie
  2. 2.Kompilator polityk konwertuje YAML na reprezentację pośrednią (IR)
  3. 3.Walidator polityk Nemotron sprawdza IR pod kątem logicznej spójności i konfliktów
  4. 4.Kompilator eBPF generuje zweryfikowany bajtkod, który jest ładowany do jądra
  5. 5.Weryfikator środowiska uruchomieniowego zapewnia, że programy eBPF kończą się i są bezpieczne pamięciowo

Cały potok kompilacji wykonuje się w mniej niż 2 sekundy dla typowych zestawów polityk, a polityki mogą być przeładowywane na gorąco bez restartowania agenta.

bash
# 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

Procesy zatwierdzania przez operatora

Jedną z najbardziej wyróżniających cech OpenShell jest wbudowany system zatwierdzania przez operatora. Gdy agent próbuje wykonać akcję zaklasyfikowaną jako wysokiego ryzyka, OpenShell wstrzymuje wykonywanie agenta i kieruje żądanie zatwierdzenia do operatora-człowieka.

Jak działa zatwierdzanie

  1. 1.Agent próbuje wykonać wywołanie systemowe wysokiego ryzyka (np. zapis do chronionego pliku, połączenie z niezatwierdzonym punktem końcowym)
  2. 2.Program eBPF OpenShell wysyła SIGSTOP do procesu agenta
  3. 3.Generowane jest żądanie zatwierdzenia i wysyłane skonfigurowanym kanałem (Slack, Teams, PagerDuty, email)
  4. 4.Operator przegląda kontekst żądania i zatwierdza lub odrzuca
  5. 5.Jeśli zatwierdzone, OpenShell wysyła SIGCONT do wznowienia agenta; jeśli odrzucone, zwraca EPERM

Żądanie zatwierdzenia zawiera pełny kontekst:

json
{
  "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"
}

Timeout zatwierdzenia i domyślne akcje

Operatorzy mogą skonfigurować, co się dzieje po upłynięciu czasu zatwierdzenia:

yaml
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

Charakterystyka wydajności

OpenShell jest zaprojektowany dla obciążeń produkcyjnych, gdzie opóźnienie ma znaczenie. Oto zmierzone narzuty na DGX Spark:

OperacjaNarzut
Przechwycenie wywołania systemowego (dopuszczenie)8 mikrosekund
Przechwycenie wywołania systemowego (odrzucenie)12 mikrosekund
Sprawdzenie systemu plików15 mikrosekund
Sprawdzenie połączenia sieciowego20 mikrosekund
Przeładowanie polityki na gorąco< 500 milisekund
Pełny cykl zatwierdzenia (Slack)2-30 sekund (zależne od człowieka)

Dla porównania: typowe wywołanie inferencji LLM trwa 500-5000 ms, więc narzut OpenShell jest pomijalny w kontekście obciążeń agentów.

Porównanie z istniejącymi metodami izolacji

FunkcjaOpenShellDocker/OCIgVisorFirecracker
Poziom izolacjiJądro (eBPF)Przestrzeń nazwJądro w przestrzeni użytkownikamicroVM
Filtrowanie wywołań systemowychNa politykę, przeładowanie na gorącoStatyczny seccompPełne przechwyceniePełna izolacja
Polityka sieciowaNa agenta, warstwa L7iptablesiptablesiptables
Zatwierdzenie przez człowiekaWbudowaneBrakBrakBrak
Polityki świadome AITak (Nemotron)NieNieNie
Narzut~10 mikrosekund~5 mikrosekund~50 mikrosekund~100 ms uruchomienie
Przekierowanie GPUNatywneNVIDIA CTKOgraniczoneOgraniczone

Kluczowym wyróżnikiem OpenShell jest to, że został zaprojektowany od podstaw dla obciążeń agentów AI, z wbudowanym wsparciem dla polityk w języku naturalnym, procesów zatwierdzania przez człowieka i oceny polityk z akceleracją GPU.

Pierwsze kroki z OpenShell

OpenShell może być używany samodzielnie, bez reszty stosu NemoClaw:

bash
# 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 jest open source na licencji Apache 2.0 i jest dostępny pod adresem nvidia/openshell na GitHub. W następnym wpisie zbadamy rzeczywiste scenariusze wdrożeń korporacyjnych dla pełnego stosu NemoClaw.

Bądź na bieżąco

Otrzymuj powiadomienia o nowych wersjach NemoClaw, zaleceniach bezpieczeństwa i nowościach z ekosystemu. Żadnego spamu — wypisz się w dowolnej chwili.