Chuyển đến nội dung chính

dsh-vault

Đã xác minh

@aiwayds/dsh-vault · v0.7.0 · MIT

dsh-plugin: encrypted backup / restore / migration of the dsh home config through a private GitHub repo

Cài đặt

dsh plugin add @aiwayds/dsh-vault

Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.

Mã nguồn

Thẻ

Readme

dsh-vault

English | 中文

dsh 插件:把本机 dsh 配置加密备份到自己的 GitHub 私有仓库,在新机器上一条命令拉平——恢复配置、按清单重装插件,跨机恢复即迁移。

要求 dsh >= 0.2.0-rc.2 — 本插件只跟随 dsh RC/stable 线(CI 与发版在运行时解析 latest/next 中更新的 dist-tag)。不再支持 alpha 线。

零 npm 依赖:加密只用 Node 内置 crypto(scrypt + AES-256-GCM),GitHub 传输走 REST。

命令

/vault backup [口令]              备份并推送(repo 不存在则自动创建 private)
/vault list                       表格列出 Vault 里所有机器的备份信息
                                  (机器/描述/快照时间/文件数/大小,← 本机 标记)
/vault restore [机器] [--yes] [口令]
                                  不带机器名 = 列表快照
                                  跨机选择 = 迁移;--yes 才真正执行
/vault config                     查看当前设置
/vault set repo <owner/name>      覆盖默认仓库名
/vault set machine-desc <描述>    机器描述(写进快照清单,跨机选择时辨认用)
/vault set remember-passphrase on|off
                                  on 时下一次带口令的 backup 把口令存入钥匙串

配置

dsh 0.1.7 起,旧的 settings.yaml 只在启动时导入一次即改名 settings.yaml.imported,插件配置改存 profile patch。配置入口是 ~/.dsh/profiles/<profile>/cordis.patch.yml 里的 dsh-vault 条目——与 /vault set 写回的是同一条目(热生效,免重启):

- id: dsh-vault
  name: '@aiwayds/dsh-vault'
  config:
    repo: ""                        # owner/name 覆盖;空 = 默认 dsh-backup-<用户名>
    machineDescription: ""          # 写进快照清单的机器描述
    rememberPassphrase: false       # backup 时把口令存入 macOS 钥匙串

升级前的旧 settings.yaml 顶层 vault: 段不会自动迁移(entry id 是 dsh-vault,旧段名是 vault)——原文留在 settings.yaml.imported,用 /vault set 重新设置一次即可。

口令来源优先级:命令内联参数(不落日志)→ $DSH_VAULT_PASSPHRASE 环境变量 → macOS 钥匙串(rememberPassphrase 开启时)。GitHub 凭据来自 $GITHUB_TOKEN 或已登录的 gh CLI。

插件内置了一个 skill(dsh-vault-config):直接让 agent「帮我配置备份 / 做首次备份」, 指南会自动加载——以问答方式逐项收集(仓库、机器描述、口令记忆)并代写 dsh-vault 配置。

卸载

dsh plugin --profile tui remove @aiwayds/dsh-vault

宿主会自动清理 profile:dsh.profile.bundles 条目被摘除,插件的 patch 层随之卸下。但这是一个涉密/备份插件,有几样东西在卸载后仍然留存——remove 一概不碰,需自行处置:

  1. macOS 钥匙串条目(service + account 均为 dsh-vault),存着记住的口令。卸载前先 /vault set remember-passphrase off 关掉,或卸载后在「钥匙串访问」里手工删除该条目。
  2. GitHub 私有仓库 dsh-backup-<用户名>(首次 backup 自动创建),存着加密快照——不需要就在 GitHub 上删除。
  3. ~/.dsh/vault/stash/——最多 3 份 restore 前的整包配置暂存(含 .credentials.yaml,权限 0600)。rm -r ~/.dsh/vault 清掉。
  4. profile patch(cordis.patch.yml)里的 dsh-vault 配置条目,以及 ~/.dsh/settings.yaml.imported 里存档的旧 vault: 段——手工删除相关行。

备份集

进:settings.yaml、settings.yaml.imported(0.1.7 前旧设置的存档,存在即备份)、.credentials.yaml(API keys)、APPEND_SYSTEM.md、agents/、每个 profile 的清单四件套(package.json / pnpm-lock.yaml / pnpm-workspace.yaml / cordis.patch.yml——0.1.7 起插件设置就住在 patch 里)、home 级 cordis.patch.yml、models-store.json。

不进:sessions/、storages/、一切 node_modules(按清单重装)、cordis.yml(宿主启动时无条件重写)、.anonymous-user-id、使用统计。

安全模型

  • 快照在离开本机前整包加密:口令 → scrypt 派生密钥 → AES-256-GCM(vault format v1,头部自带 KDF 参数与版本号)。
  • 私有仓库只是第一道门(token 泄露),加密才是数据门。口令遗失 = 快照永久不可解,插件不做找回。
  • 口令三种给法:命令内联(recordInput: false,不落会话日志)→ $DSH_VAULT_PASSPHRASE 环境变量 → macOS 钥匙串(remember-passphrase on 时自动存取)。
  • backup 前做加密自检(加密后立即解回核对),坏快照不会顶掉好快照;restore 前把当前配置暂存到 ~/.dsh/vault/stash/(保留最近 3 份)。
  • GitHub 凭据:复用 $GITHUB_TOKEN 或已登录的 gh CLI;登录不在插件职责内。

Vault 布局

dsh-backup-<github用户名>/          ← private,可 /vault set repo 覆盖
└── machines/<hostname>/
    ├── snapshot.enc               ← 加密快照(每机只留最新,覆盖式)
    └── manifest.json              ← 明文元数据(机器/描述/时间/文件清单,无密钥材料)

已知限制

  • profile 清单里的 file: 绝对路径依赖(如本地 link 的插件)在别的机器上无效,restore 会警告,需手工处理。
  • .env、storages/(含机器绝对路径)不迁移;会话历史不迁移。
  • 每机只留最新快照(刻意为之,见 ADR 0003)——想加历史是格式级变更。
  • restore 的插件重装依赖 dsh CLI 与 pnpm 在 PATH 上。

开发

pnpm install && pnpm build && pnpm test   # 单测(24 个)
node scripts/smoke-boot.mjs               # 真宿主 boot 冒烟(scratch profile)
node scripts/e2e-host.mjs                 # 真 GitHub 回环(沙箱 home + scratch repo)
./e2e/run-e2e.sh                          # podman 容器 e2e(隔离 ~/.dsh)

设计文档:CONTEXT.md(术语表)与 docs/adr/(备份集边界、加密方案、覆盖式快照、单 repo 多机布局)。