@deepseek-ai/dsh-fs-sandbox 0.1.1-rc.2 → 0.1.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +102 -12
- package/README.zh.md +105 -15
- package/lib/index.js +5 -9
- package/lib/types/index.d.ts +5 -9
- package/package.json +14 -13
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/fs/fs-sandbox/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 722edc6230d972edbf31c3e987600dcd3dbf3102
|
|
6
|
+
README.zh.md: ea77acb4fe4190674a292fef90dec7f8a936d7d3
|
package/README.md
CHANGED
|
@@ -1,27 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "The sandbox-enforcing ctx.fs backend for deployments and maintainers confining model file mutations to a session workspace."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-fs-sandbox
|
|
2
7
|
|
|
3
8
|
English | [中文](README.zh.md)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`dsh-fs-sandbox` provides the sandbox-enforcing `ctx.fs` backend: it extends [`fs-local`](../fs-local/README.md) with every text-storage behavior intact and adds only a per-call mode fence on writes and edits, while reads always pass through. Under `read-only` every mutation is refused; under `workspace-write` a mutation is allowed only when the target sits under the session workspace or a platform temp root; under `danger-full-access` mutations run unfenced. Loading it instead of `fs-local`, together with the shared `ctx.sandboxPolicy` service, is the whole swap — the model-facing tools and the policy plugin are untouched. A denial is a structured `FS_SANDBOX_DENIED` error that the tools render as the familiar `[sandbox: file access denied under <mode> mode]` marker with a same-turn escalation hint. Choose it when a session's file mutations must be confined to its workspace.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
Mount this backend instead of `fs-local` when the model's file writes and edits must be confined by the session's sandbox mode, while reads stay unconfined. The fence applies per call: the tool layer resolves the calling session's mode and workspace root into the same policy the bash runner receives, so the filesystem and shell families never confine to different roots.
|
|
29
|
+
|
|
30
|
+
### Minimal composition
|
|
31
|
+
|
|
32
|
+
Load the shared policy service, then this backend, then the tools; the read-before-edit policy plugin stays optional.
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
- name: '@deepseek-ai/dsh-sandbox-policy'
|
|
36
|
+
- name: '@deepseek-ai/dsh-fs-sandbox'
|
|
37
|
+
config:
|
|
38
|
+
cwd: /absolute/path/to/workspace
|
|
39
|
+
- name: '@deepseek-ai/dsh-tool-fs'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The backend's config is the local backend's unchanged (`cwd` resolution default and `diffBasisMaxBytes` overwrite bound); the [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-fs-sandbox) is the exhaustive source.
|
|
43
|
+
|
|
44
|
+
### How the fence behaves
|
|
45
|
+
|
|
46
|
+
The effective mode comes from the calling session's override or escalation grant, falling back to the deployment default when neither is in force. `read-only` denies every mutation with the structured `FS_SANDBOX_DENIED`. `workspace-write` allows a mutation only when the target canonicalizes under the workspace root or a platform temp area (`/tmp`, `os.tmpdir()`) — the same writable set the Seatbelt profile grants. `danger-full-access` delegates unfenced.
|
|
47
|
+
|
|
48
|
+
### Observable success and failures
|
|
49
|
+
|
|
50
|
+
Reads, listings, and metadata work exactly as with `fs-local`. A denied mutation returns an `FS_SANDBOX_DENIED` error carrying the effective mode; through the tools the model sees `[sandbox: file access denied under <mode> mode]` plus the one-approved-wider retry hint, identical to bash's denials. A session with an approved escalation may retry the same operation at a strictly wider mode for that one call.
|
|
51
|
+
|
|
52
|
+
-----
|
|
6
53
|
|
|
7
|
-
|
|
54
|
+
<a id="understand-the-implementation"></a>
|
|
55
|
+
## Understand the implementation
|
|
8
56
|
|
|
9
|
-
|
|
57
|
+
<details>
|
|
58
|
+
<summary>Implementation internals — click to expand</summary>
|
|
10
59
|
|
|
11
|
-
|
|
60
|
+
This section explains the design decisions behind the sandbox backend and points at the code that realizes them; the observable behavior is fully covered in [Use this package](#use-this-package).
|
|
12
61
|
|
|
13
|
-
|
|
62
|
+
### Design concept
|
|
14
63
|
|
|
15
|
-
|
|
16
|
-
- `workspace-write` — allows a mutation only when the target canonicalizes under a writable root: the workspace root plus the platform temp areas (`/tmp`, `os.tmpdir()`), the SAME set the Seatbelt profile grants, derived from the one [`writableRoots`](../../sandbox/README.md) function so the fs fence and the bash runner cannot drift. Canonical spellings use a lexical fast path; an identity-based ancestor fallback recognizes alias-equivalent roots such as Windows long names and 8.3 names without treating unrelated prefixes as contained. The target is re-canonicalized immediately before delegating, so an ancestor symlink swapped since the tool resolved it is caught.
|
|
17
|
-
- `danger-full-access` — delegates unfenced.
|
|
64
|
+
The fence is a policy check in trusted code over a model-controlled path — not a kernel boundary. The operations are the seam's own (open, rename); only the target path is untrusted, so canonicalize-then-contain is the complete answer to this surface. Kernel-grade isolation of untrusted code stays `ctx.shell`'s job.
|
|
18
65
|
|
|
19
|
-
|
|
66
|
+
### Source map
|
|
20
67
|
|
|
21
|
-
|
|
68
|
+
| File | Role |
|
|
69
|
+
|---|---|
|
|
70
|
+
| [`src/index.ts`](src/index.ts) | `SandboxedFileSystem`: mode fence on `writeText`/`editText`, `sandboxMode` fact |
|
|
71
|
+
| [`src/containment.ts`](src/containment.ts) | Ancestor containment check with lexical fast path and identity-based fallback |
|
|
22
72
|
|
|
23
|
-
|
|
73
|
+
### How a mutation is fenced
|
|
24
74
|
|
|
75
|
+
Each mutation resolves the per-call policy (`danger-full-access` returns the caller's target untouched; `read-only` throws `FS_SANDBOX_DENIED`), then for `workspace-write` re-canonicalizes the target immediately and requires containment under one of the writable roots derived from the single `writableRoots` function — the same set the Seatbelt profile grants, so the fs fence and the bash runner cannot drift. The fresh target is the one mutated, so a symlink ancestor swapped since the tool resolved it is caught.
|
|
76
|
+
|
|
77
|
+
### Threat model
|
|
78
|
+
|
|
79
|
+
The residual resolve-to-syscall TOCTOU is narrowed by re-canonicalizing immediately before the write and is accepted for this threat model; a kernel-tight boundary would need `openat2`-class primitives whose portability cost is not worth it here. A denial is a structured `FsError`, not stderr inference — an in-process fence knows exactly what it refused.
|
|
80
|
+
|
|
81
|
+
</details>
|
|
82
|
+
|
|
83
|
+
-----
|
|
84
|
+
|
|
85
|
+
<a id="further-exploration"></a>
|
|
86
|
+
## Further Exploration
|
|
87
|
+
|
|
88
|
+
Read these pages when the package-level contract is not enough. They move from this backend to the shared policy home and the confinement decisions behind it.
|
|
89
|
+
|
|
90
|
+
- [Filesystem subsystem](../../../docs/subsystems/filesystem.md) — exhaustive provider contract, policy events, and error taxonomy.
|
|
91
|
+
- [dsh-fs](../fs/README.md) — the `ctx.fs` contract this backend implements.
|
|
92
|
+
- [fs-local](../fs-local/README.md) — the local backend this one extends.
|
|
93
|
+
- [sandbox-policy](../../sandbox/sandbox-policy/README.md) — the shared per-session policy resolver this backend requires.
|
|
94
|
+
- [Process sandbox subsystem](../../../docs/subsystems/sandbox.md) — modes, per-call policy, and fail-closed errors.
|
|
95
|
+
- [Cross-family fs sandbox decision](../../../.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.md) — the shared mode fence and its escalation choreography.
|
|
96
|
+
|
|
97
|
+
-----
|
|
98
|
+
|
|
99
|
+
<a id="model-experience"></a>
|
|
25
100
|
## Model Experience
|
|
26
101
|
|
|
27
102
|
### Filesystem policy and refusals
|
|
@@ -40,6 +115,21 @@ A standing-policy change appends an owner-rendered superseding runtime-context s
|
|
|
40
115
|
|
|
41
116
|
## Known Limitations and Deferred Work
|
|
42
117
|
|
|
118
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
These limits define when the sandbox backend is a poor fit or needs special operational care. They are current package constraints, not a general sandbox comparison or a task backlog.
|
|
122
|
+
|
|
43
123
|
- **A policy fence, not a kernel boundary** — the check is trusted code over a model-controlled path, so the residual resolve-to-syscall TOCTOU is narrowed (by the in-place re-canonicalization) but not eliminated; adversarial host processes are out of scope. Kernel-grade isolation of untrusted code stays `ctx.shell`'s.
|
|
44
124
|
- **Fence-vs-runner parity is derived from one owner** — the writable set comes from `writableRoots`, shared with the Seatbelt profile; a runner profile that defines its writable set elsewhere would drift.
|
|
45
125
|
- **Requires `ctx.sandboxPolicy`** — tools use it to resolve each session policy and the backend uses it for agentless-call fallbacks; the backend does not confine without it composed.
|
|
126
|
+
|
|
127
|
+
<a id="dev-note"></a>
|
|
128
|
+
### Dev Note
|
|
129
|
+
|
|
130
|
+
<details>
|
|
131
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
132
|
+
|
|
133
|
+
None.
|
|
134
|
+
|
|
135
|
+
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,45 +1,135 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "强制沙箱的 `ctx.fs` 后端:面向把模型文件变更限制在会话工作区内的部署方与维护者。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-fs-sandbox
|
|
2
7
|
|
|
3
8
|
[English](README.md) | 中文
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`dsh-fs-sandbox` 提供强制沙箱的 `ctx.fs` 后端:它扩展 [`fs-local`](../fs-local/README.zh.md),完整保留全部文本存储行为,只为写入与编辑增加按调用的模式围栏,读取始终直接通过。`read-only` 下所有变更都会被拒绝;`workspace-write` 下只有当目标位于会话工作区或平台临时根目录之下时才允许变更;`danger-full-access` 下变更不加围栏。加载它来替代 `fs-local`,并同时加载共享的 `ctx.sandboxPolicy` 服务,即可完成替换——面向模型的工具与策略插件无需改动。拒绝是结构化 `FS_SANDBOX_DENIED` 错误,工具会把它渲染为熟悉的 `[sandbox: file access denied under <mode> mode]` 标记并附同轮次升级提示。当会话的文件变更必须限制在其工作区内时选择它。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
当模型的文件写入与编辑必须受会话沙箱模式约束、而读取保持不受约束时,挂载此后端以替代 `fs-local`。围栏按调用生效:工具层把调用会话的模式与工作区根目录解析为与 bash runner 收到的相同策略,因此文件系统与 shell 两个能力族绝不会约束到不同根目录。
|
|
29
|
+
|
|
30
|
+
### 最小组合
|
|
31
|
+
|
|
32
|
+
先加载共享策略服务,再加载此后端,最后加载工具;编辑前读取策略插件仍为可选。
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
- name: '@deepseek-ai/dsh-sandbox-policy'
|
|
36
|
+
- name: '@deepseek-ai/dsh-fs-sandbox'
|
|
37
|
+
config:
|
|
38
|
+
cwd: /absolute/path/to/workspace
|
|
39
|
+
- name: '@deepseek-ai/dsh-tool-fs'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
后端的配置与本地后端完全相同(`cwd` 解析默认值与 `diffBasisMaxBytes` 覆写上限);[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-fs-sandbox)是穷尽式真源。
|
|
43
|
+
|
|
44
|
+
### 围栏行为
|
|
45
|
+
|
|
46
|
+
有效模式来自调用会话的覆盖值或升级授权,两者都未生效时才回退到部署默认值。`read-only` 以结构化 `FS_SANDBOX_DENIED` 拒绝所有变更。`workspace-write` 只允许目标规范化后位于工作区根目录或平台临时区域(`/tmp`、`os.tmpdir()`)之下的变更——与 Seatbelt profile 授权的可写集合相同。`danger-full-access` 不加围栏直接委托。
|
|
47
|
+
|
|
48
|
+
### 可观察的成功与失败
|
|
49
|
+
|
|
50
|
+
读取、列出与元数据操作与 `fs-local` 完全一致。被拒绝的变更返回携带有效模式的 `FS_SANDBOX_DENIED` 错误;经工具,模型会看到 `[sandbox: file access denied under <mode> mode]` 及唯一一次获批更宽权限的重试提示,与 bash 的拒绝完全相同。获得批准升级的会话可以在该次调用中以严格更宽的模式重试同一操作。
|
|
51
|
+
|
|
52
|
+
-----
|
|
6
53
|
|
|
7
|
-
|
|
54
|
+
<a id="understand-the-implementation"></a>
|
|
55
|
+
## 理解实现
|
|
8
56
|
|
|
9
|
-
|
|
57
|
+
<details>
|
|
58
|
+
<summary>实现细节——点击展开</summary>
|
|
10
59
|
|
|
11
|
-
|
|
60
|
+
本节解释沙箱后端背后的设计决策,并指出实现它们的代码位置;可观察行为已在[使用本包](#use-this-package)中完整说明。
|
|
12
61
|
|
|
13
|
-
|
|
62
|
+
### 设计理念
|
|
14
63
|
|
|
15
|
-
|
|
16
|
-
- `workspace-write`:只有目标规范化后位于可写根目录下,才允许变更。可写根包括工作区根目录和平台临时区域(`/tmp`、`os.tmpdir()`),与 Seatbelt profile 授权的集合相同;该集合由唯一的 [`writableRoots`](../../sandbox/README.zh.md) 函数派生,使 fs 围栏与 bash runner 不会漂移。规范拼写使用词法快速路径;基于身份的祖先回退可以识别 Windows 长名称和 8.3 名称等别名等价根目录,而不会把无关前缀视为包含关系。委托前会立即重新规范化目标,因此工具解析后被替换的祖先符号链接也会被发现;
|
|
17
|
-
- `danger-full-access`:不加围栏直接委托。
|
|
64
|
+
围栏是在可信代码中检查模型控制路径的策略,而非内核边界。操作属于 seam 自身(open、rename),只有目标路径不可信,因此「规范化后检查包含关系」就是该接口的完整答案。不可信代码的内核级隔离仍由 `ctx.shell` 负责。
|
|
18
65
|
|
|
19
|
-
|
|
66
|
+
### 源码地图
|
|
20
67
|
|
|
21
|
-
|
|
68
|
+
| 文件 | 职责 |
|
|
69
|
+
|---|---|
|
|
70
|
+
| [`src/index.ts`](src/index.ts) | `SandboxedFileSystem`:`writeText`/`editText` 上的模式围栏、`sandboxMode` 事实 |
|
|
71
|
+
| [`src/containment.ts`](src/containment.ts) | 祖先包含检查,带词法快速路径与基于身份的兜底 |
|
|
22
72
|
|
|
23
|
-
|
|
73
|
+
### 变更如何被围栏
|
|
24
74
|
|
|
75
|
+
每次变更先解析按调用策略(`danger-full-access` 原样返回调用方目标;`read-only` 抛出 `FS_SANDBOX_DENIED`),`workspace-write` 则立即重新规范化目标,并要求它位于由唯一的 `writableRoots` 函数派生的某个可写根之下——与 Seatbelt profile 授权的集合相同,因此 fs 围栏与 bash runner 不会漂移。被变更的正是这个新目标,因此工具解析后被替换的符号链接祖先也会被发现。
|
|
76
|
+
|
|
77
|
+
### 威胁模型
|
|
78
|
+
|
|
79
|
+
解析到系统调用之间残留的 TOCTOU 通过写入前立即重新规范化来缩小,并为该威胁模型所接受;内核严密边界需要 `openat2` 一类原语,其可移植性成本在此不值。拒绝是结构化 `FsError`,而不是 stderr 推断——进程内围栏准确知道自己拒绝了什么。
|
|
80
|
+
|
|
81
|
+
</details>
|
|
82
|
+
|
|
83
|
+
-----
|
|
84
|
+
|
|
85
|
+
<a id="further-exploration"></a>
|
|
86
|
+
## 进一步探索
|
|
87
|
+
|
|
88
|
+
当包级约定不够用时阅读以下页面。它们从本后端逐步进入共享策略归属及其背后的隔离决策。
|
|
89
|
+
|
|
90
|
+
- [文件系统子系统](../../../docs/subsystems/filesystem.zh.md)——穷尽式提供方约定、策略事件与错误分类体系。
|
|
91
|
+
- [dsh-fs](../fs/README.zh.md)——本后端实现的 `ctx.fs` 约定。
|
|
92
|
+
- [fs-local](../fs-local/README.zh.md)——本后端扩展的本地后端。
|
|
93
|
+
- [sandbox-policy](../../sandbox/sandbox-policy/README.zh.md)——本后端所需的共享逐会话策略解析器。
|
|
94
|
+
- [进程沙箱子系统](../../../docs/subsystems/sandbox.zh.md)——模式、逐调用策略与故障关闭错误。
|
|
95
|
+
- [跨能力族 fs 沙箱决策](../../../.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.zh.md)——共享模式围栏及其升级编排。
|
|
96
|
+
|
|
97
|
+
-----
|
|
98
|
+
|
|
99
|
+
<a id="model-experience"></a>
|
|
25
100
|
## 模型体验
|
|
26
101
|
|
|
27
102
|
### 文件系统策略与拒绝
|
|
28
103
|
|
|
29
104
|
#### 模型看到的内容
|
|
30
105
|
|
|
31
|
-
|
|
106
|
+
策略归属方贡献与具体能力无关的 `sandbox:policy` 上下文。作为间接影响,`dsh-tool-fs` 会把本后端的 `FS_SANDBOX_DENIED` 拒绝渲染为 `[sandbox: file access denied under <mode> mode]` 标记和同轮次升级提示。
|
|
32
107
|
|
|
33
108
|
#### Token 影响
|
|
34
109
|
|
|
35
|
-
|
|
110
|
+
该后端挂载期间,当前策略条款会增加一条简短的运行时上下文消息;拒绝则会把有界标记与升级提示追加到对话历史。
|
|
36
111
|
|
|
37
112
|
#### KV Cache 影响
|
|
38
113
|
|
|
39
114
|
常驻策略发生变化时,会在保留的历史之后追加一份由归属方渲染、取代先前状态的运行时上下文快照;操作结果保持仅追加。
|
|
40
115
|
|
|
41
|
-
##
|
|
116
|
+
## 已知限制与延期工作
|
|
117
|
+
|
|
118
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
这些限制说明沙箱后端何时不合适,或何时需要特别的运维注意。它们是当前包约束,不是通用沙箱对比或任务积压。
|
|
42
122
|
|
|
43
123
|
- **策略围栏,而非内核边界**:该检查是可信代码处理模型控制的路径,因此解析到系统调用之间残留的 TOCTOU 会被原位重新规范化缩小,但不会消除;对抗性宿主进程不在范围内。不可信代码的内核级隔离仍属于 `ctx.shell`。
|
|
44
124
|
- **围栏与 runner 的一致性由单一所有方派生**:可写集合来自 `writableRoots`,该函数与 Seatbelt profile 共享;在其他位置定义可写集合的 runner profile 会发生漂移。
|
|
45
125
|
- **要求 `ctx.sandboxPolicy`**:工具使用它解析每个会话策略,后端用它处理无 agent(智能体)调用的回退;未组合该服务时,后端不会实施约束。
|
|
126
|
+
|
|
127
|
+
<a id="dev-note"></a>
|
|
128
|
+
### 开发备注
|
|
129
|
+
|
|
130
|
+
<details>
|
|
131
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
132
|
+
|
|
133
|
+
无。
|
|
134
|
+
|
|
135
|
+
</details>
|
package/lib/index.js
CHANGED
|
@@ -77,22 +77,18 @@ async function isPathUnder(path, root, caseSensitive = process.platform !== "win
|
|
|
77
77
|
* The fence is a policy check in TRUSTED code over a MODEL-CONTROLLED path,
|
|
78
78
|
* NOT a kernel boundary — the operations are the seam's own (open, rename),
|
|
79
79
|
* and only the target path is untrusted, so canonicalize-then-contain is the
|
|
80
|
-
* complete answer to this surface.
|
|
81
|
-
* stays `ctx.shell`'s job
|
|
82
|
-
*
|
|
80
|
+
* complete answer to this surface. This is containment, not a security
|
|
81
|
+
* boundary; kernel-grade isolation of untrusted CODE stays `ctx.shell`'s job
|
|
82
|
+
* (`@deepseek-ai/dsh-bash-sandbox`). The residual
|
|
83
83
|
* TOCTOU (an ancestor symlink swapped between the containment re-check and the
|
|
84
84
|
* syscall) is narrowed by re-canonicalizing immediately before delegating and
|
|
85
85
|
* is accepted for this threat model.
|
|
86
86
|
*
|
|
87
87
|
* Per-call policy: `read-only` denies every mutation; `workspace-write` allows
|
|
88
88
|
* a mutation only when the target canonicalizes under the policy's workspace
|
|
89
|
-
* root or a platform temp area
|
|
90
|
-
* derived from the one `writableRoots` function so bash and fs cannot drift);
|
|
89
|
+
* root or a platform temp area from the shared `writableRoots` policy;
|
|
91
90
|
* `danger-full-access` delegates unfenced. A denial throws the structured
|
|
92
|
-
* `FS_SANDBOX_DENIED
|
|
93
|
-
* stderr), because an in-process fence knows exactly what it refused. The
|
|
94
|
-
* escalation retry lives in the tool layer (`@deepseek-ai/dsh-tool-fs`),
|
|
95
|
-
* exactly as bash's does.
|
|
91
|
+
* `FS_SANDBOX_DENIED`.
|
|
96
92
|
*
|
|
97
93
|
* @module @deepseek-ai/dsh-fs-sandbox
|
|
98
94
|
*/
|
package/lib/types/index.d.ts
CHANGED
|
@@ -10,22 +10,18 @@
|
|
|
10
10
|
* The fence is a policy check in TRUSTED code over a MODEL-CONTROLLED path,
|
|
11
11
|
* NOT a kernel boundary — the operations are the seam's own (open, rename),
|
|
12
12
|
* and only the target path is untrusted, so canonicalize-then-contain is the
|
|
13
|
-
* complete answer to this surface.
|
|
14
|
-
* stays `ctx.shell`'s job
|
|
15
|
-
*
|
|
13
|
+
* complete answer to this surface. This is containment, not a security
|
|
14
|
+
* boundary; kernel-grade isolation of untrusted CODE stays `ctx.shell`'s job
|
|
15
|
+
* (`@deepseek-ai/dsh-bash-sandbox`). The residual
|
|
16
16
|
* TOCTOU (an ancestor symlink swapped between the containment re-check and the
|
|
17
17
|
* syscall) is narrowed by re-canonicalizing immediately before delegating and
|
|
18
18
|
* is accepted for this threat model.
|
|
19
19
|
*
|
|
20
20
|
* Per-call policy: `read-only` denies every mutation; `workspace-write` allows
|
|
21
21
|
* a mutation only when the target canonicalizes under the policy's workspace
|
|
22
|
-
* root or a platform temp area
|
|
23
|
-
* derived from the one `writableRoots` function so bash and fs cannot drift);
|
|
22
|
+
* root or a platform temp area from the shared `writableRoots` policy;
|
|
24
23
|
* `danger-full-access` delegates unfenced. A denial throws the structured
|
|
25
|
-
* `FS_SANDBOX_DENIED
|
|
26
|
-
* stderr), because an in-process fence knows exactly what it refused. The
|
|
27
|
-
* escalation retry lives in the tool layer (`@deepseek-ai/dsh-tool-fs`),
|
|
28
|
-
* exactly as bash's does.
|
|
24
|
+
* `FS_SANDBOX_DENIED`.
|
|
29
25
|
*
|
|
30
26
|
* @module @deepseek-ai/dsh-fs-sandbox
|
|
31
27
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-fs-sandbox",
|
|
3
3
|
"description": "Sandbox-enforcing implementation of the DeepSeek Harness filesystem seam: fences write/edit by the per-call sandbox mode (read-only denies mutation, workspace-write contains it to the workspace + temp roots) while reads pass through",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,19 +32,20 @@
|
|
|
32
32
|
],
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@deepseek-ai/dsh-fs": "^0.1.
|
|
36
|
-
"@deepseek-ai/dsh-
|
|
37
|
-
"@deepseek-ai/dsh-
|
|
38
|
-
"@deepseek-ai/dsh-sandbox": "^0.1.
|
|
39
|
-
"@deepseek-ai/
|
|
40
|
-
"@deepseek-ai/
|
|
35
|
+
"@deepseek-ai/dsh-fs-local": "^0.1.2-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.2",
|
|
38
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.2",
|
|
39
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
40
|
+
"@deepseek-ai/dsh-fs": "^0.1.2-alpha.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@deepseek-ai/dsh-fs": "^0.1.
|
|
44
|
-
"@deepseek-ai/dsh-
|
|
45
|
-
"@deepseek-ai/dsh-
|
|
46
|
-
"@deepseek-ai/
|
|
47
|
-
"@deepseek-ai/dsh-
|
|
48
|
-
"@deepseek-ai/
|
|
43
|
+
"@deepseek-ai/dsh-fs": "^0.1.2-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-fs-local": "^0.1.2-alpha.2",
|
|
45
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
46
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.2",
|
|
47
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.2",
|
|
48
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
49
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.2"
|
|
49
50
|
}
|
|
50
51
|
}
|