@netcatty/dsh-guard 0.0.0-stage → 0.2.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/policy.json ADDED
@@ -0,0 +1,289 @@
1
+ {
2
+ "$schema": "./policy.schema.json",
3
+ "permission": {
4
+ "*": "allow",
5
+ "approvalMode": "question",
6
+ "wrappers": "allow",
7
+ "redact": true,
8
+ "sessionApprovals": false,
9
+ "denyTools": [],
10
+ "path": {
11
+ "*": "allow",
12
+ "*.env": "deny",
13
+ "*.env.*": "deny",
14
+ "*.env.example": "allow",
15
+ "*.pfx": "deny",
16
+ "*.p12": "deny",
17
+ "*/id_rsa": "deny",
18
+ "*/id_ed25519": "deny",
19
+ "*/id_ecdsa": "deny",
20
+ "*/id_dsa": "deny",
21
+ "~/.ssh/*": "deny",
22
+ "*/.ssh/*": "deny",
23
+ "~/.aws/*": "deny",
24
+ "*/.aws/*": "deny",
25
+ "~/.gnupg/*": "deny",
26
+ "*/.gnupg/*": "deny",
27
+ "~/.netrc": "deny",
28
+ "*/.netrc": "deny",
29
+ "~/.git-credentials": "deny",
30
+ "*/.git-credentials": "deny",
31
+ "~/.npmrc": "deny",
32
+ "*/.npmrc": "deny",
33
+ "~/.pypirc": "deny",
34
+ "~/.docker/config.json": "deny",
35
+ "*/.docker/config.json": "deny",
36
+ "~/.kube/config": "deny",
37
+ "*/.kube/config": "deny",
38
+ "~/.config/gh/hosts.yml": "deny",
39
+ "*/.config/gh/hosts.yml": "deny",
40
+ "~/.pi/agent/auth.json": "deny",
41
+ "~/.pi/agent/models.json": "deny",
42
+ "~/.pi/agent/models-store.json": "deny",
43
+ "~/.pi/agent/mcp.json": "deny",
44
+ "*/.dsh/.credentials.yaml": "deny"
45
+ },
46
+ "pathRead": {},
47
+ "pathWrite": {
48
+ "*": "allow",
49
+ "*.env": "deny",
50
+ "*.env.*": "deny",
51
+ "*.env.example": "allow",
52
+ "*.pfx": "deny",
53
+ "*.p12": "deny",
54
+ "*/id_rsa": "deny",
55
+ "*/id_ed25519": "deny",
56
+ "*/id_ecdsa": "deny",
57
+ "*/id_dsa": "deny",
58
+ "~/.ssh/*": "deny",
59
+ "*/.ssh/*": "deny",
60
+ "~/.aws/*": "deny",
61
+ "*/.aws/*": "deny",
62
+ "~/.gnupg/*": "deny",
63
+ "*/.gnupg/*": "deny",
64
+ "~/.netrc": "deny",
65
+ "*/.netrc": "deny",
66
+ "~/.git-credentials": "deny",
67
+ "*/.git-credentials": "deny",
68
+ "~/.npmrc": "deny",
69
+ "*/.npmrc": "deny",
70
+ "~/.pypirc": "deny",
71
+ "~/.docker/config.json": "deny",
72
+ "*/.docker/config.json": "deny",
73
+ "~/.kube/config": "deny",
74
+ "*/.kube/config": "deny",
75
+ "~/.config/gh/hosts.yml": "deny",
76
+ "*/.config/gh/hosts.yml": "deny",
77
+ "~/.pi/agent/auth.json": "deny",
78
+ "~/.pi/agent/models.json": "deny",
79
+ "~/.pi/agent/models-store.json": "deny",
80
+ "~/.pi/agent/mcp.json": "deny",
81
+ "~/.pi/agent/settings.json": "ask",
82
+ "~/.pi/agent/trust.json": "ask",
83
+ "~/.pi/agent/SYSTEM.md": "ask",
84
+ "~/.pi/agent/APPEND_SYSTEM.md": "ask",
85
+ "~/.pi/agent/npm/package.json": "ask",
86
+ "~/.pi/agent/npm/package-lock.json": "ask",
87
+ "~/.pi/agent/extensions/*": "ask"
88
+ },
89
+ "externalDirectory": {
90
+ "*": "allow"
91
+ },
92
+ "bash": {
93
+ "*": "allow",
94
+ "rm *": "ask",
95
+ "del *": "ask",
96
+ "erase *": "ask",
97
+ "rd *": "ask",
98
+ "rmdir *": "ask",
99
+ "mv *": "ask",
100
+ "ren *": "ask",
101
+ "rename *": "ask",
102
+ "format *": "ask",
103
+ "reg delete *": "ask",
104
+ "git push *": "ask",
105
+ "git reset --hard *": "ask",
106
+ "git checkout -- *": "ask",
107
+ "git restore *": "ask",
108
+ "git clean *": "ask",
109
+ "git branch -D *": "ask",
110
+ "git stash drop *": "ask",
111
+ "git stash clear *": "ask",
112
+ "curl *": "ask",
113
+ "wget *": "ask",
114
+ "iwr *": "ask",
115
+ "irm *": "ask",
116
+ "Invoke-WebRequest *": "ask",
117
+ "Invoke-RestMethod *": "ask",
118
+ "ssh *": "ask",
119
+ "scp *": "ask",
120
+ "sftp *": "ask",
121
+ "rsync *": "ask",
122
+ "npm install *": "ask",
123
+ "npm i *": "ask",
124
+ "npm ci *": "ask",
125
+ "npm update *": "ask",
126
+ "pnpm install *": "ask",
127
+ "pnpm i *": "ask",
128
+ "pnpm add *": "ask",
129
+ "pnpm update *": "ask",
130
+ "yarn install *": "ask",
131
+ "yarn add *": "ask",
132
+ "yarn up *": "ask",
133
+ "bun install *": "ask",
134
+ "bun i *": "ask",
135
+ "bun add *": "ask",
136
+ "pip install *": "ask",
137
+ "pip3 install *": "ask",
138
+ "python -m pip install *": "ask",
139
+ "python3 -m pip install *": "ask",
140
+ "py -m pip install *": "ask",
141
+ "uv add *": "ask",
142
+ "uv sync *": "ask",
143
+ "uv pip install *": "ask",
144
+ "cargo install *": "ask",
145
+ "go install *": "ask",
146
+ "gem install *": "ask",
147
+ "npx *": "ask",
148
+ "pnpm dlx *": "ask",
149
+ "yarn dlx *": "ask",
150
+ "bunx *": "ask",
151
+ "uvx *": "ask",
152
+ "pipx install *": "ask",
153
+ "pipx run *": "ask",
154
+ "npm publish *": "ask",
155
+ "pnpm publish *": "ask",
156
+ "yarn npm publish *": "ask",
157
+ "cargo publish *": "ask",
158
+ "twine upload *": "ask",
159
+ "gh pr create *": "ask",
160
+ "gh pr merge *": "ask",
161
+ "gh pr close *": "ask",
162
+ "gh release create *": "ask",
163
+ "gh release delete *": "ask",
164
+ "sudo *": "ask",
165
+ "doas *": "ask",
166
+ "runas *": "ask",
167
+ "env *": "ask",
168
+ "xargs *": "ask",
169
+ "eval *": "ask",
170
+ "cmd *": "ask",
171
+ "cmd.exe *": "ask",
172
+ "CMD *": "ask",
173
+ "CMD.exe *": "ask",
174
+ "powershell *": "ask",
175
+ "powershell.exe *": "ask",
176
+ "PowerShell *": "ask",
177
+ "PowerShell.exe *": "ask",
178
+ "pwsh *": "ask",
179
+ "pwsh.exe *": "ask",
180
+ "Pwsh *": "ask",
181
+ "Pwsh.exe *": "ask",
182
+ "bash *": "ask",
183
+ "sh *": "ask",
184
+ "dash *": "ask",
185
+ "zsh *": "ask",
186
+ "fish *": "ask",
187
+ "python *": "ask",
188
+ "python3 *": "ask",
189
+ "py *": "ask",
190
+ "node *": "ask",
191
+ "node.exe *": "ask",
192
+ "deno *": "ask",
193
+ "bun *": "ask",
194
+ "perl *": "ask",
195
+ "ruby *": "ask",
196
+ "php *": "ask",
197
+ "lua *": "ask",
198
+ "osascript *": "ask",
199
+ "mshta *": "ask",
200
+ "wscript *": "ask",
201
+ "cscript *": "ask",
202
+ "wsl *": "ask",
203
+ "npm run *": "ask",
204
+ "pnpm run *": "ask",
205
+ "yarn run *": "ask",
206
+ "bun run *": "ask",
207
+ "make *": "ask",
208
+ "gradlew *": "ask",
209
+ "gradlew.bat *": "ask",
210
+ "mvn *": "ask",
211
+ "gradle *": "ask",
212
+ "dotnet run *": "ask",
213
+ "go run *": "ask",
214
+ "cargo run *": "ask",
215
+ "terraform apply *": "ask",
216
+ "terraform destroy *": "ask",
217
+ "kubectl delete *": "ask",
218
+ "docker rm *": "ask",
219
+ "docker rmi *": "ask",
220
+ "docker system prune *": "ask",
221
+ "*.bat": "ask",
222
+ "*.cmd": "ask",
223
+ "*.ps1": "ask",
224
+ "*.vbs": "ask",
225
+ "*.sh": "ask",
226
+ "rm -rf ~*": "deny",
227
+ "rm -rf /": "deny"
228
+ },
229
+ "params": {},
230
+ "toolParams": {},
231
+ "agents": {},
232
+ "argv": [
233
+ {
234
+ "match": {
235
+ "command": [
236
+ "rm"
237
+ ],
238
+ "args": [
239
+ "-rf",
240
+ "/"
241
+ ]
242
+ },
243
+ "action": "deny"
244
+ },
245
+ {
246
+ "match": {
247
+ "pipeline": [
248
+ "curl*|*sh",
249
+ "curl*|*bash",
250
+ "wget*|*sh",
251
+ "wget*|*bash"
252
+ ]
253
+ },
254
+ "action": "deny"
255
+ },
256
+ {
257
+ "match": {
258
+ "command": [
259
+ "python",
260
+ "python3",
261
+ "node",
262
+ "perl",
263
+ "ruby",
264
+ "php",
265
+ "lua",
266
+ "bun",
267
+ "deno"
268
+ ]
269
+ },
270
+ "action": "ask"
271
+ }
272
+ ],
273
+ "opaque": "ask",
274
+ "yolo": false,
275
+ "network": [],
276
+ "projectPolicy": true,
277
+ "enforce": true,
278
+ "patternMode": "glob",
279
+ "maxGlobStars": 2,
280
+ "auditMaxBytes": 5242880,
281
+ "sessionApprovalTtlMs": 0,
282
+ "sessionApprovalMaxUses": 0,
283
+ "approvePersist": true,
284
+ "snapshots": true,
285
+ "snapshotMaxFiles": 20,
286
+ "snapshotMaxBytes": 262144,
287
+ "snapshotRetain": 100
288
+ }
289
+ }
@@ -0,0 +1,317 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/netcatty/dsh-guard/policy.schema.json",
4
+ "title": "dsh-guard policy",
5
+ "description": "allow / ask / deny gates for DeepSeek Harness tool calls. The live file is $DSH_HOME/dsh-plugins/dsh-guard/policy.json; this schema gives an editor completion and validation for it.",
6
+ "type": "object",
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string",
10
+ "description": "Editor metadata pointing at this schema. Ignored by the loader."
11
+ },
12
+ "permission": {
13
+ "$ref": "#/$defs/permission"
14
+ }
15
+ },
16
+ "$defs": {
17
+ "state": {
18
+ "type": "string",
19
+ "enum": [
20
+ "allow",
21
+ "ask",
22
+ "deny"
23
+ ],
24
+ "description": "deny > ask > allow; the most restrictive result across surfaces wins."
25
+ },
26
+ "ruleMap": {
27
+ "type": "object",
28
+ "description": "Pattern to state. Within one map the LAST matching rule wins.",
29
+ "additionalProperties": {
30
+ "oneOf": [
31
+ {
32
+ "$ref": "#/$defs/state"
33
+ },
34
+ {
35
+ "type": "null",
36
+ "description": "Remove this inherited rule."
37
+ }
38
+ ]
39
+ }
40
+ },
41
+ "toolRules": {
42
+ "type": "object",
43
+ "description": "Per-tool path rules, e.g. { \"read\": { \"*/secrets/*\": \"deny\" } }.",
44
+ "additionalProperties": {
45
+ "oneOf": [
46
+ {
47
+ "$ref": "#/$defs/ruleMap"
48
+ },
49
+ {
50
+ "type": "null",
51
+ "description": "Remove the whole inherited table."
52
+ }
53
+ ]
54
+ }
55
+ },
56
+ "paramRules": {
57
+ "type": "object",
58
+ "description": "Key pattern to value-pattern map. Keys match a full dotted path (arguments.command) or a leaf name (command).",
59
+ "additionalProperties": {
60
+ "oneOf": [
61
+ {
62
+ "$ref": "#/$defs/ruleMap"
63
+ },
64
+ {
65
+ "type": "null",
66
+ "description": "Remove the whole inherited table."
67
+ }
68
+ ]
69
+ }
70
+ },
71
+ "permission": {
72
+ "type": "object",
73
+ "properties": {
74
+ "*": {
75
+ "$ref": "#/$defs/state"
76
+ },
77
+ "path": {
78
+ "$ref": "#/$defs/ruleMap"
79
+ },
80
+ "pathRead": {
81
+ "$ref": "#/$defs/ruleMap"
82
+ },
83
+ "pathWrite": {
84
+ "$ref": "#/$defs/ruleMap"
85
+ },
86
+ "externalDirectory": {
87
+ "$ref": "#/$defs/ruleMap"
88
+ },
89
+ "bash": {
90
+ "$ref": "#/$defs/ruleMap"
91
+ },
92
+ "tools": {
93
+ "type": "object",
94
+ "description": "Tool-name glob to path-rule map. Keys match the tool name, so \"mcp__chrome-devtools__*\" governs a whole MCP server.",
95
+ "additionalProperties": {
96
+ "$ref": "#/$defs/ruleMap"
97
+ }
98
+ },
99
+ "params": {
100
+ "$ref": "#/$defs/paramRules"
101
+ },
102
+ "agents": {
103
+ "$ref": "#/$defs/ruleMap"
104
+ },
105
+ "argv": {
106
+ "type": "array",
107
+ "items": {
108
+ "type": "object",
109
+ "properties": {
110
+ "match": {
111
+ "type": "object",
112
+ "properties": {
113
+ "command": {
114
+ "type": "array",
115
+ "items": {
116
+ "type": "string"
117
+ }
118
+ },
119
+ "args": {
120
+ "type": "array",
121
+ "items": {
122
+ "type": "string"
123
+ }
124
+ },
125
+ "anyArg": {
126
+ "type": "array",
127
+ "items": {
128
+ "type": "string"
129
+ }
130
+ },
131
+ "pipeline": {
132
+ "type": "array",
133
+ "items": {
134
+ "type": "string"
135
+ }
136
+ }
137
+ },
138
+ "additionalProperties": false
139
+ },
140
+ "action": {
141
+ "$ref": "#/$defs/state"
142
+ }
143
+ },
144
+ "required": [
145
+ "match",
146
+ "action"
147
+ ],
148
+ "additionalProperties": false
149
+ }
150
+ },
151
+ "network": {
152
+ "type": "array",
153
+ "items": {
154
+ "type": "object",
155
+ "properties": {
156
+ "match": {
157
+ "type": "object",
158
+ "properties": {
159
+ "domains": {
160
+ "type": "array",
161
+ "items": {
162
+ "type": "string"
163
+ }
164
+ }
165
+ },
166
+ "additionalProperties": false
167
+ },
168
+ "action": {
169
+ "$ref": "#/$defs/state"
170
+ }
171
+ },
172
+ "required": [
173
+ "match",
174
+ "action"
175
+ ],
176
+ "additionalProperties": false
177
+ }
178
+ },
179
+ "opaque": {
180
+ "$ref": "#/$defs/state"
181
+ },
182
+ "wrappers": {
183
+ "$ref": "#/$defs/state"
184
+ },
185
+ "sandboxAware": {
186
+ "type": "boolean"
187
+ },
188
+ "yolo": {
189
+ "type": "boolean"
190
+ },
191
+ "enforce": {
192
+ "type": "boolean"
193
+ },
194
+ "audit": {
195
+ "type": "boolean"
196
+ },
197
+ "auditPath": {
198
+ "type": "string"
199
+ },
200
+ "auditMaxBytes": {
201
+ "type": "integer",
202
+ "minimum": 0
203
+ },
204
+ "projectPolicy": {
205
+ "type": "boolean"
206
+ },
207
+ "projectPolicyStrict": {
208
+ "type": "boolean"
209
+ },
210
+ "caseInsensitivePaths": {
211
+ "type": "boolean"
212
+ },
213
+ "patternMode": {
214
+ "type": "string",
215
+ "enum": [
216
+ "glob",
217
+ "regex"
218
+ ]
219
+ },
220
+ "maxGlobStars": {
221
+ "type": "integer",
222
+ "minimum": 0
223
+ },
224
+ "redact": {
225
+ "type": "boolean"
226
+ },
227
+ "sessionApprovals": {
228
+ "type": "boolean"
229
+ },
230
+ "sessionApprovalTtlMs": {
231
+ "type": "integer",
232
+ "minimum": 0
233
+ },
234
+ "sessionApprovalMaxUses": {
235
+ "type": "integer",
236
+ "minimum": 0
237
+ },
238
+ "approvePersist": {
239
+ "type": "boolean"
240
+ },
241
+ "snapshots": {
242
+ "type": "boolean"
243
+ },
244
+ "snapshotMaxFiles": {
245
+ "type": "integer",
246
+ "minimum": 0
247
+ },
248
+ "snapshotMaxBytes": {
249
+ "type": "integer",
250
+ "minimum": 0
251
+ },
252
+ "snapshotRetain": {
253
+ "type": "integer",
254
+ "minimum": 0
255
+ },
256
+ "approvalMode": {
257
+ "type": "string",
258
+ "enum": [
259
+ "approval",
260
+ "question",
261
+ "dialog"
262
+ ],
263
+ "description": "approval = DSH native, question = DSH question card with text diff, dialog = self-drawn two-column dialog."
264
+ },
265
+ "denyTools": {
266
+ "type": "array",
267
+ "items": {
268
+ "type": "string"
269
+ }
270
+ },
271
+ "projectPolicySearchUp": {
272
+ "type": "boolean"
273
+ },
274
+ "toolParams": {
275
+ "type": "object",
276
+ "description": "Tool-name glob to key/value rule map, scoped to that tool only.",
277
+ "additionalProperties": {
278
+ "type": "object",
279
+ "additionalProperties": {
280
+ "type": "object",
281
+ "additionalProperties": {
282
+ "$ref": "#/$defs/state"
283
+ }
284
+ }
285
+ }
286
+ },
287
+ "webBase": {
288
+ "type": "string",
289
+ "description": "Absolute origin used to build links in approval cards, e.g. http://100.94.19.22:3088. Empty = no link."
290
+ },
291
+ "dialogTimeoutMs": {
292
+ "type": "integer",
293
+ "minimum": 1000,
294
+ "description": "How long a self-drawn dialog waits before denying. Default 120000."
295
+ }
296
+ },
297
+ "additionalProperties": false
298
+ }
299
+ },
300
+ "anyOf": [
301
+ {
302
+ "required": [
303
+ "permission"
304
+ ]
305
+ },
306
+ {
307
+ "required": [
308
+ "path"
309
+ ]
310
+ },
311
+ {
312
+ "required": [
313
+ "bash"
314
+ ]
315
+ }
316
+ ]
317
+ }