Skip to main content
Glama

agent-sandbox

Ich habe das gebaut, damit ein KI-Coding-Agent echte Infrastruktur-Befehle gegen einen echten Kubernetes-Cluster ausführen kann – ohne jemals ein dauerhaftes Zugangsdaten zu besitzen und ohne in der Lage zu sein, unbeaufsichtigt etwas zu zerstören.

Drei MCP-Tools. Jeder Aufruf läuft in einem gVisor-sandboxed Kubernetes-Job mit einer kurzlebigen, eng begrenzten Berechtigung, die Vault für genau diese einzelne Aktion ausstellt. Alles Destruktive stoppt an einem menschlichen Genehmigungs-Gate.

AI Agent (Claude Desktop / Cursor)
        │  MCP protocol (stdio)
        ▼
┌──────────────────────────────────────────┐
│  MCP Server            src/agent_sandbox │
│    3 tools -> guardrails -> broker ->    │
│    sandbox -> audit                      │
└───────┬──────────────────────┬───────────┘
        │                      │
        ▼                      ▼
┌────────────────┐   ┌──────────────────────────┐
│ Credential     │   │ Sandbox Runner           │
│ Broker (Vault) │   │ K8s Job + gVisor         │
│ 10-min leases  │   │ restricted PSS           │
│ per-action     │   │ default-deny NetworkPolicy│
│ scope          │   │ cpu/mem limits, deadline │
└────────────────┘   └──────────────────────────┘
        │                      │
        └──────────┬───────────┘
                   ▼
        ┌──────────────────────┐
        │ Guardrails + Approval│
        │ policy.yaml, SQLite, │
        │ agent-sandbox CLI    │
        └──────────────────────┘

Warum ich das gebaut habe

Ein KI-Tool, das ich benutzte, schlug einmal eine Terraform-Änderung an Produktionsinfrastruktur vor, die den Austausch einer laufenden Ressource erzwungen hätte. Der Plan sah routinemäßig aus. Der Fehlermodus war nicht, dass das Modell falsch lag – sondern dass nichts zwischen einem plausibel aussehenden Plan und einem destruktiven Apply stand.

Ich habe dieses Projekt als die fehlende Schicht gebaut, in funktionierendem Code:

  • der Agent hält nie eine Berechtigung, die er wiederverwenden könnte

  • alles läuft an einem Ort, an dem es dem Host nicht schaden kann

  • destruktive Änderungen stoppen und warten auf eine Person

  • jede Aktion ist dokumentiert

make demo reproduziert das genaue Szenario, auf das ich gestoßen bin. Eine einzeilige Label-Änderung erzwingt den Austausch eines laufenden Deployments, und das Gate fängt es ab.

Related MCP server: Emisar

Schnellstart

Erfordert Docker, kind, kubectl, vault, terraform und Python 3.11+.

brew install kind kubectl hashicorp/tap/vault terraform
make up      # ~5 minutes from cold: cluster, CNI, gVisor, Vault, image, verify
make demo    # the forces-replacement guardrail demo
make down    # tear it all down

make up ist idempotent. Es endet mit make verify, das die Isolationsbehauptungen beweist, statt sie nur zu behaupten (siehe unten).

Einen Agenten darauf ausrichten

cp examples/claude_desktop_config.json \
   ~/Library/Application\ Support/Claude/claude_desktop_config.json

Cursor: Kopiere examples/cursor_mcp.json nach .cursor/mcp.json. Dann frage den Agenten, "Pod-Status in demo-app zu prüfen" oder "das k8s-demo Terraform zu planen".

Die drei Tools

Tool

Risiko

Verhalten

k8s_get_pod_status(namespace)

niedrig

Läuft sofort. Berechtigung beschränkt auf get/list/watch pods in einem Namespace.

terraform_plan(working_dir)

niedrig

Läuft sofort. Speichert den Plan, sodass ein späteres Apply exakt den überprüften Diff ausführt.

terraform_apply(working_dir, approval_id?)

hoch

Ohne approval_id: berechnet den Plan, protokolliert eine ausstehende Genehmigung, wendet nichts an. Mit einer: verbraucht die Genehmigung und wendet den gespeicherten Plan an.

Die vier Komponenten

1. Sandbox-Ausführung – src/agent_sandbox/sandbox.py

Ein Wegwerf-Job pro Tool-Aufruf. Jede Kontrolle existiert aus einem bestimmten Grund:

Kontrolle

Verhindert

runtimeClassName: gvisor

Syscalls treffen den gVisor-Sentry, nicht den Host-Kernel

PSS restricted, vom API-Server erzwungen

root, Privilege Escalation, Capabilities, beschreibbares Rootfs

automountServiceAccountToken: false

Jede Umgebungs-Cluster-Identität innerhalb der Sandbox

Default-Deny-NetworkPolicy + API-Server-Allowlist

Internet-Egress, laterale Bewegung, Metadaten-Endpunkte

resources.limits, activeDeadlineSeconds

Ein außer Kontrolle geratener Job, der den Node aushungert oder ewig hängt

backoffLimit: 0

Ein fehlgeschlagener destruktiver Vorgang, der stillschweigend wiederholt wird

Die Berechtigung wird als Datei gemountet, nie als Umgebungsvariable – Umgebungsvariablen leaken durch kubectl describe, /proc und Crash-Dumps.

2. Berechtigungs-Broker – src/agent_sandbox/broker.py

cred = broker.issue_scoped_credential("k8s_get_pod_status")
# -> Vault mints a ServiceAccount + Role + RoleBinding, 10-minute lease
# -> revoked immediately after the Job finishes
  • Der Agent wählt nie seinen eigenen Umfang. Der Umfang wird aus der Aktion abgeleitet.

  • Standardmäßig verweigern. Eine Aktion ohne zugeordneten Umfang erhält keine Berechtigung.

  • Blast-Radius wird erzwungen. Das Anfordern eines anderen Namespace als des Ziels wird verweigert.

  • Das Token verlässt das Modul nie. Credential.__repr__ gibt token=<redacted> aus, sodass selbst ein versehentliches Log es nicht leaken kann.

Ich habe das von Hand verifiziert: Ein pod-reader-Token listet Pods in demo-app, wird in kube-system verweigert, wird bei Secrets verweigert und funktioniert nicht mehr, sobald sein Lease widerrufen wird – ohne ein ServiceAccount zurückzulassen.

3. Schutzmechanismen – policy/policy.yaml, src/agent_sandbox/guardrails.py

Standardmäßig verweigern: Das Registrieren eines MCP-Tools reicht nicht aus, um es aufrufbar zu machen. Ein Tool, das nicht in der Policy steht, wird verweigert. Das Hinzufügen von Fähigkeiten erfordert also eine bewusste Risiko-Einstufungs-Entscheidung.

Genehmigungen sind gegen die offensichtlichen Angriffe gehärtet:

  • Einmalig – in einer einzigen SQLite-Transaktion verbraucht, sodass zwei gleichzeitige Applies nicht dieselbe Genehmigung ausgeben können

  • Parametergebunden – an einen Hash des exakten Tools + Parameter gebunden, sodass eine Genehmigung für k8s-demo nicht gegen prod-cluster wiederverwendet werden kann

  • Ablaufend – standardmäßig 30 Minuten

  • Out-of-Band – über einen separaten CLI-Prozess gewährt. Es gibt kein MCP-Tool, um etwas zu genehmigen; der Agent hat keinen Codepfad, um seine eigene Anfrage zu genehmigen.

4. MCP-Server – src/agent_sandbox/server.py

Basiert auf dem offiziellen Python-SDK (mcp 2.0, MCPServer). Die Transportschicht ist bewusst dünn und gewährt selbst keine Autorität – ein Fehler dort kann nicht erweitern, was der Agent tun kann, weil die Policy und die Pod-Security-Zulassung des API-Servers die eigentlichen Kontrollen sind.

Audit-Log

Jeder Aufruf erzeugt eine korrelierte Ereignisspur in var/audit.jsonl:

tool.request -> guardrail.decision -> credential.issued -> sandbox.started
   -> sandbox.completed -> credential.revoked -> tool.result
make audit
./.venv/bin/agent-sandbox audit --request-id req-4239b8bb5459 --json

Berechtigungswerte werden vor dem Schreiben rekursiv bereinigt; Umfang, Lease-ID und TTL werden beibehalten. Ein Test stellt sicher, dass nie ein JWT-förmiger String ins Log gelangt.

Verifiziert, nicht angenommen

Zwei Dinge in diesem Projekt sind leicht zu behaupten und stillschweigend nicht zu haben, also habe ich sie nicht auf Treu und Glauben genommen. make verify testet beide gegen den Live-Cluster:

== 1. gVisor kernel check ==
     kernel reported: Linux version 4.19.0-gvisor
  PASS: sandbox runs on the gVisor sentry kernel
== 2. NetworkPolicy egress enforcement check ==
  PASS: baseline connectivity works (got PONG)
  PASS: default-deny egress enforced (traffic blocked)

Das hat ein echtes Problem gefangen, während ich es gebaut habe. kind's Standard-CNI (kindnet) akzeptiert NetworkPolicy-Objekte und ignoriert sie stillschweigend – ich habe eine Default-Deny-Egress-Policy angewendet und Pod-zu-Pod-Verkehr kam trotzdem durch. Die Sandbox hätte wie abgesichert ausgesehen, während sie vollen Netzwerkzugriff hatte. Ich habe es behoben, indem ich kindnet deaktiviert und Calico installiert habe, das wirklich durchsetzt. Siehe scripts/install-calico.sh.

Ich bin auf eine verwandte Falle gestoßen, als ich den API-Server auf die Allowlist setzte: Die ClusterIP funktioniert nicht, weil kube-proxy vor der Calico-Egress-Bewertung zum echten Endpunkt DNATet. Das Symptom war eine Sandbox, die einfach hing, ohne ein Policy-Denied-Ereignis, das es erklärt. Dokumentiert in scripts/apply-sandbox-policy.sh.

Ehrliche Einschränkungen

  • gVisor läuft, aber das ist immer noch kind. Ich habe runsc im kind-Node (ein Container in der Linux-VM von Docker Desktop) installiert und verifiziert, dass es aktiv ist. Das ist eine echte gVisor-Sandbox, kein produktionsgehärteter Node.

  • Der AWS/STS-Pfad ist bedingt. scripts/vault-setup.sh konfiguriert Vaults AWS-Secrets-Engine nur, wenn echte AWS-Zugangsdaten vorhanden sind; ohne sie wird es übersprungen und sagt das. Ich wollte diesen Pfad nicht faken, nur um die Demo vollständig aussehen zu lassen. Der live, demonstrierbare Berechtigungspfad ist der Kubernetes-Pfad, der vollständig real ist: dynamische ServiceAccounts, echtes RBAC, echte Leases, echte Widerrufe.

  • Vault läuft im Dev-Modus – im Speicher, Root-Token root, kein Seal. Für ein lokales Projekt in Ordnung, nicht etwas, das ich so deployen würde.

  • Die Erkennung destruktiver Signale ist String-Matching auf Plan-Ausgabe. Es ist eine Oberflächen-Hilfe für den Menschen, keine Sicherheitsgrenze – terraform_apply ist bereits hoch eingestuft und unabhängig davon, was der Scan findet, gegated.

  • Einzelner Node-Cluster, daher ist das PVC, das den Terraform-State hält, ReadWriteOnce auf einem Node.

Layout

cluster/      kind config, RuntimeClass, namespaces, RBAC, network policy
images/       sandbox runner image (terraform + kubectl, providers vendored)
policy/       guardrail policy: risk tiers and destructive signals
scripts/      up/down, gVisor + Calico install, verification, demo
src/          the package: broker, sandbox, guardrails, approvals, audit, MCP
terraform/    demo module managed by the agent
tests/        56 unit tests + a real-stdio MCP integration check

Testen

make test       # 56 unit tests, no cluster required
make test-mcp   # drives the server over real MCP stdio (needs the stack up)
make verify     # proves gVisor + NetworkPolicy enforcement on the live cluster
F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to securely perform privileged actions like creating GitHub issues by minting short-lived, single-purpose tokens on demand, with policy enforcement and audit logging.
    MIT
  • F
    license
    Not graded
    quality
    A
    maintenance
    Give AI agents Zero-Trust access to production infrastructure without the risks of granting them shell access. Actions are bounded by policy and an on-host runner.
    409
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI coding agents to evaluate actions against team-defined policies, record decisions, and obtain human approvals for potentially risky operations.
    165
    1
  • A
    license
    C
    quality
    B
    maintenance
    A policy-aware MCP server for GitHub and GitHub Actions that enables safe AI-assisted infrastructure workflows—inspecting repositories, preparing branches and pull requests, and constrained remote mutations behind explicit preview-bound approval tokens.
    18
    MIT

View all related MCP servers

Related MCP Connectors

  • Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.

  • Runtime permission, approval, and audit layer for AI agent tool execution.

  • The bridge from K2 agents through Wrangler to your master AI - safe, approval-gated Cloudflare ops.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mustafa12z/agent-mcp-sandbox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server