关于 openshell-cli
openshell-cli 是指导 Agent 使用 openshell 命令行管理沙箱与平台资源的技能,适用于需要编排 OpenShell 工作流的用户。内容涵盖网关、沙箱、Provider、配置文件和策略生命周期,并建议以 CLI 内置帮助为准。
主要功能
- 01管理网关与沙箱
- 02创建和维护 Provider
- 03检查与导入配置文件
- 04编排凭据及策略流程
- 05通过内置帮助查找命令
适用场景
- 01连接网关并启动沙箱
- 02为沙箱配置 Provider 凭据
- 03检查或导入 Provider 配置文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nvidia/ openshell --skill openshell-cli安装后在 Claude Code 中输入/openshell-cli确认已加载。
详细介绍
OpenShell CLI
指导 Agent 使用 openshell CLI 管理沙盒和平台——从基本操作到高级多步骤工作流。
概述
OpenShell CLI(openshell)是管理沙盒、提供方、策略、设置、暴露的服务和网关注册的主要接口。网关服务的生命周期由软件包、systemd 或 Helm 在 CLI 之外处理。本技能将指导 Agent 编排 CLI 命令,以完成常见和复杂的工作流。
配套技能:要创建或修改沙盒策略 YAML 内容(网络规则、L7 检查、访问预设),请使用 generate-sandbox-policy 技能。本技能介绍策略生命周期的 CLI 命令;generate-sandbox-policy 则介绍策略内容的编写。
自学:CLI 内置了全面的帮助信息。遇到本技能未涵盖的命令或选项时,请沿着帮助树逐级查看:
openshell --help # Top-level commands
openshell <group> --help # Subcommands in a group
openshell <group> <cmd> --help # Flags for a specific command
这是首选的备用方案,可随时使用——CLI 的帮助输出具有权威性,且始终保持最新。
前置条件
openshell已加入 PATH。若尚未安装,请参阅发布的安装指南。- 可访问由 Docker、Podman、Kubernetes 或实验性 VM 驱动程序支持的 OpenShell 网关
- 仅在使用 BYOC 本地构建或 Docker 支持的网关时,才需要运行 Docker
- 对于 Kubernetes 部署:可访问目标集群的
kubectl和 Helm
权威参考资料
以 openshell --help 和嵌套的 --help 输出为准,了解已安装 CLI 版本的信息。使用发布的文档了解产品概念和受支持的工作流:
工作流 1:开始使用
当用户已有网关端点,并希望首次启动沙盒时,请使用此工作流。
步骤 1:注册网关
openshell gateway add http://127.0.0.1:8080 --local --name local
仅当用于可信的本地端口转发或受保护的私有路径时,才使用 http:// 端点。对于位于经过身份验证的反向代理之后的网关,请使用 openshell gateway add https://gateway.example.com 注册其 HTTPS 端点。
步骤 2:验证网关
openshell status
openshell whoami
确认网关可访问、身份验证有效或无需身份验证,并且
输出中显示了版本号。Status: Connected 仅能证明公共健康检查
端点可访问;运行受保护的命令前,请单独检查 Authentication 行。
openshell whoami 会报告经网关验证的身份,包括管理员用于授予
工作区成员资格的主体。自动化时可添加 --output json。
步骤 3:创建沙箱
启动沙箱最简单的方法:
openshell sandbox create
这会创建一个沙箱,其规范主进程为 /bin/bash -l,并将你的终端连接到该保留进程。添加 --detach,即可在沙箱就绪后返回,而不连接到该进程。
即使 stdin 或 stdout 不是终端,显式指定的末尾命令也会在前台运行。CLI 会流式传输其 stdout 和 stderr,并在输出排空后报告命令的退出状态。如果输出传送失败,即使命令本身已成功退出,CLI 也会报告失败;重试可能产生副作用的操作前,请检查沙箱状态。退出代码为 0 时,保留的沙箱状态为 Completed;非零时,状态为 Error,并显示 MainProcessFailed。使用 --no-keep 可在输出排空后删除这两种结果,或使用 --detach 运行长时间运行的服务。当网关应在没有主机连接的情况下运行服务,并在服务退出后删除其沙箱时,可组合使用 --detach --no-keep。
指定 --name 时,请使用可移植的 DNS-1123 标签:最多 63 个小写字母、数字或 - 字符,且必须以字母或数字开头和结尾。Kubernetes 驱动程序会拒绝大写字母、下划线、点号以及其他无法转换为 Kubernetes 资源标签的名称。
提供方连接需显式指定。使用 --provider 命名每个提供方;末尾命令不会选择或连接提供方。如果指定的提供方不存在,但有可用的同 ID 配置文件,CLI 可以根据本地凭据创建该提供方:
openshell sandbox create --from registry.example.com/your-org/claude-agent:latest --provider claude-code -- claude
openshell sandbox create --from registry.example.com/your-org/codex-agent:latest --provider codex -- codex
如果缺少凭据,Agent 会提示用户交互式地提供。
步骤 4:退出并清理
使用 exit 退出沙箱 shell,或按 Ctrl-D 分离,然后:
openshell sandbox delete <name>
工作流 2:提供方管理
提供方为沙箱提供凭据和特定于提供方的配置。提供方配置文件只能导入:网关只提供操作员导入的内容,而新网关的目录为空。切勿依赖硬编码的类型列表或 gh、claude 等旧别名——--type 会与配置文件 ID 精确匹配。发现所选网关上可用的配置文件:
openshell profile list
openshell profile list --type provider --output json
使用本地凭据创建提供方
openshell provider create --name my-github --type github --from-existing
--from-existing 标志会从本地状态发现凭据(例如,gh auth 令牌、Claude 配置文件)。
使用显式凭据创建提供方
openshell provider create --name my-openai --type openai \
--credential OPENAI_API_KEY
单独使用 KEY 会从同名环境变量读取值,避免将密钥写入 shell 历史记录。仅当用户明确接受此类暴露时,才使用 KEY=VALUE。
其他凭据来源包括:适用于兼容配置文件的 --from-gcloud-adc,以及在网关或沙箱运行时解析所需凭据时使用的 --runtime-credentials。
静态提供方凭据仅适用于提供方配置文件声明的主机、端口和路径。当存在占位符但请求收到 credential_endpoint_mismatch 时,可使用 profile export 检查该范围。没有配置文件的静态提供方会默认拒绝请求,因为网关无法构造绑定。
当经过检查的请求收到 request_authority_mismatch 时,请比较其 HTTP authority 与 CONNECT 隧道端点。主机和有效端口必须匹配。对于连接到 api.example.com:8443 的隧道,请发送
Host: api.example.com:8443;Host: api.example.com 未包含非默认端口,因此会被拒绝。绝对形式的请求目标也必须使用相同的 authority。
除非启用了网关全局策略,否则基于配置文件的提供方始终会应用策略。静态凭据端点绑定仍会独立强制执行。
为提供方添加标签并进行筛选
创建提供方时,可通过可重复使用的 --label KEY=VALUE
标志添加标签。所有凭据来源均支持标签。列表筛选器要求每个以逗号分隔的键值对都匹配,并在分页前应用。
openshell provider create --name public-pypi --type pypi --label env=dev --label team=ml
openshell provider list --label-selector env=dev,team=ml
openshell provider list --all-workspaces --label-selector team=ml --output json
openshell provider get public-pypi
在本示例中,使用导入的配置文件(例如 pypi)。get 会显示标签;
结构化列表输出也包含标签。--all-workspaces 需要 Platform
Admin 访问权限。传递下一个
--page-token 时,请保留筛选器和工作区范围。创建提供方后,无法更改或移除标签。
检查和管理提供方配置文件
openshell profile describe github
openshell profile export github --output yaml
openshell profile lint --file ./my-profile.yaml
openshell profile import --file ./my-profile.yaml
openshell profile lint --url https://example.com/profiles/my-profile.yaml
openshell profile import --url https://example.com/profiles/my-profile.yaml
--url 接受一个 HTTP 或 HTTPS YAML 或 JSON 配置文件。导入前,请检查其端点和
二进制授权。URL 路径必须以 .yaml、.yml 或 .json 结尾;下载大小上限为 1 MiB,超时时间为 15 秒。
创建提供方前,使用 profile describe 检查定义中的凭据元数据、端点、TLS 处理方式、MCP 访问设置、规则数量、二进制文件、来源和范围。在依赖显示的 L7 规则之前,请检查是否设置了 tls: skip,以及是否启用了未经检查凭据的选项。列表和描述命令支持表格、JSON 和 YAML 输出;使用结构化输出获取完整规则定义,使用 --workspace 指定工作区目录,或使用 --global 指定平台范围。准备可编辑的定义时,使用 profile export;使用 profile update <id> --file <file>,通过当前资源版本替换现有自定义配置文件;使用 profile delete <id>... 删除自定义配置文件。提供方实例仍通过 provider 管理。
现有脚本可继续使用 provider list-profiles 和 provider profile export/import/update/lint/delete。
这些命令共用顶层处理程序,并保留其参数、输出选项以及工作区/全局标志。编写新命令时,优先使用 profile。
列出、检查、更新、删除
使用 openshell sandbox provider status --help 以及 attach、detach 和 update 的帮助信息,查找已安装版本的等待选项。如果后续步骤依赖提供方变更生效,请添加 --wait。不添加此选项时,命令成功仅表示网关已保存变更。保存返回的 receipt_id,以便稍后检查同一项变更,并检查每个选定沙盒的结果。凭据刷新状态确认 OpenShell 已获取凭据;提供方状态确认沙盒已应用凭据、激活策略,并为新进程更新环境。如果状态为 superseded,请说明后续变更已取代此请求,并单独检查该变更。
如果 attach、detach 或 update 报告 CONFIG_OPERATION_STORAGE_UNCERTAIN,请说明变更可能已保存,但可能无法获取其就绪回执。不要盲目重试该变更操作。检查提供方和沙盒状态,并核实已保存的变更,然后再决定是否执行其他变更操作;此错误既不能证明操作已回滚,也不能证明已就绪。
openshell provider list
openshell provider list --output json
openshell provider get my-github
openshell provider update my-github --from-existing
openshell provider delete my-github
provider update 不接受 --type。它会更新现有提供方的凭据、配置或凭据有效期。
如果外部更新程序的工作负载必须保留原始环境引用,请使用设置了 stable_placeholder: true 的凭据配置,并确保网关和 supervisor 支持该模式。CLI 会在导入或更新此可选设置之前检查网关是否支持。默认值仍为 false,从而保留现有的按修订版本限定的行为和普通的旧版网关运行方式。保留 supervisor 签发的值;切勿自行生成占位符。supervisor 安装仅值更新后,保留的引用只会在其有效的主机、端口和路径绑定范围内解析为当前凭据。凭据替换、过期、绑定变更或已激活的分离操作,都会阻止旧授权继续解析。降级网关前,请移除此可选设置并激活该变更。有关生命周期约定及其与网关管理的刷新和 token_grant 的区别,请参阅提供方配置文档。
配置凭据刷新
仅当提供商配置文件和网关支持可刷新的凭据时,才使用刷新命令:
openshell provider refresh status my-provider
openshell provider refresh configure my-provider \
--credential-key MS_GRAPH_ACCESS_TOKEN \
--strategy oauth2-refresh-token \
--secret-material-env REFRESH_TOKEN=MS_GRAPH_REFRESH_TOKEN \
--credential-expires-at 2026-07-16T00:00:00Z
openshell provider refresh rotate my-provider --credential-key ACCESS_TOKEN
对于机密刷新材料,优先使用 --secret-material-env KEY[=ENVVAR]。--material KEY=VALUE 用于非机密材料;--secret-material-key 会将提供的材料键标记为机密。
网关通过其活动凭据驱动程序存储机密刷新材料。 选择 Vault 后,刷新令牌、客户端密钥和私钥会与可注入的提供商凭据一同存储在 Vault 中;刷新状态仅包含不透明句柄。凭据后端读取或写入失败时,刷新会以 失败关闭的方式处理,而不会回退到内联存储。在 OpenShell 0.1.0 之前,网关 不会迁移旧版内联刷新材料,也不会在凭据后端之间移动机密。升级后请重新配置 受影响的授权;在更改后端之前,请确保原后端仍可用,并在此期间移除或重新配置 凭据。不要让混合版本的网关使用同一批刷新记录。
网关管理的刷新凭据使用身份稳定的工作负载句柄。常规自动刷新和
provider refresh rotate 会更新该句柄关联的访问令牌,因此长时间运行的
进程无需重启。从按修订版本划分的占位符升级时,必须重启正在运行的进程一次。
之后调用 provider refresh configure 是明确的重新授权边界:它会撤销先前的
句柄,持有该句柄的进程将以失败关闭的方式处理,直至重启。
配置了网关管理的刷新后,provider update --credential 无法替换或删除刷新
拥有的主要凭据或任何共同签发的输出。要恢复手动管理这些密钥,请使用
provider refresh rotate、重新配置刷新,或先删除刷新。其他不相关的提供商
字段仍可更新。
OAuth 刷新失败时,请查看 provider refresh status 输出中的 RECOVERY 和
FAILURE_CODE 列;不要根据 HTTP 状态推断补救措施,也不要解析
LAST_ERROR。retry 表示工作线程会再次尝试;reauthorize 表示用户必须获取
新的 OAuth 授权,并运行 provider refresh configure;fix_configuration
表示操作员必须修复 OAuth 客户端、作用域或管理员策略;investigate 可能表示
发行方响应无法识别,或签发过程被中断且结果不确定。网关会暂停
reauthorize 记录,直到手动轮换或重新配置。它会每小时重试
fix_configuration 记录,以便外部修复配置后能够恢复,同时避免令牌端点流量
激增。现有访问凭据仅在其记录的到期时间之前可用。
refresh_in_progress 和 refresh_committing 可能表示操作仍在进行。将其视为
失败之前,请检查网关运行状况和刷新状态;并发刷新请求会等待当前签发操作完成。
如果网关中断后遗留了其中任一标记,且轮换报告先前的签发结果不确定,网关将
不会自动重用该授权。请调查发行方状态,然后使用有效授权运行
provider refresh configure。如果先前的刷新令牌可能已被使用,请先获取新的
OAuth 授权。不要直接清除标记,也不要反复轮换;重新配置会撤销旧的工作负载
句柄,因此请重启持有这些句柄的进程。
工作流 3:沙盒生命周期
使用选项创建
openshell sandbox create \
--name my-sandbox \
--provider my-github \
--provider my-claude \
--policy ./my-policy.yaml \
--label team=agents \
-- claude
关键标志:
--provider:附加已配置的凭据提供方,用于 API 密钥、令牌和其他机密(可重复指定)--policy:自定义策略 YAML(否则使用内置默认值或OPENSHELL_SANDBOX_POLICY环境变量)--gpu [COUNT]:请求驱动程序的默认 GPU 选择,或指定 GPU 数量--cpu、--memory:设置每个沙箱的计算资源规格。Docker/Podman 会应用限制;Kubernetes 会应用相应的请求和限制。--driver-config-json:传入实验性的驱动程序专属沙箱配置--template NAME:基于具名沙箱工作负载模板创建。与--from、--gpu、--cpu、--memory、--env、--env-from和--driver-config-json等内联工作负载标志冲突。--label KEY=VALUE:添加标签以供后续选择(可重复指定)--annotation KEY=VALUE:添加非机密元数据,例如文件路径(可重复指定)--env KEY=VALUE:设置非机密沙箱环境变量(可重复指定);凭据请使用--provider--env-from KEY[=ENVVAR]:从 CLI 进程环境中读取沙箱环境变量值,不将其值放入参数中;如需避免工作负载接触凭据,请使用--provider--tty:为规范主进程分配一个保留的 PTY--restart-policy never|on-failure|always:选择由网关管理的主进程重启行为;默认值为never--approval-mode manual|auto:控制对由 Agent 编写的策略提案的处理方式;默认值为manual--upload <PATH>[:<DEST>]:将本地文件上传到容器工作目录或指定目标路径--no-git-ignore:禁用上传时的.gitignore过滤--no-keep:主进程输出和退出结果排空后删除沙箱--detach:启动规范主进程,但不附加到该进程--forward [BIND_ADDRESS:]PORT:转发本地端口并保持沙箱运行--editor vscode|cursor:创建后打开远程编辑器并保持沙箱运行
如果驱动程序在创建验证期间拒绝前台附加,请使用 --detach。
--detach 不会增加附加宽限期。规范进程退出后,
系统会立即报告其终止阶段。前台创建会声明一个预期的主进程
SSH 附加;该连接自然关闭后,清理工作才会完成。使用
--detach --no-keep 时,网关负责管理分离进程的生命周期,并在
终止报告完成后删除临时沙箱。
不要将 --upload 与末尾的主命令一起使用。
上传目前会在规范进程启动后完成;请创建临时沙箱并使用
sandbox exec,或将文件构建到镜像中。
当多个沙箱需要共享镜像、环境、资源规格或驱动程序专属配置时, 请基于可复用的工作负载模板创建:
openshell sandbox template create gpu-kata \
--image registry.example.com/agents/python:latest \
--cpu 2 \
--memory 4Gi \
--gpu 1 \
--driver-config-json '{"kubernetes":{"pod":{"node_selector":{"pool":"gpu"}}}}'
openshell sandbox create --name my-sandbox --template gpu-kata --provider my-github -- claude
默认情况下,驱动程序配置处于禁用状态。以下模板示例和一次性
sandbox create --driver-config-json 示例都要求管理员为所选驱动程序设置
allow_driver_config = true。这不会免除资源准入要求:外部附加
需要在实际资源上设置由管理员控制的批准标签,而不是沙箱标签。GPU 设备附加
暂时不需要标签;公开的 --gpu 标志无需启用驱动程序配置。更改准入设置前,
请参阅已发布的网关配置参考;不要建议通过禁用准入来绕过
拒绝。只有在需要复用驱动程序配置时,才将其放入模板中。
管理沙箱工作负载模板
openshell sandbox template create gpu-kata \
--image registry.example.com/agents/python:latest \
--cpu 2 \
--memory 4Gi \
--gpu 1 \
--label team=runtime \
--env FEATURE_FLAG=on
openshell sandbox template list
openshell sandbox template list --label-selector team=runtime
openshell sandbox template list --all-workspaces --output json
openshell sandbox template get gpu-kata
openshell sandbox template delete gpu-kata
模板的 --image 接受 OCI 镜像引用。如果省略,网关会在根据模板创建沙箱时
应用默认沙箱镜像。创建时的策略、提供方、标签、上传、端口转发、
编辑器启动和初始命令仍通过 sandbox create 设置。
列出并检查沙盒
openshell sandbox list
openshell sandbox list --selector team=agents --output json
openshell sandbox get my-sandbox
大多数可选沙盒名称的命令都会使用上次使用的沙盒。在自动化中,请传入明确的名称。
连接到正在运行的沙盒
openshell sandbox connect my-sandbox
openshell sandbox connect my-sandbox --editor vscode
连接到沙盒中现有的规范主进程。断开连接不会终止该进程;重新连接时会指向同一个进程实例,并重放最近的输出。如果已建立的 SSH 传输中断(例如,笔记本电脑休眠后又唤醒),CLI 会在最长 60 秒内重试暂时性故障,并重新连接到同一个进程。要启动新的 shell,请使用 sandbox exec --tty -- /bin/bash -l。按 Ctrl-D 或 Ctrl-P,然后按 Ctrl-Q,即可断开连接而不终止主进程。OpenSSH 的 ~. 转义序列看起来像传输中断,因此会启动自动恢复;重新连接后,按 Ctrl-D 或 Ctrl-P,然后按 Ctrl-Q 退出,或者在两次重试之间按 Ctrl-C 取消恢复。当你拥有 stdin 时,Ctrl-C 会中断前台进程。在只读连接中,按 Ctrl-C 或 Ctrl-D 会退出查看器,并让主进程和其他连接继续运行。使用以下配置设置 VS Code Remote-SSH:
openshell sandbox ssh-config my-sandbox >> ~/.ssh/config
如果可写连接发现另一个连接正占用 stdin,就会报告 attached read-only; retry input after the owner disconnects。自动恢复可能在重新连接时遇到这种情况,因为监督程序尚未关闭失效的连接。监督程序会在连接最后一次收到字节 60 秒后关闭该连接;如果中继缓冲了数据,关闭时间可能晚于网络中断后的 60 秒。旧连接的所有者断开连接或超时后,再发送你接下来想输入的内容。如果 stdin 空闲,连接会打印 input enabled 并将该输入转发给进程,因此不要按 Enter 试探,也不要发送 y 之类的提示回答。如果没有任何输出,说明旧连接仍占用 stdin。在连接处于只读状态时发送的输入不会到达进程,因此之后需要重新发送。按 Ctrl-C、Ctrl-D,以及按 Ctrl-P 后再按 Ctrl-Q,仍会退出只读连接,而不会启用输入;如果需要用 Ctrl-C 中断进程,请先启用输入。恢复过程不会从正常运行的所有者手中接管 stdin,显式设为只读的连接也会始终保持只读。
如果 connect 报告 canonical main process already finished,请使用 sandbox get 检查结果。处于 Completed 或 Error 状态的待处理前台连接仍可获取保留的输出;是否可连接并不只由阶段状态决定。在 on-failure 策略下,主进程以非零状态退出,或在 always 策略下主进程以任何状态退出,都会使沙盒在退避等待和资源替换期间进入 Starting 状态。新的监督程序会话变为 Ready 后,连接和执行命令会恢复。显式执行 sandbox stop 会取消待处理的重启。
上传和下载文件
# Upload local files to the sandbox working directory
openshell sandbox upload my-sandbox ./src
# Download a path relative to the sandbox working directory
openshell sandbox download my-sandbox output ./local-output
上传使用有界流式传输,并会等待沙盒消耗输入;4 MiB 的进程输入预算并非上传总大小上限。请同时升级 CLI 和沙盒使用的 supervisor 运行时。较旧的 supervisor 会在发送文件数据之前拒绝上传协议。失败或取消的上传可能会在目标位置留下不完整的文件;重试前请检查目标位置,或删除残留文件。
默认情况下,在 Git 工作树中上传会遵循 .gitignore,如果 Git 筛选失败或未选中任何文件,则会停止。确认位于 Git 工作树之外的源文件会在不进行筛选的情况下上传,并会警告未应用 .gitignore 规则。必须能够使用 Git,才能判断是否适用筛选;损坏或无法访问的仓库会导致上传停止。如需明确进行未筛选上传,请添加 --no-git-ignore。sandbox create --upload 也适用此规则。
sandbox create --upload 会在配置资源前于本地检查每个上传项;如果有任何上传项被拒绝,则不会创建沙盒。如果配置资源后传输失败,沙盒仍会运行,且此前的上传可能已完成。请针对该沙盒重试 sandbox upload,或使用 sandbox delete 将其删除。
上传会保留符号链接,包括悬空符号链接,而不会跟随链接访问目标。符号链接源会跳过 Git 筛选,以便将链接本身打包存档。
省略上传目标时,CLI 会查找远程工作目录。上传具名目录时,会将其合并到同名的现有目录中,覆盖匹配的条目,但不会删除无关条目。下载路径可以是相对于该工作目录的路径,也可以是该目录内的绝对路径。
执行非交互式命令
openshell sandbox exec my-sandbox --workdir /workspace -- ls -la
openshell sandbox exec --name my-sandbox --env MODE=test -- cargo test
沙盒必须是位置参数名称或 --name,不能同时使用两者;省略时会使用上次使用的沙盒。必须使用 --,其后的所有内容都会作为远程命令,因此请将 --tty 等选项放在它之前。
sandbox exec 会启动一个独立的同级进程,并流式传输输出。标准输出和标准错误流排空后,如果输出传送成功,则会返回远程命令的退出代码。如果输出传送失败,则会返回退出代码 74,即使命令已成功退出也是如此。命令退出后,如果某个后代进程在超过 30 秒的时间内仍保持继承的输出管道打开,就会触发此失败。重试有副作用的工作之前,请先确认命令是否已运行。请使用 sandbox connect 连接到规范的主进程。
--env 仅用于非机密值。请通过提供程序将凭据附加到沙盒,而不要将 API 密钥、令牌或其他机密传递给 sandbox exec。
更改已附加的提供程序
openshell sandbox provider list my-sandbox
openshell sandbox provider list my-sandbox --output json
openshell sandbox provider attach my-sandbox my-github --wait --timeout 30
openshell sandbox provider status my-sandbox my-github --output json
openshell sandbox provider detach my-sandbox my-github --wait --timeout 30
结构化的附加信息输出包含提供程序名称、类型,以及已排序的凭据和配置键名称。它绝不会包含凭据、句柄或配置值。
查看日志
# Recent logs
openshell logs my-sandbox
# Stream live logs
openshell logs my-sandbox --tail
# Filter by source and level
openshell logs my-sandbox --tail --source sandbox --level warn
# Logs from the last 5 minutes
openshell logs my-sandbox --since 5m
删除沙盒
openshell sandbox delete my-sandbox
openshell sandbox delete sandbox-1 sandbox-2 sandbox-3 # Multiple at once
openshell sandbox delete --all
deletion accepted 表示清理仍在进行中。请检查沙盒,直至其消失,再确认删除已完成。已不存在的沙盒也会视为成功;工作区缺失和授权失败仍会报错。如果其他进程可能已重新创建同名沙盒,请勿盲目按名称重试。
停止和启动沙箱
使用 stop 可停止计算,同时保留沙箱及其持久化工作区:
openshell sandbox stop [name]
openshell sandbox start [name]
这两个命令默认针对最近使用的沙箱。Stop 会停止后台转发,并等待状态变为 Stopped;start 会等待状态变为 Ready。沙箱处于停止或已完成状态时,无法连接、执行命令、传输文件、进行转发或访问已公开的服务。启动保留的 Completed 或 Error/MainProcessFailed 沙箱时,会启动一个全新的规范主实例,并使前一个运行时代的 SSH 会话失效。删除才会移除保留状态。
沙箱的 SSH 主机身份在 stop/start 和运行时重启后保持不变。API 客户端可以从沙箱资源或 SSH 会话响应中读取其公钥指纹,并将其绑定到沙箱 ID。即使使用相同名称重新创建已删除的沙箱,也会生成不同的身份。有关验证行为和发行版兼容性,请参阅沙箱 SSH 文档。
如果在支持重启已停止沙箱的后端上遇到基础设施 Error,请修复报告的原因,运行 sandbox stop 并等待其成功,然后运行 sandbox start。这会保留沙箱和持久化工作区,但无法恢复已删除的资源或存储。如果发生配置超时,请等待清理完成,然后直接运行 sandbox start。
暂停和恢复沙箱
在计算驱动程序和隔离后端支持此功能的网关上,suspend 会冻结处于 Ready 状态的沙箱,并保留其内存状态:
openshell sandbox suspend [name]
openshell sandbox resume [name]
Suspend 会等待状态变为 Suspended,然后停止后台转发。如果 suspend 被拒绝,转发会继续运行。Resume 会在新的运行时代中恢复状态,并等待状态变为 Ready。不支持此功能的网关会以 FAILED_PRECONDITION 拒绝 suspend。如果无法恢复保留的状态,resume 会失败;如需明确进行全新启动,请使用 sandbox start。对已暂停的沙箱运行 sandbox start、sandbox stop 和 sandbox delete 会丢弃保留的内存状态。
工作流 4:策略迭代循环
这是最重要的多步骤工作流。它建立了紧密的反馈循环,可根据观察到的活动不断完善沙箱策略。
核心概念:策略包含静态字段(激活后不可更改:filesystem_policy、landlock、process)和两个动态字段:network_policies 与 network_middlewares。如果所选计算驱动程序支持实时策略更新,则无需重新创建沙箱即可更新这两个动态字段。不使用标准 supervisor 的驱动程序会通过沙箱配置 API 获取修订版本,并报告是否已加载这些版本。
如果启动时报告 ConfigurationInvalid,请检查 openshell sandbox get,
并通过网关修复完整的策略或提供程序集合。沙箱首次激活时,工作负载尚未启动,
因此在这次初始修复期间也可以替换静态字段。此前已激活的沙箱在等待重启准入或
重启准入被拒绝期间,会保留静态字段限制。
在网关的 300 秒修复窗口到期之前,验证成功即可原地完成启动。已存储配置的有效变更
及其首次加载失败会重置此窗口;重复失败不会重置。发生
ProvisioningTimedOut 后,请检查保留的记录和清理状态,修复配置,并在清理完成后
显式运行一次 sandbox start。CLI 等待超时与此网关期限是分开的。请遵循已发布的
策略修复指南,
并通过已安装的 CLI 帮助确认当前的替换/分离语法。
未指定 protocol 的端点会保留显式代理行为。显式设置 protocol: tcp 表示请求使用策略 DNS 和透明 TCP,目前要求使用 Docker 或 Podman 运行时;不支持的运行时会在启动
工作负载前拒绝该策略,而不会仅激活网络契约的一部分。
Create sandbox with initial policy
│
▼
Monitor logs ◄──────────────────┐
│ │
▼ │
Observe denied actions │
│ │
▼ │
Pull current policy │
│ │
▼ │
Modify policy YAML │
(use generate-sandbox-policy) │
│ │
▼ │
Push updated policy │
│ │
▼ │
Verify reload succeeded ─────────┘
步骤 1:使用初始策略创建沙箱
openshell sandbox create --name dev --from registry.example.com/your-org/claude-agent:latest --policy ./initial-policy.yaml -- claude
默认情况下,沙箱会持续运行,以便进行迭代。只有在希望沙箱在初始会话后自动删除时,才添加 --no-keep。
步骤 2:监控日志中的拒绝操作
在单独的终端中监控,或由 Agent 监控:
openshell logs dev --tail --source sandbox
查找 DENIED 日志行。NET:OPEN [MED] DENIED 表示连接被阻止,HTTP:<METHOD> [MED] DENIED 表示请求被阻止。策略事件是 INFO 级别的日志记录,因此不要添加 --level warn。日志包含:
- 目标主机和端口(被阻止的对象)
- 二进制文件路径(尝试连接的进程)
- 拒绝原因(被阻止的原因)
步骤 3:提取当前策略
set -o pipefail
openshell policy get dev --base | sed '1,/^---$/d' > current-policy.yaml
--base 返回不含提供程序组合条目的可编辑策略;OpenShell 会单独组合已附加的提供程序规则。命令会打印修订详情、一行 ---,然后打印策略 YAML。sed 表达式只保留 YAML,因为 policy set 无法解析修订详情。--full 仅用于检查生效策略,不要将其作为 policy set 的输入。
第 4 步:修改策略
编辑 current-policy.yaml,允许被阻止的操作。**编写策略内容时,请委派给 generate-sandbox-policy 技能。**该技能负责处理:
- 网络端点规则结构
- L4 与 REST、WebSocket、JSON-RPC 和 MCP L7 策略决策
- 访问预设(
read-only、read-write、full) - TLS 终止配置
- 强制执行模式(
audit与enforce) - 二进制匹配模式
- 有序的
network_middlewares、主机选择、HTTP 请求/响应和 WebSocket 绑定,以及fail_open或fail_closed行为
当所选计算驱动程序支持实时策略更新时,可在运行时修改 network_policies 和 network_middlewares。使用 --wait 验证活动运行时已加载该修订版本;不要仅凭网关接受更新就推断策略已生效。如果需要更改 filesystem_policy、landlock 或 process,则必须重新创建沙箱。openshell/regex 等内置中间件无需在网关注册。由操作员运行的中间件必须已在 [[openshell.supervisor.middleware]] 下注册;更改此静态注册需要重启网关。
如果实现声明了相应绑定,中间件可以检查 HTTP 请求、HTTP 响应或客户端 WebSocket 文本消息。内置的 openshell/regex 支持请求正文和客户端 WebSocket 文本消息。使用 generate-sandbox-policy 技能选择附加项和失败策略,并使用 debug-openshell-cluster 调查中间件故障。
第 5 步:推送更新后的策略
openshell policy set dev --policy current-policy.yaml --wait
网关会验证完整的有效候选策略(包括已附加的提供方配置文件策略),之后才会存储直接更新、增量合并、已批准的提案、提供方附加项,或影响已附加沙箱的配置文件更新。若遇到歧义错误,将返回 FAILED_PRECONDITION;被拒绝的候选策略不会创建策略修订版本,也不会部分更新受影响的沙箱。如果 credential_signing 未附加凭据边界覆盖该端点的 AWS 配置文件,或者显式绑定到了没有端点的 AWS 配置文件,也会采用相同的失败关闭响应。修正冲突的端点选择器或凭据来源后重新提交。
--wait 标志会阻塞,直到沙箱确认策略已加载(每秒轮询一次)。退出代码:
- 0:策略已成功加载
- 1:策略加载失败
- 124:超时(默认 60 秒)
第 6 步:验证更新
openshell policy list dev
检查最新修订版本的状态是否为 loaded。如果状态为 failed,请查看错误列中的详细信息。
第 7 步:重复
返回第 2 步。继续监控日志并完善策略,直到允许所有必需操作,且不存在不必要的权限。
策略修订历史记录
查看所有修订版本,了解策略的演变过程:
openshell policy list dev --page-size 50
openshell policy list dev --output json
获取特定的历史修订版本:
openshell policy get dev --rev 3 --full
网关全局策略命令使用 --global,除非指定 --yes,否则需要确认:
openshell policy get --global --full
openshell policy set --global --policy ./global-policy.yaml
openshell policy list --global
openshell policy delete --global
交互操作时避免使用 --yes。全局策略会锁定网关上所有沙箱的策略控制。
审核 Agent 编写的规则提案
使用 --approval-mode manual 创建的沙箱会将每个提案放入审核收件箱。auto 只会批准有效策略候选方案中证明器差异为空的方案;发现的问题仍需审核。CLI 会将批准操作绑定到候选方案当前的审核令牌。如果实时策略、提供方或凭据输入发生变化,批准操作会将该区块保留为待处理状态,并刷新候选方案,因此需要重新审核。
openshell rule get dev --status pending
openshell rule approve dev --chunk-id <chunk-id>
openshell rule reject dev --chunk-id <chunk-id> --reason "too broad"
openshell rule history dev
批准前,请审核提议的范围、候选方案哈希、证明器发现的问题和应用错误。将 rule approve-all --include-security-flagged 视为高风险批量操作。
在网关能够分析当前策略和提议策略之前,validation unavailable 会阻止批准。它并不表示已接受风险。
工作流 5:BYOC(自带容器)
构建自定义容器镜像,并将其作为沙箱运行。
从预构建镜像创建沙箱
docker build -t my-app:latest .
openshell sandbox create --from my-app:latest --name my-app
--from 标志接受明确的 OCI 镜像引用,例如 myregistry.com/img:tag。它不会展开目录别名。先使用与本地网关相同的容器引擎构建本地 Dockerfile,然后传入镜像标签。
对于 Docker 网关,使用 docker build -t my-app:latest。对于 Podman 网关,使用 podman build -t localhost/my-app:latest,并将 localhost/my-app:latest 传给 --from。对于远程网关,将镜像推送到网关可访问的注册表。
对于 Docker 和 Podman 网关,自定义镜像应声明一个非 root 的 OCI
USER。未声明该值的镜像将以数字 UID 和 GID 1000 运行。每个显式设置的 process.run_as_user 或 process.run_as_group 策略
字段都会独立生效;未设置的字段则回退到镜像声明的值。
显式数字字段可以使用 1 到
4294967294 之间的任意 UID/GID;0 表示 root,4294967295 是无效身份哨兵值。
请提醒用户,较低的 ID 可能会继承匹配账户、镜像
文件、挂载卷或设备的权限。
转发端口
# Foreground (blocks)
openshell forward start 8080 my-app
# Background (returns immediately)
openshell forward start 8080 my-app -d
现在可以通过 localhost:8080 访问该服务。
CLI 端口转发不受用户 SSH 配置中的 SSH 多路复用和自动后台运行设置影响。只有后台转发会由 forward list 跟踪并由
forward stop 管理;前台转发会在命令退出时结束。
管理或迭代沙箱:
openshell forward list
openshell forward stop 8080 my-app
openshell sandbox delete my-app
openshell sandbox create --from my-app:latest --name my-app --forward 8080
自动化需要跟踪的转发元数据和经过验证的进程状态时,请使用结构化输出:
openshell forward list --output json
每条记录都包含 workspace、sandbox、bind_address、port、pid 和
alive。alive 布尔值会验证工作区范围内的沙箱和跟踪的进程身份;它不会探测转发的套接字。
在一条命令中创建并转发:
openshell sandbox create --from my-app:latest --forward 8080 -- ./start-server.sh
--forward 标志会在命令运行前启动后台端口转发。
工作流 6:Agent 辅助的沙箱会话
支持用户在沙箱中工作,同时由 Agent 并行监控活动并调整策略。
创建沙箱并使其保持运行:
openshell sandbox create \
--name work-session \
--provider github \
--provider claude \
--policy ./dev-policy.yaml
告知用户在另一个 Shell 中连接:
openshell sandbox connect work-session
openshell sandbox connect work-session --editor vscode
监控被拒绝的活动:
openshell logs work-session --tail --source sandbox
出现被拒绝的操作时:
-
对于新增网络配置,优先使用增量更新:
openshell policy update work-session --add-endpoint api.github.com:443:read-only:rest:enforce --binary /usr/bin/gh --waitopenshell policy update work-session --rule-name allow_api_github_com_443 --binary /usr/bin/gh --add-allow 'api.github.com:443:POST:/repos/*/issues' --wait规则会授权其中列出的每个二进制文件访问其中列出的每个端点,因此,更新现有规则以添加二进制文件或端点时,必须声明该规则的完整二进制文件和端点范围。网关会拒绝授予某个二进制文件访问某个端点的权限、但更新中未要求此权限的操作,并在错误中指出仍缺少的二进制文件。若要仅授予某个二进制文件访问规则中部分端点的权限,请使用其专属的
--rule-name提交范围较窄的授权;该授权会保留在自己的规则中,不会并入范围更广的规则。--add-allow和--add-deny必须与--rule-name及完整的二进制文件范围一起使用,后者通过重复指定--binary或显式指定--any-binary来声明。操作中必须声明端点的每个端口,例如api.example.com:443,8443:POST:/admin。使用--endpoint-path可在所选规则中区分端点;显式指定空路径表示选择未设置路径选择器的端点。网关会在持久化之前拒绝范围缺失或不匹配的操作。检查当前策略并确认预期受影响的范围;不要仅为避免被拒绝而自动从当前策略填充声明。 -
对于大范围网络变更,或
policy update无法表达的设置,使用完整 YAML 替换,包括原本需要重新声明大量现有范围的任何变更。文件系统、Landlock 和进程变更仍需重新创建沙箱:openshell policy get work-session --base | sed '1,/^---$/d' > policy.yaml使用generate-sandbox-policy技能修改策略。openshell policy set work-session --policy policy.yaml --wait -
使用
openshell policy list work-session验证。
用户无需断开连接。策略更新会热重载;--wait 会阻塞,直到沙箱确认该修订或超时。会话结束后删除沙箱:
openshell sandbox delete work-session
工作流 7:使用已附加提供方进行推理
推理采用与其他需要凭据的服务相同的提供方附加工作流。导入或选择一个允许访问提供方原生端点的配置文件,创建提供方,并仅将其附加到需要它的沙箱:
openshell provider profile import -f ./inference-provider.yaml
openshell provider create --name model-provider --type <profile-id> --credential <KEY>
openshell sandbox provider attach work-session model-provider --wait --timeout 30
openshell sandbox exec work-session -- <client-command>
应用负责管理原生基础 URL、模型、请求格式和超时。提供方就绪后启动新进程,使其继承已安装的提供方环境。若发生端点、策略、凭据绑定或迁移故障,请使用 debug-inference 技能。
对于常规的静态提供方更新,请等待更新完成,然后启动新的客户端进程以获取新引用。不要声称就绪状态会更新现有进程的环境或重新指向其旧引用。确认分离后,会撤销保留的引用,并将其从后续进程的环境中移除。
工作流 8:网关管理
列出、切换和验证网关:
openshell gateway select
openshell gateway list --output json
openshell gateway select production
openshell gateway info --name production
openshell status
openshell gateway info 会报告计算驱动程序、凭据驱动程序、网关拦截器和监督器中间件的不可变启动快照。诊断扩展版本不匹配问题时,请参考每个条目的协议版本、实现版本、支持的功能和网关要求;实现版本不能标识底层的 Docker、Kubernetes 或凭据后端。
注册或移除网关:
openshell gateway add http://127.0.0.1:8080 --local --name local
openshell gateway add https://gateway.example.com --name production
openshell gateway remove local
https:// 注册默认使用边缘身份验证。使用 gateway login 和 gateway logout 刷新或清除已存储的身份验证信息。对于 OIDC 网关,请提供 --oidc-issuer,并在需要时提供 --oidc-client-id、--oidc-audience 和 --oidc-scopes。如果 OIDC 自动刷新失败,受保护的命令会在发送 RPC 前停止,并提示用户运行 openshell gateway login <name>;openshell status 仍会分别报告网关可访问性和身份验证状态。对于远程 mTLS 网关,请使用 --remote USER@HOST 或 ssh:// 端点。
对于一次性自动化,--gateway-endpoint URL 可直接连接,不使用已存储的元数据。仅对明确可信的开发端点使用 --gateway-insecure。
检查 Kubernetes 部署:
helm -n openshell status openshell
kubectl -n openshell get deployment,statefulset,pods,svc
kubectl -n openshell logs deployment/openshell -c openshell-gateway --tail=100
kubectl -n openshell logs statefulset/openshell -c openshell-gateway --tail=100
对于 Docker、Podman 和由虚拟机提供支持的网关,请直接检查网关进程或容器日志以及所选运行时。
工作流 9:设置管理
管理沙盒级或网关全局设置:
openshell settings get work-session
openshell settings set work-session --key ocsf_json_enabled --value true
openshell settings delete work-session --key ocsf_json_enabled
openshell settings get --global --json
openshell settings set --global --key ocsf_json_enabled --value true
# OCSF schema version downgrade for SIEM compatibility (allowed: "1.1", "1.3")
openshell settings set --global --key ocsf_schema_version --value "1.1"
启用 ocsf_json_enabled 后,监督器的 stderr 中会在简写日志旁添加精简的 OCSF-JSON 记录;如果文件存储可用,也会将这些记录写入其 JSONL 文件。通过监督器的平台日志(docker logs、podman logs 或 kubectl logs)收集这些记录;openshell logs 仍用于查看简写日志。请在时间戳后匹配 OCSF-JSON 标记,并将其余部分解析为 JSON。有关传输和保留限制,请参阅已发布的 OCSF JSON 导出指南。
全局更改需要确认。仅在经过审查的自动化中使用 --yes。
policy_validation_failure_mode 是网关启动配置,并非可通过 openshell settings 修改的键。请在 gateway.toml 的 [openshell.gateway] 下设置该项,然后重启网关。安全优先的默认值为 fail_closed;retain_last_valid 则是在可用性方面作出的明确权衡。OCSF 配置事件会说明运行时验证失败后,是否仍在使用上一代配置。
工作流 10:服务访问
本地访问使用 forward,网关管理的 HTTP 端点使用 service:
# SSH-based same-port forwarding; optional bind address is accepted.
openshell forward start 127.0.0.1:8080 my-app -d
# gRPC relay to a loopback TCP service, with an optional dynamic local port.
openshell forward service my-app --target-port 8000 --local 127.0.0.1:0
# Create a sandbox with its unnamed HTTP or WebSocket service exposed.
openshell sandbox create \
--name my-app \
--from my-app:latest \
--expose 8080 \
--expose-authorization-mode bearer-passthrough \
--detach \
-- ./start-server.sh
# Expose and manage an HTTP service through the gateway.
openshell service expose my-app 8080 web \
--authorization-mode bearer-passthrough
openshell service list my-app
openshell service list my-app --output json
openshell service get my-app web
openshell service delete my-app web
使用 openshell service list --all-workspaces 查看跨工作区的平台管理员视图。沙箱名称与 --all-workspaces 不能同时使用。
sandbox create --expose PORT 会在创建请求中注册未命名端点,并让沙箱保持运行。添加 --output json 可用于自动化;结果包含一个 service_urls 映射,其中空键对应未命名端点。创建后,使用 openshell service expose 添加或更新已命名端点。
默认情况下,已公开的服务会剥离 Authorization。只有当沙箱内的应用会对自己的客户端进行身份验证时,才选择 bearer-passthrough 模式。此模式接受没有 Authorization 标头,或恰好包含一个非空 Bearer 凭证的情况,并原样转发该值。在联系应用之前,它会拒绝重复、格式错误或非 Bearer 的授权信息。应用仍负责验证令牌,且原始令牌会传递到沙箱进程,因此切勿记录该令牌。服务路由会绕过控制平面 RPC 授权,但仍使用网关现有的监听器、域名路由和 TLS 配置,包括任何客户端证书要求。完整的安全约定请参阅已发布的沙箱服务文档。
除非用户明确需要可供局域网访问的本地服务,否则优先绑定到 loopback 地址。
通过 --help 自主学习
遇到本技能未涵盖的命令或选项时:
- 先了解概况:运行
openshell --help查看所有命令组。 - 缩小范围:运行
openshell <group> --help查看子命令(例如,openshell sandbox --help)。 - 查看详情:运行
openshell <group> <cmd> --help查看标志和用法(例如,openshell sandbox create --help)。
CLI 帮助始终具有权威性。如果帮助输出与本技能冲突,请以帮助输出为准——CLI 可能已在编写本技能后更新。
示例:探索不熟悉的命令
$ openshell sandbox --help
# Shows: create, get, list, stop, start, delete, exec, connect, upload, download, ssh-config, provider, template
$ openshell sandbox upload --help
# Shows: positional arguments (name, path, dest), usage examples
配套技能
| 技能 | 适用场景 |
|---|---|
generate-sandbox-policy | 创建或修改策略 YAML 内容(网络规则、L7 检查、访问预设、端点配置和网络中间件) |
debug-openshell-cluster | 诊断网关部署、运行时或健康状态故障 |
debug-inference | 诊断附加的提供方推理、原生端点、基于主机的模型,以及从已弃用的托管端点迁移 |