DeepSeek Harness 插件

we39/dsh-jumpserver

Star 数 ★ 0 分类 安全与权限 收录于 2026-09-18

通过对话查询与管理 JumpServer:资产、用户、账号、授权、会话、命令审计、命令过滤与 RBAC 角色,使用 AccessKeyID/AccessKeySecret(HTTP 签名)鉴权。

安装

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:we39/dsh-jumpserver

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWEDERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yamlallowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

English

一个 DeepSeek Harness 插件,通过对话查询并管理 JumpServer 资产,使用 JumpServer 的 AccessKeyID/AccessKeySecret(HTTP Signature)进行鉴权。

项目状态:v0.9.0。已实现资产、用户、账号、授权规则、会话、命令审计、用户组、命令过滤规则、资产树节点、RBAC 角色/角色绑定的只读查询,以及资产、账号、用户、资产授权规则、用户组、命令组、命令过滤规则、资产树节点(包括将节点移动到新父节点)、自定义 RBAC 角色/角色绑定的创建/更新/删除,以及用户的密码/MFA/SSH 密钥重置——均需经过强制的原生用户审批。考虑到 JumpServer 作为堡垒机/PAM 系统的角色,终止会话和工单审批目前有意保留不实现。

为什么用 dsh-jumpserver

  • 按关键字或过滤条件查询 JumpServer 的资产、用户、账号、资产授权规则、终端会话、已执行命令、用户组、命令过滤规则、资产树节点和 RBAC 角色/角色绑定。
  • 创建、更新、删除资产、账号、用户、资产授权规则、用户组、命令组、命令过滤规则、资产树节点(包括将节点移动到新父节点)、自定义 RBAC 角色/角色绑定,以及重置用户的密码/MFA/SSH 密钥——每次写操作执行前都必须经过明确的原生用户审批提示,模型无法绕过。
  • 拒绝删除或重置超级管理员(管理员)账号的密码,拒绝创建"授予所有权限"式的宽泛资产授权规则或命令过滤规则,拒绝重命名/删除组织根节点或删除仍含资产的节点,也拒绝修改或删除内置 RBAC 角色、或删除仍绑定用户的角色——以上均由工具自身强制执行,不只是写在文档里的约定。
  • 只读查询绝不泄露敏感信息:账号的密钥/密钥密码,以及用户的密码/公钥/MFA 密钥,在返回给模型前会被逐字段剔除,即便 JumpServer API 本身返回了这些字段。
  • 使用 JumpServer 官方开发文档中记录的 AccessKeyID/AccessKeySecret 签名机制(hmac-sha256 HTTP Signature)进行鉴权。
  • AccessKeySecret 保存在本地 DSH 凭证库中,永远不会被回显到浏览器。

环境要求

组件 支持的最低版本
Node.js 20.11 及以上
DeepSeek Harness 0.1.2-rc.1
JumpServer REST API v1(支持 Access Key 认证)

安装

本地开发调试,从本地路径安装:

npm ci
dsh plugin --profile add link:/absolute/path/to/dsh-jumpserver

发布后,尽量安装已发布的、不可变的 tag 版本:

dsh plugin --profile add github:we39/dsh-jumpserver#v<version>

仅在测试时安装可变的开发分支:

dsh plugin --profile add github:we39/dsh-jumpserver

安装后需重启对应的 DSH profile。Windows 上请使用绝对路径 link:C:/path/to/dsh-jumpserver

配置

在 DSH Web 中打开 设置 → 插件 → JumpServer 资产查询

需要配置:

  • JumpServer URL:绝对地址,例如 https://jumpserver.example.com
  • Access Key:在 JumpServer 网页控制台的个人 API Key 列表中创建。
  • Secret Key:与上面的 Access Key 配对。

Access Key/Secret Key 使用 DSH 特权的本地回环凭证 RPC——只写不读,存储的值永远不会被读回或显示。URL 存储在 jumpserver 设置命名空间中,属于非敏感字段,保存后会以明文形式回显在卡片中以便核对。

HTTP 和 HTTPS 均可直接使用——没有 TLS 证书的内部部署可以直接用 http:// 地址,无需额外配置。请注意,纯 HTTP 会以明文方式传输签名后的请求(虽然密钥本身不会被传输),在不受信任的网络中建议优先使用 HTTPS。如需强制只使用 HTTPS,可在插件配置中关闭:

allowInsecureHttp: false

凭证引用名默认是 JUMPSERVER_ACCESS_KEY_ID / JUMPSERVER_ACCESS_KEY_SECRET,可以在插件配置中通过 akRef / skRef 修改。

JumpServer 权限建议

建议使用仅具有资产只读权限的 JumpServer 账号创建 AccessKey,避免使用超级管理员账号的密钥进行本插件的接入。

工具

只读工具中涉及分页的接口支持 limit(1-100,默认 20)/ offset(默认 0)。 共 53 个工具(12 个只读 / 41 个写),覆盖 10 个域。所有写工具都需要原生用户审批。

工具 行为
jumpserver_list_assets 按可选的 search 关键字列出资产。
jumpserver_get_asset id 获取单个资产的完整详情,包含协议和网域信息。
jumpserver_list_users 按可选的 search 关键字列出用户。绝不返回密码、公钥或 MFA 密钥。
jumpserver_get_user id 获取单个用户的完整详情。绝不返回密码、公钥或 MFA 密钥。
jumpserver_list_accounts 列出账号(资产上的登录凭据),可按 asset id 或 username 过滤。绝不返回密钥或密钥密码。
jumpserver_get_account id 获取单个账号的完整详情。绝不返回密钥或密钥密码。
jumpserver_list_permissions 列出资产授权规则,可按 userIdassetId 过滤。
jumpserver_list_sessions 列出终端(审计)会话,可按 userassetisFinished 过滤。
jumpserver_create_asset 写操作。 创建资产(必填 nameaddressplatform;可选 commentisActive)。需要原生用户审批。
jumpserver_update_asset 写操作。id 更新已有资产;只会修改你传入的字段。需要原生用户审批。
jumpserver_delete_asset 写操作,不可逆。id 永久删除资产。需要原生用户审批。
jumpserver_create_account 写操作。 创建账号(必填 usernameasset;可选 namesecretTypesecretpassphraseprivilegedisActivecomment)。需要原生用户审批,详见下方"账号密钥的处理方式"。
jumpserver_update_account 写操作。id 更新已有账号;只会修改你传入的字段,可用于轮换 secret/passphrase。需要原生用户审批。
jumpserver_delete_account 写操作,不可逆。id 永久删除账号。需要原生用户审批。
jumpserver_create_user 写操作。 创建平台用户(必填 nameusernameemail;可选 commentisActive)。不会设置初始密码——用 jumpserver_update_user 单独设置。需要原生用户审批。
jumpserver_delete_user 写操作,不可逆。id 永久删除用户。拒绝删除超级管理员(管理员)账号。需要原生用户审批。
jumpserver_update_user 写操作。id 更新已有用户;只会修改你传入的字段(nameemailcommentisActive)。也可以将登录密码重置为指定值(password)。拒绝修改超级管理员(管理员)账号的密码——其它字段仍可修改。需要原生用户审批,见下方"账号密钥的处理方式"——同样的暴露权衡适用于 password 值。
jumpserver_reset_user_mfa 写操作。id 解绑用户的 MFA/OTP 设备,迫使其下次登录时重新绑定。拒绝对超级管理员账号执行。需要原生用户审批。
jumpserver_reset_user_ssh_key 写操作。id 清空用户登录 JumpServer 本身所用的 SSH 公钥(不是资产账号密钥)。拒绝对超级管理员账号执行。需要原生用户审批。
jumpserver_create_permission 写操作。 创建资产授权规则(必填 nameassetsaccounts 必须是非空 UUID 数组;users/userGroups 至少提供一个且非空)。拒绝宽泛或"授予所有权限"式的匹配——不提供 all 或按节点匹配的选项。需要原生用户审批。
jumpserver_update_permission 写操作。id 更新已有规则;只会修改你传入的字段。传入的任何数组字段(usersuserGroupsassetsaccounts)都必须非空。需要原生用户审批。
jumpserver_delete_permission 写操作,不可逆。id 永久删除资产授权规则,立即撤销其授予的访问权限。需要原生用户审批。
jumpserver_list_commands 列出已执行的会话命令(命令审计日志),可按 assetaccountusersessionIdriskLevel 过滤。每行的命令输出会截断到 500 字符。
jumpserver_list_user_groups 按可选的 search 关键字列出用户组。用户组本身不授予任何资产访问权限。
jumpserver_get_user_group id 获取单个用户组的完整详情,包含其成员用户 id。
jumpserver_create_user_group 写操作。 创建用户组(必填 name;可选 userscomment)。需要原生用户审批。
jumpserver_update_user_group 写操作。id 更新已有用户组;只会修改你传入的字段。若传入 users,必须非空。需要原生用户审批。
jumpserver_delete_user_group 写操作,不可逆。id 永久删除用户组;成员用户本身不会被删除,但引用该组的授权规则会失去对应授权。需要原生用户审批。
jumpserver_list_command_groups 按可选的 search 关键字列出命令组(命名的命令匹配规则集合)。命令组本身不生效,需要绑定到命令过滤规则上。
jumpserver_get_command_group id 获取单个命令组的完整详情,包含完整的匹配内容。
jumpserver_create_command_group 写操作。 创建命令组(必填 namecontent;可选 typeignoreCasecomment)。需要原生用户审批。
jumpserver_update_command_group 写操作。id 更新已有命令组;只会修改你传入的字段。需要原生用户审批。
jumpserver_delete_command_group 写操作,不可逆。id 永久删除命令组;绑定该组的命令过滤规则会失去对应匹配规则。需要原生用户审批。
jumpserver_list_command_filters 按可选的 search 关键字列出命令过滤规则(对匹配命令进行拒绝/告警/接受的安全规则)。
jumpserver_get_command_filter id 获取单个命令过滤规则的完整详情,包含其用户/资产/账号范围和绑定的命令组。
jumpserver_create_command_filter 写操作。 创建命令过滤规则(必填 nameusersassetsaccountscommandGroupIds,均须为非空 UUID 数组;可选 action——reject/warning/accept,默认 reject——prioritycommentisActive)。拒绝"全部用户"/"全部资产"/"全部账号"式的宽泛范围——不提供这类选项。将 action 设为 accept 会在审批提示里被标记为安全降级。需要原生用户审批。
jumpserver_update_command_filter 写操作。id 更新已有规则;只会修改你传入的字段。传入的任何范围数组字段(usersassetsaccountscommandGroupIds)都必须非空。将 action 改为 accept 会在审批提示里被标记为安全降级。需要原生用户审批。
jumpserver_delete_command_filter 写操作,不可逆。id 永久删除命令过滤规则。审批提示会展示该规则删除前的当前 action(在审批前实时查询),方便你在批准前看清是否正在移除一条生效中的 reject/warning 防护规则。需要原生用户审批。
jumpserver_list_nodes 列出 JumpServer 资产树节点(资产所归属的文件夹式分组树),可按 search 关键字匹配完整的"/"分隔路径进行过滤。
jumpserver_get_node id 获取单个资产树节点的完整详情,包含其 key、完整路径、父节点 key 和直属资产数量。
jumpserver_create_node 写操作。 创建一个资产树节点。只传 value 时,会作为组织根节点的直接子节点创建;传入 fullValue("/"分隔的路径)则会一次性创建/复用一整条嵌套节点链。需要原生用户审批。
jumpserver_update_node 写操作。id 重命名已有节点(value)。拒绝重命名组织根节点——由 JumpServer 自身强制执行。需要原生用户审批。
jumpserver_delete_node 写操作,不可逆。id 永久删除节点。如果该节点是组织根节点,或其子树中仍含有资产,JumpServer 会拒绝该操作。需要原生用户审批。
jumpserver_move_node 写操作。 将某个节点(及其整个子树)重新挂载到另一个父节点下(idtargetParentId)。如果会形成环路,JumpServer 会拒绝该移动操作。需要原生用户审批。
jumpserver_list_roles 列出 JumpServer RBAC 角色,可按 search 关键字和 scopesystemorg)过滤。
jumpserver_get_role id 获取单个 RBAC 角色的完整详情,包含其 scope、是否内置、备注和已绑定的权限 id。
jumpserver_create_role 写操作。 创建自定义 RBAC 角色(必填 namescope;可选 permissionIdscomment)。创建 scope="system" 角色会在审批提示中被标记为高风险。需要原生用户审批。
jumpserver_update_role 写操作。id 更新已有自定义角色;只会修改你传入的字段,且传入的 permissionIds 会替换整套权限集合。拒绝更新内置角色——由 JumpServer 自身强制执行。需要原生用户审批。
jumpserver_delete_role 写操作,不可逆。id 永久删除自定义角色。如果角色是内置角色,或仍绑定至少一个用户,JumpServer 会拒绝该操作。需要原生用户审批。
jumpserver_list_role_bindings 列出角色绑定(角色到用户的分配关系),可按 userIdroleId 过滤。
jumpserver_create_role_binding 写操作。 将角色授予某个用户(必填 userIdroleId;组织级角色必填 orgId,系统级角色需省略)。授予 scope="system" 角色会在审批提示中被标记为高风险。需要原生用户审批。
jumpserver_delete_role_binding 写操作,不可逆。id 撤销一条角色绑定。如果这是某用户在某组织内的最后一条组织级角色绑定,JumpServer 会拒绝该操作。需要原生用户审批。

终止会话和工单审批尚未实现,目前也没有计划实现——详见下方"范围之外"。

范围之外

jumpserver_terminate_session 曾被评估过,最终放弃:JumpServer 的 /api/v1/terminal/tasks/kill-session/ 接口在标准 swagger 导出中没有记录请求体 schema,实际字段名只能推断、无法确认。工单审批(/api/v1/tickets/...)有意不实现——这会让助手替代本应由人工完成的审批步骤,而这正是 JumpServer 自身工作流所要求的。

写操作审批机制

对资产或账号写工具的每一次调用都会被 tools/pre-execute 网关拦截(与 dsh-grafana 拦截 grafana_push 是同一套模式),并始终降级为明确的原生审批提示——模型无法在没有审批的情况下执行写操作。审批提示会展示具体操作和将被修改的字段;更新时只会发送你传入的字段,删除成功后会读回当时的名称/地址(资产)或用户名/所属资产(账号)用于最终确认。更新和删除工具在执行写操作前都会先重新确认目标是否存在(多发一次 GET),如果目标已不存在会明确报错,而不是静默不做任何事。

账号密钥的处理方式

jumpserver_create_accountjumpserver_update_account 接受可选的 secret/passphrase 参数——也就是目标资产上实际的登录凭据。这是本插件"密钥绝不进入模型上下文"这一惯例的一个刻意例外:与 AccessKeySecret(只存在于 DSH 凭证库中,永远不会发给模型)不同,通过这两个工具设置的账号密钥,会经过工具调用参数才能到达 JumpServer,因此会暴露在对话内容中,以及处理该对话的模型服务商那一侧。

审批提示中永远不会显示密钥的具体值——只会提示"是否正在设置或修改密钥"这一事实——工具的返回值同样不会回显具体值。但这种脱敏止步于插件边界:如果你让助手设置一个具体的密码,那个密码在到达插件之前,都会出现在对话记录里。如果密钥值本身必须完全不经过模型上下文,建议优先使用 JumpServer 自身的自动化能力(账号推送、改密任务)来生成/轮换凭据;只有在你已明确接受这一权衡的情况下,才使用这两个工具的密钥参数。

同样的权衡也适用于 jumpserver_update_userpassword 参数。

安全与数据边界

  • AccessKeySecret 不会进入工具参数、模型消息、日志或 Git。
  • 账号的密钥/密钥密码,以及用户的密码/公钥/MFA 密钥,会在每个只读工具的输出中被逐字段明确排除——而不是仅仅依赖通用序列化器的省略。(账号写工具是唯一的例外,见上方"账号密钥的处理方式"。)
  • 已认证的请求会拒绝 HTTP 重定向,避免签名请求被转发到其它域。
  • 默认禁止非回环地址使用纯 HTTP(见 allowInsecureHttp)。
  • 请求支持协作式取消、超时控制和响应体大小上限。
  • 错误响应只暴露受长度限制的状态/详情描述。
  • id 参数在拼入请求路径前会校验是否为合法的 JumpServer UUID,防止路径注入。
  • 所有返回字段(名称、地址、备注、用户名等)均视为不可信数据,不会被当作模型指令执行。

开发

npm ci
npm run verify

测试使用 Node 内置测试运行器,并对 JumpServer 响应进行了 mock。

License

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。