Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8f7e2ff
feat(examples): add agent tool argv allowlist sandbox (#645)
cgflag Jul 21, 2026
64d0fe5
feat(examples): add thin Dockerfile for agent-tool-allowlist (#645)
cgflag Jul 21, 2026
19e549a
test(examples): add local allowlist unit tests (#645)
cgflag Jul 21, 2026
f817387
docs(examples): document Path B template and layer honesty (#645)
cgflag Jul 21, 2026
c6dd509
fix(examples): avoid remote Dockerfile frontend dependency (#645)
cgflag Jul 21, 2026
ca731d2
test(examples): exercise Windows path rejection branch (#645)
cgflag Jul 21, 2026
76ee7fa
feat(examples): add local verify gate and allowlist sync (#645)
cgflag Jul 21, 2026
b4b04d5
docs(examples): document verify_local and host DNS caveat (#645)
cgflag Jul 21, 2026
d237405
feat(examples): add sidecar allow path for host without DNS (#645)
cgflag Jul 21, 2026
f841f37
docs(examples): document host sidecar allow path (#645)
cgflag Jul 21, 2026
68d047a
docs(examples): trim allowlist README to Quick Start style (#645)
cgflag Jul 22, 2026
0541764
test(examples): assert deny path never calls Sandbox.create (#645)
cgflag Jul 22, 2026
0551642
feat(examples): stack Mode-1 airgap on allowlist allow path (#645)
cgflag Jul 22, 2026
b776fac
feat(examples): treat interpreter as explicit code-execution capabili…
cgflag Jul 22, 2026
e763e59
refactor(examples): DRY assert_allowlisted via is_allowlisted (#645)
cgflag Jul 22, 2026
af55c07
fix(examples): use resolved_path consistently in load_local_dotenv (#…
cgflag Jul 22, 2026
fa9b32b
chore(examples): tighten allowlist example hygiene from bot nits (#645)
cgflag Jul 22, 2026
ea18327
chore(examples): final allowlist hygiene nits (#645)
cgflag Jul 22, 2026
2802bc9
fix(examples): unify deny messages and AST-guard Sandbox.create (#645)
cgflag Jul 22, 2026
0348de6
docs(examples): avoid stale test names; note shlex path caveat (#645)
cgflag Jul 22, 2026
bb5732f
fix(examples): harden shlex denials and verify I/O checks (#645)
cgflag Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/guide/tutorials/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Hands-on examples demonstrating various Cube Sandbox use cases. Each example is
| [SWE-bench with mini-swe-agent](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/mini-rl-training) | Automate SWE-bench coding tasks in isolated sandboxes using cube-sandbox + mini-swe-agent, with multi-model support and RL training vision. |
| [OpenAI Agents SDK Integration](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/openai-agents-example) | Wire OpenAI Agents SDK's `E2BSandboxClient` to Cube Sandbox. Ships a minimal Shell Agent with Pause/Resume and a full SWE-bench Django debugging agent with streaming + tracing. |
| [OpenAI Agents + Code Interpreter](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/openai-agents-code-interpreter) | Data-analysis Agent running pandas / matplotlib inside a Cube Sandbox. Provides two variants: generic E2B write+exec and Jupyter-kernel Code Interpreter with cross-turn state and auto image capture. |
| [Agent Tool Allowlist Sandbox](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/agent-tool-allowlist-sandbox) | Host-side argv allowlist gate for agent tool commands: allowlisted tools run in a MicroVM with stdout/artifact readback; non-allowlisted commands fail fast without creating a sandbox. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: consider placing this entry near other agent-tooling examples

The "Agent Tool Allowlist Sandbox" is an agent-tooling example (alongside OpenClaw, OpenAI Agents SDK, OpenAI Agents + Code Interpreter). Appending it at the end of the table separates it from peers that users browsing agent integrations are most likely scanning. Consider inserting it after the "OpenAI Agents + Code Interpreter" row (or after "OpenAI Agents SDK Integration") to keep the agent-tooling cluster together. The same organizational note applies to docs/zh/guide/tutorials/examples.md.

| [cube-bench](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/cube-bench) | CLI benchmark tool written in Go that measures sandbox creation/deletion latency at configurable concurrency levels. Features a real-time TUI dashboard (Bubbletea/Lipgloss), percentile report (P50/P95/P99), and JSON export. |

::: tip
Expand Down
1 change: 1 addition & 0 deletions docs/zh/guide/tutorials/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
| [SWE-bench + mini-swe-agent](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/mini-rl-training) | 使用 cube-sandbox + mini-swe-agent 在隔离沙箱中自动化 SWE-bench 编码任务,支持多模型切换和 RL 训练愿景。 |
| [OpenAI Agents SDK 集成](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/openai-agents-example) | 将 OpenAI Agents SDK 的 `E2BSandboxClient` 对接 Cube Sandbox。包含最小 Shell Agent(含 Pause/Resume 演示)以及完整的 SWE-bench Django 调试 Agent(流式输出 + 全链路追踪)。 |
| [OpenAI Agents + Code Interpreter](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/openai-agents-code-interpreter) | 在 Cube Sandbox 中运行使用 pandas / matplotlib 的数据分析 Agent,提供通用 E2B(write+exec)与 Jupyter kernel(状态跨轮保留、图像自动捕获)两种执行形态。 |
| [Agent 工具白名单沙箱](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/agent-tool-allowlist-sandbox) | 宿主机侧 Agent 工具 argv 白名单门控:白名单工具在 MicroVM 内执行并回传 stdout/小工件;非白名单命令快速失败且不创建沙箱。 |
| [cube-bench](https://github.com/tencentcloud/CubeSandbox/tree/master/examples/cube-bench) | Go 编写的 CLI 压测工具,可在可配置并发数下测量沙箱创建/删除延迟。具备实时 TUI 看板(Bubbletea/Lipgloss)、分位数报告(P50/P95/P99)和 JSON 导出功能。 |
| [Volume 插件(COS)](https://github.com/TencentCloud/CubeSandbox/blob/master/examples/volume/cos/README.zh.md) | binary / rpc 两种类型的腾讯云 COS Volume 插件示例,含 Python SDK 验证脚本。框架文档见 [Volume 插件开发指南](../volume-plugin.md)。 |

Expand Down
21 changes: 21 additions & 0 deletions examples/agent-tool-allowlist-sandbox/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Required: Cube API server address (dev-env host forward defaults to :13000)
export E2B_API_URL="http://127.0.0.1:13000"

# Required: any non-empty value satisfies the SDK check
export E2B_API_KEY="e2b_000000"

# Required: template ID from cubemastercli tpl create-from-image
export CUBE_TEMPLATE_ID="<your-template-id>"

# --- Host-side allow path without wildcard DNS (run_allowlisted_sidecar.py) ---
# See docs/guide/connect-existing-cluster.md Option D + examples/e2b-dev-sidecar
# export CUBE_REMOTE_PROXY_BASE="https://127.0.0.1:11443"
# export CUBE_REMOTE_PROXY_VERIFY_SSL="false"
# export CUBE_REMOTE_SANDBOX_DOMAIN="cube.app"

# Optional: only needed when using Cube's built-in mkcert certificate
# export SSL_CERT_FILE="/root/.local/share/mkcert/rootCA.pem"

# Optional: verify_local.py knobs
# export ALLOWLIST_IMAGE_TAG="agent-tool-allowlist-sandbox:night-verified"
# export ALLOWLIST_USE_SIDECAR="1" # use run_allowlisted_sidecar.py when env is set
4 changes: 4 additions & 0 deletions examples/agent-tool-allowlist-sandbox/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.venv/
__pycache__/
*.py[cod]
.env
49 changes: 49 additions & 0 deletions examples/agent-tool-allowlist-sandbox/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Thin wrapper on the official Cube Sandbox code image.
# Purpose: give this example a buildable template path for #645, without
# adding a new language/runtime stack.
#
# Markers baked into the image:
# - ENV TOOL_ALLOWLIST_SANDBOX=1
# - /etc/cube-sandbox/tool-allowlist.txt (demo allowlist file)
#
# The allowlist file body must stay aligned with allowlist.DEFAULT_ALLOWED_BINARIES.
# Check with: python verify_local.py
#
# Build (from this directory):
# docker build -t agent-tool-allowlist-sandbox:latest .
#
# Register as a Cube template (same flags as code-sandbox-quickstart):
# cubemastercli tpl create-from-image \
# --image <your-registry>/agent-tool-allowlist-sandbox:latest \
# --writable-layer-size 1G \
# --expose-port 49999 \
# --expose-port 49983 \
# --probe 49999
#
# Base image registries (same as examples/code-sandbox-quickstart/README.md):
# CN: cube-sandbox-cn.tencentcloudcr.com/cube-sandbox/sandbox-code:latest
# INT: cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest

ARG SANDBOX_CODE_IMAGE=cube-sandbox-cn.tencentcloudcr.com/cube-sandbox/sandbox-code:latest
FROM ${SANDBOX_CODE_IMAGE}

ENV TOOL_ALLOWLIST_SANDBOX=1

# Demo allowlist file inside the guest (informational; host-side gate remains
# the enforcement point for this example — see README Limitations).
# Names are sorted to match allowlist_sync.allowlist_file_body().
RUN mkdir -p /etc/cube-sandbox \
&& printf '%s\n' \
'# Agent tool argv allowlist (demo; host gate is authoritative)' \
'cat' \
'echo' \
'head' \
'ls' \
'pwd' \
'sha256sum' \
'uname' \
'wc' \
> /etc/cube-sandbox/tool-allowlist.txt

# Ports inherited from sandbox-code / quickstart convention.
EXPOSE 49999 49983
146 changes: 146 additions & 0 deletions examples/agent-tool-allowlist-sandbox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Agent Tool Allowlist Sandbox

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README references specific test method names

If these tests are renamed, the README becomes stale. Consider describing the concept rather than exact method identifiers.


[中文文档](README_zh.md)

Demonstrates argv allowlisting for agent tools **before** `Sandbox.create`:
allowlisted binaries run in a Cube Sandbox MicroVM; others fail on the host
(no sandbox on the deny path).

The gate is host-side (`assert_allowlisted`). It is not egress CIDR policy or
guest kernel enforcement.

**Use when:** the host may only forward a fixed tool set (`echo` / `ls` /
`cat`, …) and must reject shells / network tools early. Interpreters are an
explicit capability (`enable_code_execution=True`), not part of the default set.

**Not for:** full agent frameworks, or replacing
[`network-policy`](../network-policy).

## 1. Prerequisites

- A running Cube Sandbox deployment ([dev environment](../../docs/guide/dev-environment.md))
- Python 3.8+
- Docker only if you use Path B

```bash
pip install -r requirements.txt
```

## 2. Quick Start

### Step 1 — Create a template (Recommended)

```bash
cubemastercli tpl create-from-image \
--image cube-sandbox-cn.tencentcloudcr.com/cube-sandbox/sandbox-code:latest \
--writable-layer-size 1G \
--expose-port 49999 \
--expose-port 49983 \
--probe 49999
```

Note the printed `template_id`. Outside CN, use
`cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest`.

| Item | Suggestion |
|------|------------|
| Writable layer | `1G` |
| Ports | `49999`, `49983`; `--probe 49999` |

### Step 2 — Configure environment

```bash
cp .env.example .env
# set E2B_API_URL (e.g. http://127.0.0.1:13000) and CUBE_TEMPLATE_ID
```

### Step 3 — Run

```bash
python verify_local.py # unit + deny; no sandbox
python run_allowlisted.py # allow (needs *.cube.app DNS or run in dev VM)
python run_denied.py # deny on host; no sandbox
```

Allow (host gate passes, then create with `allow_internet_access=False` —
[`network-policy`](../network-policy) Mode 1 airgap; argv allow ≠ network):

```text
egress: allow_internet_access=False (airgap; argv gate != network)
agent-tool-allowlist-ok
artifact: artifact-ok
```

Deny:

```text
denied_as_expected: command not on tool allowlist: 'bash' ...
```

Evidence that deny never calls `Sandbox.create`: see the unit tests in
`test_allowlist.py` that cover host-gate-before-create ordering and that
`run_denied.py` has no `Sandbox.create` call (also covered by `verify_local.py`).

On a host without `*.cube.app` DNS, use `python run_allowlisted_sidecar.py`
instead of `run_allowlisted.py` (set proxy vars in `.env.example`; see
[`e2b-dev-sidecar`](../e2b-dev-sidecar)). Optional `verify_local` knobs:
`ALLOWLIST_IMAGE_TAG`, `ALLOWLIST_USE_SIDECAR` (see `.env.example`).

## 3. Path B (optional) — build this example image

```bash
docker build -t agent-tool-allowlist-sandbox:latest .
# optional: --build-arg SANDBOX_CODE_IMAGE=.../sandbox-code:latest

cubemastercli tpl create-from-image \
--image agent-tool-allowlist-sandbox:latest \
--writable-layer-size 1G \
--expose-port 49999 \
--expose-port 49983 \
--probe 49999
```

If CubeMaster cannot see a local tag, retag/push to a reachable registry first.

## 4. Default allowlist

`allowlist.py` (`DEFAULT_ALLOWED_BINARIES`): `echo`, `uname`, `pwd`, `ls`,
`cat`, `head`, `wc`, `sha256sum`. Path-style binaries and shells such as
`bash` / `curl` are rejected. `python3` lives in `CODE_EXECUTION_BINARIES` and
is only added when `enable_code_execution=True`.

## 5. Limitations

- This demo is **capability-style tool gating** on the first argv token — not
full parameter policy. Combining small tools / redirects is out of scope.
- Default policy **denies interpreter execution**. Enabling `python3` grants
arbitrary code execution inside the guest, not "one more binary".
Passing a custom `allowed_binaries` that includes `python3` also grants that
capability without `enable_code_execution=True`.
- Host-side gate only — callers that skip `assert_allowlisted` can still send
any command to the API. MicroVM isolation ≠ guest capability control.
- Mode 1 airgap blocks egress; it does **not** stop local misuse in the guest.
Network tools stay off the default argv list; use [`network-policy`](../network-policy)
for CIDR policy.
- In-image `/etc/cube-sandbox/tool-allowlist.txt` (Path B) is informational;
the host gate is authoritative for this demo. Production should set
capabilities explicitly (do not casually `| CODE_EXECUTION_BINARIES`).

## 6. Directory

```text
agent-tool-allowlist-sandbox/
├── README.md
├── README_zh.md
├── Dockerfile
├── allowlist.py
├── allowlist_sync.py
├── verify_local.py
├── run_allowlisted.py
├── run_allowlisted_sidecar.py
├── run_denied.py
├── test_allowlist.py
├── env_utils.py
├── requirements.txt
└── .env.example
```
139 changes: 139 additions & 0 deletions examples/agent-tool-allowlist-sandbox/README_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Agent 工具白名单沙箱

[English](README.md)

演示在 `Sandbox.create` **之前**对 Agent 工具做 argv 白名单:
白名单内命令在 Cube Sandbox MicroVM 中执行;非白名单在宿主机失败(拒绝路径不建沙箱)。

门控在宿主机(`assert_allowlisted`),不能替代出口 CIDR 或 guest 内核强制。

**适用:** 调用方只允许转发固定工具集(`echo` / `ls` / `cat` 等),并尽早拒绝
shell / 网络类工具。解释器是显式能力(`enable_code_execution=True`),不在默认集。

**不适用:** 完整 Agent 框架,或替代 [`network-policy`](../network-policy)。

## 1. 前置条件

- 已部署的 Cube Sandbox([开发环境](../../docs/zh/guide/dev-environment.md))
- Python 3.8+
- 仅 Path B 需要 Docker

```bash
pip install -r requirements.txt
```

## 2. Quick Start

### Step 1 — 创建模板(推荐)

```bash
cubemastercli tpl create-from-image \
--image cube-sandbox-cn.tencentcloudcr.com/cube-sandbox/sandbox-code:latest \
--writable-layer-size 1G \
--expose-port 49999 \
--expose-port 49983 \
--probe 49999
```

记下 `template_id`。海外可用
`cube-sandbox-int.tencentcloudcr.com/cube-sandbox/sandbox-code:latest`。

| 项 | 建议 |
|----|------|
| 可写层 | `1G` |
| 端口 | `49999`、`49983`;`--probe 49999` |

### Step 2 — 配置环境

```bash
cp .env.example .env
# 填写 E2B_API_URL(如 http://127.0.0.1:13000)与 CUBE_TEMPLATE_ID
```

### Step 3 — 运行

```bash
python verify_local.py # 单测 + 拒绝;不需沙箱
python run_allowlisted.py # 放行(需 *.cube.app DNS 或在开发虚机内)
python run_denied.py # 宿主机拒绝;不建沙箱
```

放行(宿主机门控通过后,`Sandbox.create` 带
`allow_internet_access=False`——[`network-policy`](../network-policy) Mode 1
断网;argv 放行 ≠ 网络通):

```text
egress: allow_internet_access=False (airgap; argv gate != network)
agent-tool-allowlist-ok
artifact: artifact-ok
```

拒绝:

```text
denied_as_expected: command not on tool allowlist: 'bash' ...
```

拒绝路径零 `Sandbox.create` 的证据:见 `test_allowlist.py` 中覆盖
「门控先于 create」以及「`run_denied.py` 无 `Sandbox.create` 调用」的用例
(`verify_local.py` 会跑到)。

宿主机无 `*.cube.app` DNS 时,用 `python run_allowlisted_sidecar.py` 替代
`run_allowlisted.py`(代理变量见 `.env.example`;另见
[`e2b-dev-sidecar`](../e2b-dev-sidecar))。`verify_local` 可选环境变量:
`ALLOWLIST_IMAGE_TAG`、`ALLOWLIST_USE_SIDECAR`(见 `.env.example`)。

## 3. Path B(可选)— 构建本示例镜像

```bash
docker build -t agent-tool-allowlist-sandbox:latest .
# 可选: --build-arg SANDBOX_CODE_IMAGE=.../sandbox-code:latest

cubemastercli tpl create-from-image \
--image agent-tool-allowlist-sandbox:latest \
--writable-layer-size 1G \
--expose-port 49999 \
--expose-port 49983 \
--probe 49999
```

若 CubeMaster 看不到本地 tag,先打标签推到可拉取的仓库。

## 4. 默认白名单

`allowlist.py`(`DEFAULT_ALLOWED_BINARIES`):`echo`、`uname`、`pwd`、`ls`、
`cat`、`head`、`wc`、`sha256sum`。路径形式二进制以及 `bash` / `curl` 等会被拒绝。
`python3` 在 `CODE_EXECUTION_BINARIES` 中,仅当 `enable_code_execution=True` 时并入。

## 5. 限制

- 本示例是基于**首个 argv token** 的能力式工具门控,不是完整参数策略;小工具组合 /
重定向等不在范围内。
- 默认**拒绝解释器**。打开 `python3` 等于授予 guest 内任意代码执行,不是「多一个二进制」。
若自定义 `allowed_binaries` 直接包含 `python3`,即使未设 `enable_code_execution=True`
也会获得同等能力。
- 仅宿主机门控——跳过 `assert_allowlisted` 仍可向 API 发任意命令。MicroVM 隔离 ≠
guest 内能力控制。
- Mode 1 断网只挡出站,**不**防 guest 本地滥用。网络类工具不在默认 argv 名单;CIDR
见 [`network-policy`](../network-policy)。
- Path B 的 `/etc/cube-sandbox/tool-allowlist.txt` 仅为信息标记;生产应显式配置能力,
勿随意 `| CODE_EXECUTION_BINARIES`。

## 6. 目录结构

```text
agent-tool-allowlist-sandbox/
├── README.md
├── README_zh.md
├── Dockerfile
├── allowlist.py
├── allowlist_sync.py
├── verify_local.py
├── run_allowlisted.py
├── run_allowlisted_sidecar.py
├── run_denied.py
├── test_allowlist.py
├── env_utils.py
├── requirements.txt
└── .env.example
```
Loading
Loading