toby-bridges/api-relay-audit
toby-bridges/api-relay-audit从 DeepSeek Harness 对 AI API 中转站和 LLM 代理运行本地安全审计,生成 Markdown 报告,覆盖提示词注入、模型替换信号、工具调用改写、错误泄漏、流完整性和按 profile 启用的 Web3 风险。
自动审批权限守卫:介于 workspace-write 与 danger-full-access 之间的中间档——信任目录内安全操作自动放行,危险操作一律人工确认;11 个分类开关可调,自带审计记录。
Auto-approval permission guard for DeepSeek Harness (dsh) web — the "middle tier" between workspace-write (asks too often) and danger-full-access (too open). Common operations like cross-directory edits, git commit/merge and builds run without approval prompts; destructive operations (deletes, disk ops, privilege escalation, curl|sh) always ask for human confirmation.
Unofficial project: independently developed and maintained by a community member, not an official DeepSeek product.
⚠️ DISCONTINUED (2026-10-01)
DSH 0.2 ships a built-in per-call auto approval (
@deepseek-ai/dsh-experimental-auto-review— theAuto reviewentry in the permission selector, shipped with the app since 0.2.0-rc.2) that covers this plugin's core scenario. The author has moved to the official option, so this plugin is no longer maintained.
- Last release:
v0.4.2(verified on DSH 0.2.0-rc.2). No further fixes or compatibility work.- It has been removed from the author's two profiles (desktop / web). You may keep installing it, but compatibility going forward is at your own risk.
- How they differ: this plugin is a deterministic, zero-token rule set (command classifier + trust directories; works on any host, incl. headless / CLI), whereas the official Auto review is a per-call LLM review (needs the Web layer, costs one extra model request per tool call, marked experimental by the vendor).
- Thanks to everyone who used it.


~/.dsh/perm-guard.json, survives restarts. Zero host dependencies.# DSH 0.1.7 and later:
dsh plugin --profile web add "github:a903067276-rgb/dsh-perm-guard#main"
# DSH 0.1.5 and older (this release needs 0.1.7+):
# dsh plugin --profile web add "github:a903067276-rgb/dsh-perm-guard#v0.2.10"
Then restart dsh web. Update: dsh plugin --profile web update dsh-perm-guard, restart.
Manual install fallback: see docs/install.md.
| Category | Standard | Aggressive |
|---|---|---|
| File edit (write/edit/cp/mv/mkdir) | auto (in trust dirs) | auto |
| Git local (commit/merge/rebase/checkout) | auto | auto |
| Build / test / install | auto | auto |
| Read-only queries (ls/cat/grep/git status) | auto | auto |
| Delete (rm, reset --hard, clean -fd) | ask | ask |
| Protected paths (.ssh/.aws/secrets/.env/system dirs) | ask | ask |
| Privilege (sudo, services, global installs) | ask | ask |
| Network download-execute (curl|sh) | ask | ask |
| Git push | ask | auto |
| Publish / deploy | ask | auto |
| Disk / partition / device | ask | ask |
Switching modes resets the category switches to that mode's defaults (adjustable afterwards).
rm, rm -rf / or ~ (circuit breaker, even with $(...) variants), git reset --hard, git clean -fd, Remove-Itemdd writing devices, mkfs/fdisk/wipefs/diskutil erase, writes to /dev/sudo/su, service management (launchctl/systemctl), recursive chmod/chown on / or ~curl|sh, wget|shgit push --force / -f (rewrites history)| Platform | Status |
|---|---|
| macOS | ✅ development environment |
| Linux | ⚠️ expected to work |
| Windows | ✅ adapted & field-tested (win32 path handling + PowerShell vocabulary, 2026-08-24) |
C:\…, C:/…, /c/… (MSYS/Git-Bash) — normalized to C:/… on save; invalid entries are reported back by the UI instead of being silently dropped.Select-Object etc.) count as read-only; Invoke-RestMethod/iwr map to network; Stop-Process, reg add, schtasks /create etc. map to privilege (always human-confirmed); vssadmin delete shadows, bcdedit, diskpart are hard red lines.gh CLI read-only subcommands (view/list/status…) auto-approve; write operations fall back to human confirmation.sandbox_permissions) raise exactly one confirmation card instead of two.key+id registration to satisfy both rc.6 (id) and rc.7+ (key); verified locally on rc.6/rc.8/0.1.1-rc.2/0.1.5-rc.1, not guaranteed on every DSH version):
main (default) or v0.2.9 and newer.v0.2.7 (dsh plugin add github:a903067276-rgb/dsh-perm-guard#v0.2.7); DSH 0.1.0-rc.6 → frozen rc6-compat tag (no maintenance).v0.2.8: it imports the removed settingsNamespace export and makes the whole plugin tree fail to load (the web app will not boot). Use main / v0.2.9+ instead.pnpm in PATH — dsh plugin is a pnpm forwarder (needed for install/update)
v0.4.2): it declares peerDependencies: {"@deepseek-ai/dsh": "^0.1.7-rc.1 || ^0.2.0-rc.1"}, so a mismatched host refuses to load it with an explicit reason instead of failing quietly. Settings move to the 0.1.7 model (plugin Config, live-editable .volatile() fields), so changes apply without a restart.^0.1.7-rc.1 || ^0.2.0-rc.1) and dsh.compatibility.dshReleases adds "0.2.0-rc.1": "compatible" — verified on a real 0.2.0-rc.1 host and a shadow instance. Since 0.2 the host gates profile bundles on peer compatibility and skips the whole bundle when the declared range misses the running host, so this range is what keeps the plugin loading.v0.2.10: that line keeps the old behavior and uses no 0.1.7-only API.v0.2.10) are not supported on 0.1.7 — disabling and re-enabling it from the plugin manager throws duplicate route, and configuration edits no longer apply. Upgrade the plugin together with the host.allowed-once (~13ms, no popup), risky ones are forwarded to the human prompt.callId; DSH 0.1.5 removed Session.events, so it now reads the public snapshotEvents() (older hosts keep the events path). When neither is available it always falls back to the human prompt (safe default, never auto-allow).tools/pre-execute) — dangerous categories are intercepted before the sandbox even rejects them.approval/asked + approval/decided event pair.curl|sh) in command text, not block other network traffic."Remove-Item", or scripts embedding rule sources) are conservatively intercepted — expected, rare in practice.approval/asked + approval/decided event pair.bash, pwsh (PowerShell), and the write/edit file tools. MCP tools and other read-only tools have no approval mechanism and are unaffected.a && rm -rf x): pure-word chains are split and evaluated per subcommand, taking the strictest result; chains containing variables/redirection/wildcards are treated conservatively as one unit.| Claude Code | Codex | dsh-perm-guard | |
|---|---|---|---|
| Read-only command set | built-in, not configurable | sandbox | built-in + configurable |
rm -rf / ~ breaker | always prompts | sandbox blocks | always prompts (all modes) |
| Protected paths | yes | .git/.agents/.codex | .ssh/.aws/secrets/system dirs/.git |
| Network isolation | tool-level | OS-level (default off) | not available (DSH has no OS network fence; only curl|sh pattern detection) |
| Approval categories | 3 tool classes | 5 granular switches | 11 explicit switches + 2 modes |
| Auditing | prompts only | logs | in-plugin audit + host approval/asked/decided events |
~/.dsh/perm-guard.json (created on first change):
{
"enabled": true,
"mode": "standard",
"categories": { "fileEdit": "auto", "...": "..." },
"trustedDirs": []
}
trustedDirs: extra absolute paths auto-approved in Standard mode (default: workspace + its sibling directories).# hot-plug testing (no restart)
# 1. define a dynamic Cordis plugin with the same decision logic
# 2. cordis_run → verify → cordis_stop
# static bundle (this repo layout)
# symlink to ~/.dsh/profiles/web/node_modules/dsh-perm-guard
# add "dsh-perm-guard" to ~/.dsh/profiles/web/package.json dsh.profile.bundles
# restart dsh web
Verification matrix: docs/verify-checklist.md