返回 CodeWhale
page.tsx
根目录 / web / app / [locale] / docs / sandbox / page.tsx
1 import { buildPageMetadata } from "@/lib/page-meta";
2
3 export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
4 const { locale } = await params;
5 const isZh = locale === "zh";
6 return buildPageMetadata({
7 path: "/docs/sandbox",
8 locale,
9 title: isZh ? "沙箱与审批 · Codewhale 文档" : "Sandbox & Approval · Codewhale Docs",
10 description: isZh
11 ? "macOS Seatbelt、Linux 可选 bubblewrap、平台缺口和审批策略的真实边界。"
12 : "The honest boundary: macOS Seatbelt, opt-in Linux bubblewrap, platform gaps, and approval policy.",
13 });
14 }
15
16 export default async function SandboxPage({ params }: { params: Promise<{ locale: string }> }) {
17 const { locale } = await params;
18 const isZh = locale === "zh";
19 const bodyClass = isZh
20 ? "text-ink-soft leading-[1.9] tracking-wide"
21 : "text-ink-soft leading-relaxed";
22 const platforms = isZh
23 ? [
24 {
25 name: "macOS · Seatbelt",
26 detail:
27 "Codewhale 探测 /usr/bin/sandbox-exec;探测成功且策略要求沙箱时,子命令会被包上运行时生成的 Seatbelt profile:广泛的文件系统读取、按策略限制的写入、仅在策略允许时放行网络。探测失败则如实报告无 OS 沙箱。",
28 },
29 {
30 name: "Linux · 可选 bubblewrap",
31 detail:
32 "Linux 命令沙箱是显式启用的:设置 prefer_bwrap = true,且 /usr/bin/bwrap 是可执行文件时才选用。子命令得到只读根视图,writable 挂载来自解析后的策略;默认隔离网络命名空间,仅在策略开启 network_access 时加 --share-net。未启用或未安装 bwrap 时报告 none。",
33 },
34 {
35 name: "Windows · 无 OS 沙箱",
36 detail:
37 "Windows 命令路径目前报告无 OS 沙箱。主机权限和审批策略仍然有效,但它们不是 Codewhale 的 OS 命令沙箱。",
38 },
39 {
40 name: "外部 OpenSandbox 执行",
41 detail:
42 "配置 sandbox_backend = \"opensandbox\" 后,shell 执行会发往配置的 OpenSandbox 兼容 HTTP 端点,而不是启动本地子进程。隔离保证属于所配置的服务及其运营者。",
43 },
44 ]
45 : [
46 {
47 name: "macOS · Seatbelt",
48 detail:
49 "Codewhale probes /usr/bin/sandbox-exec; when the probe succeeds and the policy requests a sandbox, the child command is wrapped in a generated Seatbelt profile: broad filesystem reads, policy-limited writes, and network only when the policy enables it. A failed probe is reported honestly as no OS sandbox.",
50 },
51 {
52 name: "Linux · opt-in bubblewrap",
53 detail:
54 "Linux command sandboxing is opt-in: set prefer_bwrap = true and keep /usr/bin/bwrap executable. The child gets a read-only root view with writable mounts derived from the resolved policy; the network namespace is isolated by default and --share-net is added only when the policy enables network access. Without the opt-in, Codewhale reports none.",
55 },
56 {
57 name: "Windows · no OS sandbox",
58 detail:
59 "The Windows command path currently reports no OS sandbox. Host permissions and approval policy still apply, but they are not a Codewhale OS command sandbox.",
60 },
61 {
62 name: "External OpenSandbox execution",
63 detail:
64 "With sandbox_backend = \"opensandbox\", shell execution is sent to the configured OpenSandbox-compatible HTTP endpoint instead of starting a local child. Isolation guarantees belong to the configured service and its operator.",
65 },
66 ];
67
68 return (
69 <section className="space-y-10">
70 <section id="overview" className="scroll-mt-32">
71 <h2 className="font-display text-3xl mb-1">{isZh ? "沙箱与审批" : "Sandbox & Approval"}</h2>
72 <p className={`${bodyClass} mt-3`}>
73 {isZh
74 ? "Codewhale 可以启动由模型提出的 shell 命令。审批策略、感知工作区的文件工具和操作系统命令包装器是三个独立的控制:一次审批不是沙箱,选择 workspace-write 也不代表当前平台有可用的 OS 包装器。本页只描述已经接入命令执行路径的行为。"
75 : "Codewhale can launch shell commands proposed by a model. Approval policy, workspace-aware tools, and an operating-system command wrapper are separate controls: an approval is not a sandbox, and selecting workspace-write does not prove the current platform has an OS wrapper available. This page describes only behavior wired into the command execution path."}
76 </p>
77 <div className="hairline-t mt-6">
78 {platforms.map((row) => (
79 <section key={row.name} className="py-4 hairline-b">
80 <h3 className="font-display text-lg">{row.name}</h3>
81 <p className={`${bodyClass} mt-1 text-sm`}>{row.detail}</p>
82 </section>
83 ))}
84 </div>
85 </section>
86
87 <section id="policies" className="scroll-mt-32">
88 <h2 className="font-display text-2xl mb-1">{isZh ? "策略与回退" : "Policies and fallbacks"}</h2>
89 <p className={`${bodyClass} mt-3`}>
90 {isZh ? (
91 <>
92 本地 <code className="inline">sandbox_mode</code> 取值为{" "}
93 <code className="inline">read-only</code>、<code className="inline">workspace-write</code>、
94 <code className="inline">danger-full-access</code> 或{" "}
95 <code className="inline">external-sandbox</code>。前两者只在选中且可用的 Seatbelt 或
96 bubblewrap 包装器下被强制执行;<code className="inline">danger-full-access</code>{" "}
97 有意绕过本地 OS 包装器;<code className="inline">external-sandbox</code>{" "}
98 声明执行已被外部隔离。没有选中包装器时,shell 命令在没有 Codewhale OS 隔离的情况下运行——审批规则和感知工作区的原生文件工具仍是独立的控制。
99 </>
100 ) : (
101 <>
102 The local <code className="inline">sandbox_mode</code> values are{" "}
103 <code className="inline">read-only</code>, <code className="inline">workspace-write</code>,{" "}
104 <code className="inline">danger-full-access</code>, and{" "}
105 <code className="inline">external-sandbox</code>. The first two are enforced by Seatbelt or
106 bubblewrap only when that wrapper is selected and available;{" "}
107 <code className="inline">danger-full-access</code> deliberately bypasses the local OS
108 wrapper; <code className="inline">external-sandbox</code> declares that execution is already
109 externally isolated. When no wrapper is selected, the shell command runs without Codewhale
110 OS isolation — approval rules and workspace-aware native file tools remain separate controls.
111 </>
112 )}
113 </p>
114 <pre className="code-block mt-4">{`# config.toml
115 sandbox_mode = "workspace-write"
116 prefer_bwrap = true # Linux opt-in
117
118 # Canonical environment overrides
119 CODEWHALE_SANDBOX_MODE
120 CODEWHALE_SANDBOX_BACKEND
121 CODEWHALE_SANDBOX_URL
122 CODEWHALE_SANDBOX_API_KEY`}</pre>
123 </section>
124
125 <section id="diagnostics" className="scroll-mt-32">
126 <h2 className="font-display text-2xl mb-1">{isZh ? "诊断与限制" : "Diagnostics and limits"}</h2>
127 <p className={`${bodyClass} mt-3`}>
128 {isZh
129 ? "codewhale setup --status、codewhale doctor、codewhale doctor --json 和 diagnostics 工具会报告应用 bubblewrap 偏好后本地可用的包装器。拒绝归因是保守的:子命令的通用 Permission denied 本身并不能证明是 Codewhale 的沙箱拦截了它,未沙箱化的命令失败永远不会被标记为沙箱拒绝。"
130 : "codewhale setup --status, codewhale doctor, codewhale doctor --json, and the diagnostics tool report the locally available wrapper after applying the resolved bubblewrap preference. Denial attribution is intentionally conservative: a child command's generic Permission denied is not by itself proof that Codewhale's sandbox blocked it, and unsandboxed command failures are never labeled sandbox denials."}
131 </p>
132 <p className={`${bodyClass} mt-3`}>
133 {isZh
134 ? "限制同样如实说明:可用性在启动前检查,选中的包装器仍可能因主机策略、容器限制或竞态而失败;bubblewrap 会忽略缺失或不是目录的可写根;没有任何沙箱能防御内核漏洞或所有资源耗尽与侧信道攻击。"
135 : "The limitations are stated just as plainly: availability is checked before launch, yet the selected wrapper can still fail because of host policy, container restrictions, or a race after the probe; bubblewrap ignores a configured writable root that is missing or not a directory; and no sandbox protects against kernel vulnerabilities or all resource-exhaustion and side-channel attacks."}
136 </p>
137 </section>
138
139 <section id="source" className="hairline-t pt-8">
140 <p className="text-sm text-ink-mute">
141 {isZh
142 ? "来源文档:docs/SANDBOX.md · 更新时请同步修改 docs-map.ts。"
143 : "Source document: docs/SANDBOX.md · Update docs-map.ts when changing."}
144 </p>
145 </section>
146 </section>
147 );
148 }
149
149 lines Plain Text