DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Permission Gate — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-permission-gate

Permission Gate

DeepSeek Harness 的 UI 级访问门禁 + 进程级智能体工具制动:共享会话、严格的 60 分钟空闲锁定、原生设置模块。不是服务器端身份验证。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-permission-gate@1.2.0
README兼容性版本

兼容性与来源证明

Permission Gate 以 dsh-permission-gate 发布,当前版本为 1.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/23

版本

1.2.0stable
2026/9/23

相关插件

正在加载相关插件…

最新版
1.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
80 kB
文件数
9
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 1
周下载
0
最近提交
2026/9/23
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 security-access 分类下经过校验的插件。

DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。Plugin Subscriptionsdsh-plugin-subscriptions将 ChatGPT (Codex)、Claude、Grok (X Premium)、GitHub Copilot 和 Google Antigravity 订阅用作 DeepSeek Harness LLM 提供商,并通过网页设置页面使用 OAuth 登录Auto Reviewdsh-auto-review针对 DeepSeek Harness 审批请求的第二模型 AI 自动审查:只读审查子代理在审批应答链上决定允许或拒绝,并采用故障关闭回退机制和完整的会话日志审计。Codex Subscriptiondsh-codex-subscription通过 OAuth 在 DeepSeek Harness 中使用 ChatGPT 和 Codex 订阅,支持配额管理、安全重置、网页搜索、图像和快速模式

README

dsh-permission-gate

A UI-level access gate and process-wide agent tool brake for DeepSeek Harness (dsh).

Log in once → every open DSH page unlocks. Nobody logged in → the agent itself can't run a single tool.


⚠️ Read this first: this is NOT authentication

DSH's /api surface has no authentication of its own — that is a deliberate property of the harness, not a bug this plugin fixes. The harness's own source describes its request fence like this:

trustedHosts is a DNS-rebinding fence, explicitly not authentication

Any client that can reach the DSH port can bypass this plugin entirely by calling the HTTP API directly. This plugin gates:

  • ✅ the browser page (a full-screen lock page injected into every page load)
  • ✅ the agent's tool calls (a process-wide tools.guard brake)

It does not gate the HTTP surface. It is not a reverse proxy, not a session layer, and not an authorization system.

Always pair it with a real boundary:

Real boundaryWhat it gives you
Bind DSH to loopback (dsh web, the default)Nothing on the network can reach it at all
A VPN / overlay (WireGuard, Tailscale, ZeroTier)Only your own devices can route to the port
A TLS reverse proxy that performs real authenticationThe only place a real auth layer can live

If you deploy this on a public port and believe you are protected, you are worse off than having nothing, because you will stop looking for the real problem.


What it does

  • Full-screen lock page. Injected into every DSH page load via the documented webserver/index-inject channel — no client bundle, no module loader, nothing to keep in sync with the SPA.
  • Global shared session. One session per process, one idle clock. Log in on your phone → your desktop page unlocks on its next poll. The clock expires → every page falls back to the login page.
  • Strict 60-minute idle lock. No grace period, not even for a running task. This is intentional: the gate is a dead-man switch.
  • Process-wide tool brake. While nobody is logged in, ctx.tools.guard denies every agent tool call. The agent cannot read files, run commands, open the network, or spawn subagents.
  • Real credentials. scrypt + random salt, stored at ~/.dsh/permission-gate.json (mode 0600). The session lives in memory only, so a restart always requires a fresh login — but your password is never reset.
  • Server-rendered escape hatch. /gate is plain HTML served by the host half. It works even if the injected script fails or is cached out.
  • Native settings module. A 权限闸门 page inside DSH's own Settings, where the gate can be disabled — and disabling requires the password.
  • Collapsible status chip. A countdown chip in the corner; collapse it to a slim tab on the right edge and click the tab to bring it back. The preference persists in localStorage.

Install

This package declares dsh.bundle, so it is a profile layer: installing it is one command, and DSH reconciles the composition for you. There is no patch file to edit.

dsh plugin --profile web add dsh-permission-gate

# restart DSH once — the client roster is scanned at startup

The bundle inserts this row on its own (see cordis.patch.yml):

- insert:
    - id: permission-gate
      name: dsh-permission-gate

Migrating from a manual install? Delete that same row from your own ~/.dsh/profiles/web/cordis.patch.yml first. The bundle now inserts it, and two entries sharing one id will collide.

On the next page load you get the lock page. The first visit asks you to set a password; every visit after that asks you to enter it.

Endpoints

All of them are served by the host half and sit behind the same origin as DSH.

MethodPathPurpose
GET/gateServer-rendered login page. Always available.
GET/gate/ui.jsThe injected browser script (cache-control: no-store).
GET/gate/status{ state, expires, remainingMs, idleMs, hasCredential, authenticated }
POST/gate/login{ password, mode } — mode: "setup" on first run. Sets the session cookie.
POST/gate/touch"A human is present" — extends the idle clock.
POST/gate/lockDrop the session and clear the cookie.
POST/gate/mode{ password, enable } — disable/enable the gate. Requires the password.

state is one of setup · locked · unlocked · disabled.

Threat model

ScenarioCovered?
Someone picks up your unlocked phone/laptop and opens the browser✅ full-screen lock page
You walk away and an autonomous agent keeps working✅ strict idle lock + tool brake
A page is left open on a second device✅ shared session logic; all pages mirror the server state
Someone in your tailnet calls /api directly❌ not covered — that is what the real boundary is for
Someone can edit cordis.patch.yml or the package directory❌ not covered — a plugin cannot defend the composition that loads it
Someone restarts the DSH process❌ not covered — the gate lives in the process; a restart also clears the session

Deliberate exemption

Three tools stay callable while the gate is locked, because they touch no files, commands, session content, or credentials:

get_goal · update_goal · todo_write

They exist so a locked agent can still report state and close out its own bookkeeping. Remove the BOOKKEEPING_TOOLS line in lib/index.js if you want a zero-exemption gate.

Recovery

SituationWhat to do
Forgot the passwordDelete ~/.dsh/permission-gate.json → next visit asks you to set a new one
The injected UI is broken / cachedVisit /gate directly — it is server-rendered
Locked out completelySet disabled: true on the row in cordis.patch.yml, or remove the row. cordis.patch.yml is watched live, so no restart is usually needed
Want to inspect statecurl http://127.0.0.1:3080/gate/status

Design notes

Built while running DSH remotely from a phone. Three bugs are baked into the comments and the test suite, because each one is a trap anyone building injected UI for DSH will hit:

  1. A silent render crash is worse than a visible error. The lock page used to throw on every render in the common path (appendChild(null) when the "confirm password" field is absent) — the host-side guard kept working while the UI showed nothing, i.e. "no permissions, but you can still chat." Fix: never append null, and wrap the whole render in a fallback that puts the error on screen.
  2. Never re-render a form on a timer. A 5-second status poll rebuilt the login form and wiped whatever the password field contained. Fix: re-render only when the state actually changes, and carry typed values across renders.
  3. A global session must not require a per-browser cookie. /gate/touch originally demanded a cookie matching the session token. After a restart only the browser that logged in held a valid cookie, so every other page's activity was rejected with 401 — the countdown only ever went down. Fix: touch grants nothing; it only requires that the shared session is unlocked.

Development

The smoke test runs the real lib/ui.js against a minimal DOM stub whose appendChild throws on null, exactly like a real DOM. No browser needed.

npm test

Compatibility

Developed against DSH 0.1.1-rc.2 / cordis 4.x, and depends on these harness capabilities:

  • host: webServer.register · webserver/index-inject · tools.guard
  • client: the settings.section slot · slots and timer services

These are internal-ish APIs; a DSH upgrade may require a matching update here.

License

MIT