dsh-isolation-gate 0.2.3 → 0.3.1
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/CHANGELOG.md +22 -0
- package/README.md +8 -8
- package/lib/audit.js +37 -1
- package/lib/client.js +1525 -1329
- package/lib/index.js +46 -1
- package/lib/profiles-runtime.js +164 -0
- package/lib/profiles.js +320 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -40,3 +40,25 @@
|
|
|
40
40
|
|
|
41
41
|
### 自测
|
|
42
42
|
- `npm test` → 4 个套件 · **325 断言**全绿(数据层 85 / 通道 74 / 路由 84 / 客户端 82)。
|
|
43
|
+
|
|
44
|
+
## 0.3.0 — 策略档(会话级隔离)
|
|
45
|
+
|
|
46
|
+
- 新增三种档:`blocklist`(原行为)/ `allowlist`(只允许列出目录,其余全拒)/ `sealed`(再加禁网与未知工具全拒)
|
|
47
|
+
- 档的绑定:**会话覆盖**(`state.sessionOverrides[sessionId]`,用 `exec.agent.id`)> **目录配置** `.dsh-gate.json` > 全局默认档
|
|
48
|
+
- `.dsh-gate.json` **只能加严、且只能管自己所在的子树**:写 `C:\` 不会生效(防"仓库自带配置解锁")
|
|
49
|
+
- 坏配置 / 坏状态文件 ⇒ 按 `sealed` 处理(fail-closed)
|
|
50
|
+
- 联网软禁:`web_search` / `web_fetch` 等工具 + `curl` / `npm install` / `git clone` 等命令;`npm test`、`git status` 不误判
|
|
51
|
+
- `sealed` 下认不出路径的 shell 命令一律拒
|
|
52
|
+
- 自测:新增 44 + 12 条断言,套件 6/6 通过
|
|
53
|
+
|
|
54
|
+
### 面板拆成三页(同日)
|
|
55
|
+
|
|
56
|
+
- 侧栏三项:`门禁`(对象授权)/ `门禁 · 策略`(档位与目录绑定,只读)/ `门禁 · 审计`(磁盘差异 + 审计账本)
|
|
57
|
+
- 新增宿主路由 `GET /__dsh-isolation-gate/profiles`
|
|
58
|
+
- 原单页保留为第 1 页,内容未删
|
|
59
|
+
|
|
60
|
+
- 修正:不做三个侧栏项,改回**一个「门禁」+ 页内标签**(对象与分组 / 策略档 / 审计与诊断),与「技能」面板同款交互
|
|
61
|
+
|
|
62
|
+
- 审计页新增「清空审计」:清空前整份备份到 `D:\回收站\isolation-gate-audit\access-log-<时间>.jsonl`,再截断原文件;新增 `POST /__dsh-isolation-gate/audit/clear`
|
|
63
|
+
|
|
64
|
+
- 修:`POST /audit/clear` 缺 `clearAudit` 导入(运行时 ReferenceError → 400);前端改用 `post()` 正确序列化 body
|
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/dsh-isolation-gate)
|
|
6
6
|
[](https://www.npmjs.com/package/dsh-isolation-gate)
|
|
7
|
-
[](https://github.com/huanlin-labs/dsh-isolation-gate/stargazers)
|
|
8
8
|
[](./LICENSE)
|
|
9
|
-
[](https://github.com/huanlin-labs/dsh-isolation-gate/actions/workflows/ci.yml)
|
|
10
10
|
[](https://nodejs.org)
|
|
11
11
|
|
|
12
12
|
**给 DeepSeek Harness(DSH)的隔离区授权台:默认禁、名单制、点一下生效、可审计、agent 自己能查。**
|
|
@@ -18,7 +18,7 @@ dsh plugin --profile desktop add dsh-isolation-gate
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
> ⭐ **如果它帮你少踩一次坑,点个 Star 能让更多人找到它** —— 这是这个项目唯一的「传播预算」。
|
|
21
|
-
> [](https://github.com/huanlin-labs/dsh-isolation-gate)
|
|
22
22
|
|
|
23
23
|

|
|
24
24
|
|
|
@@ -258,15 +258,15 @@ MIT · 见 [LICENSE](./LICENSE)。
|
|
|
258
258
|
- ❌ 内核级沙箱(该交给 Windows ACL / VM)
|
|
259
259
|
- ❌ 云端同步 / 账号体系(本插件只认本机状态文件)
|
|
260
260
|
|
|
261
|
-
有想法请开 [Issue](https://github.com/
|
|
261
|
+
有想法请开 [Issue](https://github.com/huanlin-labs/dsh-isolation-gate/issues),说清处境比说清方案更有用。
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
|
265
265
|
## 参与
|
|
266
266
|
|
|
267
|
-
- 装不上 / 不会配 → [Discussions](https://github.com/
|
|
268
|
-
- 有 Bug → [Bug 报告](https://github.com/
|
|
269
|
-
- 想加功能 → [功能建议](https://github.com/
|
|
267
|
+
- 装不上 / 不会配 → [Discussions](https://github.com/huanlin-labs/dsh-isolation-gate/discussions)
|
|
268
|
+
- 有 Bug → [Bug 报告](https://github.com/huanlin-labs/dsh-isolation-gate/issues/new?template=bug_report.yml)
|
|
269
|
+
- 想加功能 → [功能建议](https://github.com/huanlin-labs/dsh-isolation-gate/issues/new?template=feature_request.yml)
|
|
270
270
|
- 改代码 → [CONTRIBUTING.md](./CONTRIBUTING.md)(`npm test` 全绿即可提 PR)
|
|
271
271
|
- 安全问题 → [SECURITY.md](./SECURITY.md)(不要开公开 Issue)
|
|
272
272
|
|
|
@@ -276,4 +276,4 @@ MIT · 见 [LICENSE](./LICENSE)。
|
|
|
276
276
|
|
|
277
277
|
**点一下右上角的 ⭐ Star**。它不会改变代码,但会让更多人在搜索 `dsh plugin` 时看到它。
|
|
278
278
|
|
|
279
|
-
[](https://star-history.com/#huanlin-labs/dsh-isolation-gate&Date)
|
package/lib/audit.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 有上限(默认 500 行):超了从头截掉,避免日志无限长。
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
11
|
+
import { appendFileSync, copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { homedir } from 'node:os';
|
|
13
13
|
import { dirname, join } from 'node:path';
|
|
14
14
|
|
|
@@ -90,3 +90,39 @@ export function appendAudit(logPath, entry, options = {}) {
|
|
|
90
90
|
}
|
|
91
91
|
return { ok: true, record };
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
/** 清空前的备份落点(房规:备份一律进 D:\\回收站)。 */
|
|
95
|
+
export const DEFAULT_BACKUP_DIR = 'D:\\回收站\\isolation-gate-audit';
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 一键清空审计:先整份复制到备份目录,再截断原文件。
|
|
99
|
+
* @param {string} logPath
|
|
100
|
+
* @param {{backupDir?:string, now?:Date}} options
|
|
101
|
+
*/
|
|
102
|
+
export function clearAudit(logPath = DEFAULT_LOG_PATH, options = {}) {
|
|
103
|
+
if (!existsSync(logPath)) return { ok: true, removed: 0, backup: null };
|
|
104
|
+
let removed = 0;
|
|
105
|
+
try {
|
|
106
|
+
const text = readFileSync(logPath, 'utf8');
|
|
107
|
+
removed = text.split(/\r?\n/).filter((line) => line.trim() !== '').length;
|
|
108
|
+
} catch {
|
|
109
|
+
removed = 0;
|
|
110
|
+
}
|
|
111
|
+
const now = options.now instanceof Date ? options.now : new Date();
|
|
112
|
+
const backupDir = options.backupDir || DEFAULT_BACKUP_DIR;
|
|
113
|
+
const stampName = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
|
114
|
+
let backup = null;
|
|
115
|
+
try {
|
|
116
|
+
mkdirSync(backupDir, { recursive: true });
|
|
117
|
+
backup = join(backupDir, `access-log-${stampName}.jsonl`);
|
|
118
|
+
copyFileSync(logPath, backup);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return { ok: false, removed: 0, backup: null, error: `备份失败,未清空:${error?.message ?? String(error)}` };
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
writeFileSync(logPath, '', 'utf8');
|
|
124
|
+
} catch (error) {
|
|
125
|
+
return { ok: false, removed: 0, backup, error: `清空失败:${error?.message ?? String(error)}` };
|
|
126
|
+
}
|
|
127
|
+
return { ok: true, removed, backup };
|
|
128
|
+
}
|