news 2026/10/10 2:10:29

AIO Sandbox 安全加固指南:JWT 鉴权、短时票据与网络边界实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AIO Sandbox 安全加固指南:JWT 鉴权、短时票据与网络边界实践
  • AI Agent
  • 后端
  • MCP 服务
  • 浏览器控制
  • Agent 评测

【免费下载链接】sandbox

All-in-One Sandbox for AI Agents that combines Browser, Shell, File, MCP and VSCode Server in a single Docker container.

项目地址:https://gitcode.com/gh_mirrors/sandbox103/sandbox
点击查看免费下载

导读

本文聚焦 AIO Sandbox(All-in-One Sandbox for AI Agents)在本地可信环境之外部署时的安全加固方案。默认情况下,沙盒面向可信本地开发使用;当需要暴露给网络或其他服务时,必须开启鉴权并收紧访问边界。读完本文,你将掌握:用JWT_PUBLIC_KEY启用 Bearer token 校验的完整流程、短时票据的换取与使用方式、反向代理与网络边界的最小暴露策略,以及密钥处理的最佳实践。

安全模型总览:默认可信,暴露需加固

AIO Sandbox 把浏览器、Shell、文件、MCP 与 VSCode Server 集成在同一个 Docker 容器中,其核心 API(如/v1/sandbox、/v1/shell/exec、/v1/file/read)能力非常强。默认情况下,沙盒面向可信本地开发使用,此时无需额外鉴权;但一旦要暴露给网络或其他服务,就必须补齐三个层面:

  1. 身份鉴权:启用 JWT Bearer token 校验或共享 token,确保只有持有合法凭证的调用方可以访问 API;
  2. 访问边界:端口绑定、反向代理、IP/网络/服务身份限制,缩小暴露面;
  3. 凭据管理:密钥的注入方式与生命周期控制,避免长期密钥进入镜像或生成文件。

对应环境变量的完整说明见 环境变量配置 中的「安全」小节:

变量默认值用途
JWT_PUBLIC_KEY空启用 API 和 Web 路由的 Bearer token 校验
AUTH_TOKEN空简单部署场景的共享 token,取决于运行镜像是否支持

JWT 鉴权:用公钥验证 Bearer Token

原理与角色划分

设置JWT_PUBLIC_KEY即可启用 Bearer token 校验,采用典型的非对称签名模式:

  • 业务侧(Token 签发方):使用私钥签发 JWT;
  • 沙盒侧(Token 验证方):只持有 base64 编码的公钥,通过JWT_PUBLIC_KEY环境变量注入,验证每个请求携带的 Bearer token。

这种公私钥分离的设计保证私钥不会进入沙盒镜像,业务侧可以独立控制签发策略(如有效期、受众),沙盒侧只负责验证。

生成密钥对

使用 OpenSSL 生成 2048 位 RSA 密钥对:

openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem

private_key.pem保留在业务侧,public_key.pem用于注入沙盒。

启动沙盒并注入公钥

通过-e JWT_PUBLIC_KEY="$(base64 -w 0 public_key.pem)"把公钥(base64 单行编码)注入容器。同时建议把端口只绑定到 localhost,避免沙盒 API 直接暴露到局域网或公网:

docker run --security-opt seccomp=unconfined --rm -it \ -p 127.0.0.1:8080:8080 \ -e JWT_PUBLIC_KEY="$(base64 -w 0 public_key.pem)" \ ghcr.io/agent-infra/sandbox:latest

说明:--security-opt seccomp=unconfined是 AIO Sandbox 运行的必要参数(浏览器等组件依赖),与鉴权无关但不可省略。镜像名以当前仓库 docker-compose.yaml 与 README.md 中使用的ghcr.io/agent-infra/sandbox:latest为准。

使用 Docker Compose 时,仓库的 docker-compose.yaml 已预留了端口绑定与环境变量透传:

ports: - "127.0.0.1:${HOST_PORT:-8080}:8080" environment: JWT_PUBLIC_KEY: ${JWT_PUBLIC_KEY:-}

也就是说,你只需在宿主机导出JWT_PUBLIC_KEY环境变量(或.env文件),Compose 会自动注入容器。

业务侧签发 JWT 并调用 API

业务服务用私钥签发 token(有效期建议按需控制,例如 1 小时),然后调用 API 时携带 Bearer token:

curl "http://localhost:8080/v1/sandbox" \ -H "Authorization: Bearer $SANDBOX_TOKEN"

在本地验证鉴权链路的完整流程(从密钥生成到请求成功),可参考 鉴权指南,其中包含用 shell 直接构造 RS256 JWT 的脚本:

base64url_encode() { openssl base64 -e -A | tr '+/' '-_' | tr -d '='; } header='{"alg":"RS256","typ":"JWT"}' exp_time=$(($(date +%s) + 3600)) payload="{\"exp\":${exp_time}}" to_be_signed="$(echo -n "$header" | base64url_encode).$(echo -n "$payload" | base64url_encode)" signature=$(echo -n "$to_be_signed" | openssl dgst -sha256 -sign private_key.pem | base64url_encode) jwt="${to_be_signed}.${signature}"

并可通过curl "http://localhost:8080/cdp/json/version" -H "Authorization: Bearer ${jwt}"验证带鉴权的浏览器调试端点。生产环境中应使用成熟 JWT 库签发,而不是手写脚本。

共享 token 的补充场景

对于简单部署场景,镜像若支持还可以通过AUTH_TOKEN环境变量启用共享 token 鉴权(见 环境变量配置)。它不依赖密钥对,适合单点信任的内网场景;但共享 token 无法做细粒度的签发与吊销控制,因此安全要求较高时仍应优先使用 JWT 模式。

短时票据:为浏览器访问与临时交接而设计

为什么需要票据

JWT 需要放在Authorization请求头中,但浏览器直接打开 VNC、WebSocket 等页面时无法自定义请求头。此时就用「短时票据」替代:先携带 JWT 通过一次带鉴权的 API 调用换取一次性票据,再把票据以 URL 查询参数(?ticket=...)形式拼接到前端访问地址中。

票据应尽快过期,并限制在最小必要访问范围内(例如只允许访问 VNC 对应路径),从而把长期 JWT 的泄露风险收敛为一个几十秒内有效的临时凭证。

端点与 SDK 佐证

从 SDK 源码可以看出票据功能的官方实现(sdk/python/agent_sandbox/auth/raw_client.py):

  • POST /tickets:创建并返回一个短时票据。SDK 文档明确标注这是非幂等操作,每次调用都会生成一个新的唯一票据(见 sdk/python/agent_sandbox/auth/client.py);
  • GET /auth:验证请求,支持两种凭证——x-original-uri请求头中的票据,或Authorization请求头中的 JWT。该端点专为 Nginxauth_request之类的鉴权子请求设计(见 sdk/python/agent_sandbox/auth/raw_client.py)。

Python SDK 中的调用方式:

from agent_sandbox import Sandbox client = Sandbox(base_url="http://localhost:8080") ticket = client.auth.create_ticket()

完整换取与使用流程

  1. 前置条件:服务已通过静态(JWT_PUBLIC_KEY)或动态模式启动并完成鉴权配置。

  2. 用 JWT 换取票据:票据默认有效期为 30 秒,可通过TICKET_TTL_SECONDS环境变量调整:

ticket_response=$(curl --silent -X POST "http://localhost:8080/tickets" \ -H "Authorization: Bearer ${jwt}") ticket=$(echo "$ticket_response" | jq -r .ticket) expires=$(echo "$ticket_response" | jq -r .expires_in) echo "票据: ${ticket}, 有效期: ${expires}秒"
  1. 客户端拼接访问 URL(以 VNC 为例):
vnc_url="http://localhost:8080/vnc/index.html?ticket=${ticket}&path=websockify%3Fticket%3D${ticket}"

浏览器打开该 URL 即可在无请求头能力的情况下完成鉴权访问。完整的可运行示例见 鉴权指南。

网络边界:最小暴露原则

无论是否开启鉴权,网络边界都是必须单独落实的一层:

  • 不需要远程访问时,只绑定到 localhost。例如上文-p 127.0.0.1:8080:8080,或 Compose 中的127.0.0.1:${HOST_PORT:-8080}:8080,让沙盒 API 只在本机可达;
  • 共享环境中,建议在沙盒前放置带 TLS 的反向代理。沙盒内部服务走 HTTP,TLS 终结放在代理层;同时可配合上文提到的GET /auth端点做auth_request鉴权子请求,把「先鉴权、后转发」的职责交给代理;
  • 通过 IP、网络或服务身份限制入站访问。例如防火墙只放行内网网段、Kubernetes 下用 NetworkPolicy 限定来源 Pod(见 README.md 中的 Deployment 示例),云环境可用安全组;
  • 不要把未鉴权的沙盒 API 暴露到公网。沙盒内的 Shell 与文件 API 具备完整执行能力,一旦裸奔暴露等同于把主机交给任意访客。

更完整的云端部署边界建议(边缘层加鉴权、启用沙盒自身 JWT 鉴权)可参考 云部署指南。

密钥处理:凭据的生命周期管理

针对可能进入沙盒容器的密钥,遵循以下原则:

  • 通过运行时环境变量或密钥管理系统传入密钥。沙盒的配置体系本身就建立在环境变量之上,JWT_PUBLIC_KEY、AUTH_TOKEN都应通过docker run -e或 Compose 的environment注入,而不是烧进镜像;
  • 不要把密钥写入自定义镜像。镜像会被复制、分发和长期留存,一旦打入镜像就失去吊销能力;
  • 不要把长期密钥写入 Skills、Hooks、Notebook 或生成文件。这些内容可能在沙盒工作区持久化、被 Agent 读取或随上下文泄露,长期密钥一旦进入就等于明文外泄;
  • 任务级访问优先使用短时凭据。单个任务用几十秒有效的票据或短有效期 JWT,即便被截获,其影响范围也随时间自动收敛。

小结:从本地可信到生产可用的安全 Checklist

层级措施关键配置/依据
身份鉴权开启 JWT Bearer token 校验JWT_PUBLIC_KEY(base64 公钥),见 环境变量配置
身份鉴权简单场景共享 tokenAUTH_TOKEN
临时交接浏览器/WebSocket 访问用短时票据POST /tickets+?ticket=,TICKET_TTL_SECONDS控制有效期
网络边界端口只绑 localhost、前置 TLS 反向代理、限制入站来源-p 127.0.0.1:8080:8080、GET /auth供代理auth_request使用
密钥管理环境变量注入、不入镜像、不写进生成文件、优先短时凭据见 docker-compose.yaml 环境变量示例

AIO Sandbox 的安全模型可以概括为一句话:默认面向可信本地,暴露即需鉴权。按照本文的 JWT 鉴权、短时票据、网络边界与密钥管理四步加固后,沙盒的 Browser、Shell、File 等全部能力才能在受控边界内安全地开放给 Agent 与其他服务使用。

  • AI Agent
  • 后端
  • MCP 服务
  • 浏览器控制
  • Agent 评测

【免费下载链接】sandbox

All-in-One Sandbox for AI Agents that combines Browser, Shell, File, MCP and VSCode Server in a single Docker container.

项目地址:https://gitcode.com/gh_mirrors/sandbox103/sandbox
点击查看免费下载

相关推荐

上一篇:Cherry Studio 跨平台入门指南:Windows/macOS/Linux 完整安装与快速上手
下一篇:解密Equalizer APO:系统级音频处理的架构设计与实战优化

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 2:09:44

青岛市shp数据转GeoJSON实操:格式解析、坐标系与避坑指南

简介:这份青岛市空间数据压缩包,面向GIS学习者、城市规划与地理信息处理人员,承载了青岛市完整的区域划分矢量边界,包含行政区域轮廓、空间范围等基础地理要素,可直接用于地图制图、叠加分析与Web地图展示,…

作者头像 李华
网站建设 2026/10/10 2:07:56

光模块核心知识拆解:封装演进、激光器选型与DDM排障实践

简介:《光模块学习文档.docx》是一份面向光通信初学者、网络工程师及数据中心运维人员的基础学习资料,系统梳理了光模块在交换机、路由器、服务器等设备间的核心作用与光电转换原理。文档从速率、功能、封装、应用领域、传输模式等多个维度展开分类讲解&…

作者头像 李华
网站建设 2026/10/10 2:07:51

OpenClaw Windows 安装指南:把 settings 改到 TaoToken 的完整配置流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 2:06:53

断网也能飞:无人机项目最容易被忽视的底座

在工业无人机场景里,最让人崩溃的,往往不是飞机飞不起来。 而是飞机已经起飞了,地图却打不开。 现场并不少见这样的画面: 飞手就位,任务下发,大屏准备联动。结果一进作业区,公网开始掉链子&…

作者头像 李华