Skip to main content
Glama

agent-sandbox

我构建这个项目是为了让 AI 编码代理能够针对真实的 Kubernetes 集群运行真实的基础设施命令——而无需持有长期有效的凭据,也无法在无人监督的情况下破坏任何东西。

三个 MCP 工具。每次调用都在一个 gVisor 沙箱化的 Kubernetes Job 中运行,并附带一个由 Vault 为单次操作签发的短期、窄范围凭据。任何破坏性操作都会在人工审批门处停止。

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    │
        └──────────────────────┘

我为什么构建这个

我使用的一个 AI 工具曾针对生产基础设施提出过一项 Terraform 变更,该变更会强制替换一个在线资源。计划看起来平平无奇。失败模式并不是模型出错——而是没有任何东西介于一个看似合理的计划与破坏性的 apply 之间。

我将这个项目构建为缺失的那一层,以可工作的代码呈现:

  • 代理永远不会持有可复用的凭据

  • 一切都在无法伤害宿主的地方运行

  • 破坏性变更会停止并等待人工介入

  • 每个操作都有记录

make demo 重现了我遇到的确切场景。一行标签编辑会强制替换正在运行的 Deployment,而门禁会捕获它。

Related MCP server: Emisar

快速开始

需要 Docker、kindkubectlvaultterraform 和 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 是幂等的。它通过运行 make verify 结束,该命令 证明 隔离声明,而不是仅仅断言它们(见下文)。

将代理指向它

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

Cursor:将 examples/cursor_mcp.json 复制到 .cursor/mcp.json。然后让代理 "检查 demo-app 中的 pod 状态""规划 k8s-demo terraform"

三个工具

工具

风险

行为

k8s_get_pod_status(namespace)

立即运行。凭据范围限定为单个命名空间中的 get/list/watch pods

terraform_plan(working_dir)

立即运行。保存计划,以便后续 apply 执行 完全 经过审查的差异。

terraform_apply(working_dir, approval_id?)

没有 approval_id:计算计划,记录待处理的审批,不应用任何内容。有 approval_id:消耗该审批并应用已保存的计划。

四个组件

1. 沙箱化执行 — src/agent_sandbox/sandbox.py

每次工具调用一个一次性 Job。每个控制项都有其特定原因:

控制项

防止的

runtimeClassName: gvisor

系统调用命中 gVisor sentry,而非宿主内核

PSS restricted,由 API 服务器强制执行

root、权限提升、能力、可写 rootfs

automountServiceAccountToken: false

沙箱内任何环境集群身份

默认拒绝的 NetworkPolicy + API 服务器白名单

互联网出口、横向移动、元数据端点

resources.limitsactiveDeadlineSeconds

失控的 Job 耗尽节点资源或无限挂起

backoffLimit: 0

失败的破坏性操作被静默重试

凭据以 文件 形式挂载,绝不使用环境变量——环境变量会通过 kubectl describe/proc 和崩溃转储泄露。

2. 凭据代理 — 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
  • 代理永远不会自行选择范围。 范围由操作派生。

  • 默认拒绝。 没有映射范围的操作不会获得凭据。

  • 爆炸半径被强制执行。 请求除目标之外的任何命名空间都会被拒绝。

  • 令牌永远不会离开模块。 Credential.__repr__ 打印 token=<redacted>,因此即使是意外日志也无法泄露它。

我手动验证了这一点:pod-reader 令牌可以列出 demo-app 中的 pod,在 kube-system 中被 拒绝,在 secrets 上被 拒绝,并且在其租约被撤销的那一刻立即失效——不会留下任何 ServiceAccount。

3. 护栏 — policy/policy.yamlsrc/agent_sandbox/guardrails.py

默认拒绝:注册 MCP 工具并不足以使其可调用。 策略中不存在的工具会被拒绝,因此添加能力需要深思熟虑的风险层级决策。

审批针对明显的攻击进行了加固:

  • 一次性使用 — 在单个 SQLite 事务中消耗,因此两个并发的 apply 无法花费同一个审批

  • 参数绑定 — 绑定到确切工具 + 参数的哈希,因此针对 k8s-demo 的审批无法重放到 prod-cluster

  • 过期 — 默认 30 分钟

  • 带外 — 通过单独的 CLI 进程授予。没有 MCP 工具可以批准任何内容;代理没有代码路径来批准自己的请求。

4. MCP 服务器 — src/agent_sandbox/server.py

基于官方 Python SDK(mcp 2.0、MCPServer)构建。传输层刻意保持轻薄,本身不授予任何权限——那里的错误无法扩大代理的能力,因为策略和 API 服务器的 Pod Security 准入才是实际的控制点。

审计日志

每次调用都会向 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

凭据值在写入前会被递归清理;范围、租约 ID 和 TTL 会被保留。一个测试断言任何 JWT 形状的字符串永远不会到达日志。

已验证,而非假设

这个项目中有两件事很容易 声称 却悄悄没有,所以我没有凭信。make verify 针对实时集群测试两者:

== 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)

这在我构建时捕获了一个真实问题。 kind 的默认 CNI(kindnet)接受 NetworkPolicy 对象并静默忽略它们——我应用了默认拒绝的出口策略,但 pod 之间的流量仍然通过。沙箱看起来像是被锁定,却拥有完全的网络访问权限。我通过禁用 kindnet 并安装 Calico 来修复,Calico 会真正强制执行。参见 scripts/install-calico.sh

我在白名单 API 服务器时遇到了一个相关的陷阱:ClusterIP 不起作用,因为 kube-proxy 在 Calico 评估出口之前将流量 DNAT 到真实端点。症状是沙箱只是挂起,没有策略拒绝事件来解释。记录在 scripts/apply-sandbox-policy.sh 中。

诚实的局限性

  • gVisor 运行,但这仍然是 kind。 我在 kind 节点(Docker Desktop 的 Linux VM 中的一个容器)内安装了 runsc 并验证其处于活动状态。这是一个真正的 gVisor 沙箱,但不是生产加固的节点。

  • AWS/STS 路径是有条件的。 scripts/vault-setup.sh 仅在存在真实 AWS 凭据时才配置 Vault 的 AWS secrets 引擎;没有则跳过并说明。我不想为了演示看起来完整而伪造该路径。实时、可演示 的凭据路径是 Kubernetes 路径,它完全真实:动态 ServiceAccount、真实 RBAC、真实租约、真实撤销。

  • Vault 以开发模式运行 — 内存中,root 令牌 root,无封缄。适合本地项目,不适合我原样部署。

  • 破坏性信号检测是对计划输出进行字符串匹配。 它是为人类提供的 表面 辅助,而非安全边界——terraform_apply 已经是高风险层级,无论扫描发现什么都会被门禁。

  • 单节点集群,因此保存 Terraform 状态的 PVC 在单个节点上是 ReadWriteOnce

布局

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

测试

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