deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:aashizpoudel/dsh-remote-trust
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
Open DSH's privileged /api methods to remote trusted hosts, so a browser
visiting the Web UI through a reverse proxy (or from another machine on your
network) can configure the harness — Settings → Models, provider and
credential management — instead of getting 403 forbidden.
# ~/.dsh/profiles/web/cordis.patch.yml
- insert:
- id: remote-trust
name: "@crckss/dsh-remote-trust"
config:
hosts:
- dsh.example.com
DeepSeek Harness binds its Web server to loopback for safety (--host 0.0.0.0
is refused outright) and its /api browser-trust fence has two layers:
Host must be loopback or a
--trusted-host authority, with Origin and sec-fetch-site checks.settings.*, credentials.*,
agentPreset.*, and llm.discoverModels are additionally FORCED to
loopback with an empty trust list, even when --trusted-host names your
domain.That pin is hardcoded in @deepseek-ai/dsh-client-connection, so a deployment
behind Traefik/Caddy/nginx can browse sessions but can never open the settings
plane. This plugin removes the pin for endpoints you declare, without
touching node_modules.
The webserver's route table is checked exact-first, then longest-prefix.
The built-in /api route is a prefix route, so this plugin registers
exact routes for each privileged endpoint (/api/settings.describe, …).
Those exact routes win, run the same browser-trust fence (Host + Origin +
sec-fetch-site) against loopback plus your configured hosts, and then
forward the request to apiProxy exactly like the built-in bridge would.
The two host-native methods (host.pickDirectory, host.openPath) are not
opened by default because they drive native dialogs on the server machine.
# from your DSH profile directory
cd "${DSH_HOME:-~/.dsh}/profiles/web" # or profiles/tui, …
# pnpm must be on PATH (dsh plugin forwards to pnpm)
dsh plugin --profile web add @crckss/dsh-remote-trust
# or, from a local checkout:
dsh plugin --profile web add /path/to/dsh-remote-trust
dsh plugin --profile web add @crckss/dsh-remote-trust
- insert:
- id: remote-trust
name: "@crckss/dsh-remote-trust"
config:
# Authorities allowed to call privileged methods.
# Port-less host matches any port; host:port matches exactly.
hosts:
- dsh.example.com
- 100.34.48.118
# Optional: open privileged methods beyond the defaults
# (these are host-native actions, opt-in).
extraEndpoints:
- host.pickDirectory
# Optional: request body ceiling for the forwarded bridge.
maxRequestBodyBytes: 4194304
Trusted authorities are merged from two places:
config.hosts — explicit entries in the patch layer;ctx.webStartup.trustedHosts — whatever the invocation declared with
--trusted-host, plus LAN IP literals derived from the bind (when bound to
all interfaces).So the plugin follows the deployment's existing trust declaration: if you
already run dsh web --trusted-host dsh.example.com, the plugin picks that up
even with an empty hosts list.
agentPreset.read agentPreset.copy
agentPreset.openDocument agentPreset.remove
settings.describe settings.openDocument
settings.update settings.replace
settings.mutate
credentials.describe credentials.set
credentials.unset
llm.discoverModels
host.pickDirectory and host.openPath stay loopback-only unless listed in
extraEndpoints.
The plugin reuses the harness's own browser-trust logic — it does not add a looser check:
Host must be loopback or a configured authority (DNS-rebinding gate);Origin, when a browser sends one, must match the Host;sec-fetch-site: cross-site is always refused.Nothing becomes unauthenticated: the fence is not authentication, and it
never was. What changes is that the config plane stops being loopback-only and
becomes reachable from the authorities you already trust with
--trusted-host.
Do not expose the DSH port (3080) or the whole machine through a public proxy unless you add your own authentication. The fence protects against rebinding and cross-site requests, not against a stranger who can reach the port.
BODY='{"type":"client-request","rpcId":"v","method":"settings.describe","payload":{}}'
# remote host -> should be 200 (was 403 without the plugin)
curl -i -H 'Host: dsh.example.com' -H 'Content-Type: application/json' \
-d "$BODY" http://127.0.0.1:3080/api/settings.describe
# cross-site / attacker host -> must stay 403
curl -i -H 'Host: dsh.example.com' -H 'Origin: https://evil.example' \
-H 'sec-fetch-site: cross-site' -H 'Content-Type: application/json' \
-d "$BODY" http://127.0.0.1:3080/api/settings.describe
curl -i -H 'Host: evil.example' -H 'Content-Type: application/json' \
-d "$BODY" http://127.0.0.1:3080/api/settings.describe
@deepseek-ai/dsh-client-connection; this plugin pins
@deepseek-ai/dsh-host-apiproxy to a matching version so the forwarded
bridge stays compatible. After upgrading dsh, bump that dependency.cordis.yml composition change; the settings seam's merge semantics apply.MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。