🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

凭据管理 fatatalia/dsh-credentials-admin

DeepSeek Harness
fatatalia38 天前有提交已提供中文文档扫描:含敏感能力

在设置页增删改长期凭据,值写入后不可读取

28.2/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/11 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add fatatalia/dsh-credentials-admin
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · security
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 38 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 4 处,展示前 4 条)
  • 读取本地文件
    index.js:230
    const text = await readFile(this.filename, "utf8");
  • 读取本地文件
    index.js:233
    updatedAt = (await stat(this.filename)).mtime.toISOString();
  • 写入本地文件
    index.js:294
    await mkdir(dirname(this.filename), { recursive: true, mode: 0o700 });
  • 读取本地文件
    index.js:298
    const text = await readFile(this.filename, "utf8");
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-typert-protocol
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 列出凭据引用
  • 新增凭据引用
  • 删除凭据引用

DSH 凭据管理设置页插件:列出/新增/删除 ~/.dsh/.credentials.yaml 的 refs(值只进不出)

README

由 DeepSeek 最新模型翻译生成
dsh-credentials-admin — 凭据管理设置页插件 在 dsh Web 的 Settings → 凭据管理 分区里,管理 $DSH_HOME/.credentials.yaml 的 refs: 段长期凭据:列出、新增、覆盖、删除。 一句话设计原则:值只进不出。 界面能写新值,但永远不会显示、也不能取回任何已配置的值 —— 连值的长度都不给。这是设计,不是遗漏。 dsh 版本兼容性 要求 dsh ≥ 0.1.7-rc.1(已在 0.1.7-rc.1 实测通过)。 - Typert strict codec 必须带 create() 工厂(2026-09-24):0.1.7 起客户端 typert registry 对 strict codec 同样严格校验(dsh-typert-registry/lib/client.js 要求 codec.create 是函数),缺失则打开设置卡片即报 typert: <id> result strict codec has no create() factory。client.js 与 index.js 两处 codec 均已补 create()(服务端 gateway 走 codec.create().parse(v))。
展开完整文档(README 剩余 1 节)
dsh-credentials-admin — 凭据管理设置页插件

在 dsh Web 的 Settings → 凭据管理 分区里,管理 $DSH_HOME/.credentials.yaml 的 refs: 段长期凭据:列出、新增、覆盖、删除。

一句话设计原则:值只进不出。 界面能写新值,但永远不会显示、也不能取回任何已配置的值 —— 连值的长度都不给。这是设计,不是遗漏。

dsh 版本兼容性

要求 dsh ≥ 0.1.7-rc.1(已在 0.1.7-rc.1 实测通过)。

- Typert strict codec 必须带 create() 工厂(2026-09-24):0.1.7 起客户端 typert registry 对 strict codec 同样严格校验(dsh-typert-registry/lib/client.js 要求 codec.create 是函数),缺失则打开设置卡片即报 typert: <id> result strict codec has no create() factory。client.js 与 index.js 两处 codec 均已补 create()(服务端 gateway 走 codec.create().parse(v))。

它做什么

| 能做 | 不能做(有意为之) |
| 列出 refs: 里所有凭据名 + 是否已配置 | 显示 / 复制 / 下载已配置的值 |
| 新增一条(名字 + 值) | 改 records: 段(浏览器会话 secret、Models 页的 API key) |
| 覆盖已有的值 | 改 env / .env 分层的凭据 |
| 删除一条 | 重命名(换名 = 新增 + 删旧,两步) |

改完立即生效:dsh 的 credentials provider 监听该文件,引用这些名字的脚本下次读取就能拿到新值,不用重启。

架构

两层,零 dsh 本体改动:

浏览器 (client.js) host (index.js)
Settings → 凭据管理 ──── Typert RPC ────▶ credentialsAdmin(TypertRemoteService) list / set / unset 读-改-写 refs 段(行级编辑) dsh-atomic-write:文件锁 + 原子写 credentials-local 解析器:写前自校验

为什么自己写盘:官方把 refs: 定义为只读缝 —— CredentialRef 只做 env → managed store → .env 分层解析,唯一的官方写路径 modifyRecord 只管 records:。管理 refs: 属于扩展能力,所以自建(共用锁 + 写前自校验 + 只碰 refs: 段),全程不修改 dsh 本体。

三条硬纪律

1. 永不回显已配置的值。 list 只返回 { name, configured };服务端不存在任何"读单个 ref 明文"的方法,所以浏览器端就算被改也拿不到旧值。日志只记名字,绝不记值。
2. 只动 refs: 段。 行级编辑,records: 段一字不改。写完立刻用 dsh 官方的 parseCredentialsDocument 自校验 —— 解析器不接受就整体放弃,绝不落盘半成品。
3. 与 dsh 共用同一把写锁。 @deepseek-ai/dsh-atomic-write 的 withFileLock 锁的是 <file>.lock(wx 创建),与 credentials provider 完全一致,所以"我写 refs"与"它写 records"不会互相覆盖。

目录

dsh-credentials-admin/
├── index.js # host:credentialsAdmin remote service + refs 行级编辑纯函数 ├── client.js # 浏览器 bundle:Settings → 凭据管理 分区 ├── scripts/selftest.mjs # 自测(只读真实文件做兼容性校验,不打印值) ├── cordis.patch.yml # bundle patch(插入 host 插件行) └── package.json

挂载

在 dsh profile(如 $DSH_HOME/profiles/web/package.json)里加依赖并登记 bundle:

{
"dependencies": {
"dsh-credentials-admin": "link:/path/to/dsh-credentials-admin"
},
"dsh": {
"profile": {
"bundles": ["…", "dsh-credentials-admin"]
}
}
}

生效方式:client 半由 dsh web 现场从磁盘读取并经 /plugins/??… 组合路由下发,改完刷新页面即生效;host 半改动需要重启主实例。

配置

cordis.patch.yml 插入的插件行接受两个可选项,默认值通常够用:

| 字段 | 默认 | 说明 |
| filename | $DSH_HOME/.credentials.yaml | 托管凭据文档路径;DSH_HOME 未设置时用 ~/.dsh |
| lockWaitMs | 5000 | 等待写锁的上限(dsh 侧同锁默认 2s,这里放宽以容忍并发窗口) |

输入约束:

- 凭据名匹配 ^[A-Za-z_][A-Za-z0-9_]*$ —— POSIX 名,不能以数字开头
- 值长度上限 8192 字符(挡住"把整个文件内容误粘贴进值框"这类事故)
- 空值 = 不存在:在 dsh 里空值与缺失等价,所以要清空请用删除,不要保存空值

RPC 接口

命名空间 credentialsAdmin,三个方法:

| 方法 | 参数 | 成功返回 |
| list | — | { refs: [{ name, configured }], file, updatedAt }(文件不存在 → refs: [],不算错误) |
| set | { name, value } | { name, replaced } |
| unset | { name } | { name, removed } |

失败一律 throw RemoteError(code, message),错误码:read-failed / bad-name / empty-value / too-long / write-failed。

⚠️ 不要自己包 { ok, value } 信封。 Typert 的 RPC 层已经替调用方包了一层;host 再包一层,客户端 result.value 拿到的是信封而不是数据 —— 症状是列表恒显示「共 0 条凭据」且不报错(RPC 层认为调用成功)。官方 dsh-api-settings-controller 的 credentialsController 就是「直接返回业务数据 + throw RemoteError」,照它写。

自测

node scripts/selftest.mjs

31 项断言:行级编辑纯函数(增 / 改 / 删 / 转义 / 边界)、与 dsh 官方解析器的兼容性、结构异常时的拒绝行为。只读真实凭据文件用于兼容性校验(内容不打印、不写入),所有写入都在内存文本上完成。

踩过的坑

- 方法名不能用 remove:client 侧 RemoteNamespaceService 原型上已有 remove(),同名会被 API gateway 以 client api: method "credentialsAdmin/remove" conflicts with its namespace service 拒绝,整个分区挂不起来。已改名 unset。
- 不要自包 RPC 信封:见上方 RPC 接口的警告。这个坑的隐蔽之处在于它不报错 —— 修完命名冲突后,页面能挂载了,却显示「共 0 条」,而 RPC 层一切正常。

限制

- 只管 refs: 段;records: 段、env、.env 层不在此处管理。
- 不支持重命名(请新增 + 删旧)。
- 无审计日志:文件里不记录「谁在何时改了哪个名字」,进程日志也只记「refs 已更新」。
预览分享卡片长什么样 ↓fatatalia/dsh-credentials-admin
分享 · DeepSeek Harness Hub
fatatalia/dsh-credentials-admin

在设置页增删改长期凭据,值写入后不可读取

回到顶部