爸爸的私人凭据保管库 · 微信扫码登录 · 浏览器 1Password 体验
门神 = 个人版 1Password + 企业版 Vault 的混血——但完全长在自己的开发流里,不依赖任何第三方 SaaS。
所有 secret 用 age (SSH 公钥)加密成 .age 文件,git 当后端,明文从不落盘。
白名单 openid 才能进。CLI 与 Web 端共用同一份 vault。
每条凭据有 desc/vendor/severity/category/tags,AI agent 也能精准检索调用。
三个层次:CLI 写入(你的 mac)→ Git 同步(Restry/vault-data)→ Web 只读(线上 menshen-ui)。
vault add _global/MY_NEW_KEY --value "xxx"
vault meta _global/MY_NEW_KEY --desc "..." --vendor "..." --severity high --tags "..."
触发链:本地 age 加密 → git push → post-write hook → regen-snapshot → mvp-deployer 重新部署 menshen-ui → 浏览器立刻能搜到。单条 ≈ 9 秒。
遵循 skill vault-bulk-import:关 hook → JSON 分批 → 直接 age 加密落盘 → 一次 commit/push → 一次 snapshot → 一次部署。127 条 ≈ 30 秒。
手机扫码 → wx-gateway 回调带 HMAC → /api/wx/finalize 验签 → NextAuth 发 JWT cookie → 进 VaultBrowser → 点 secret → /api/secret 解密返回真值 → 复制即走。
| 路径 | 方法 | 作用 |
|---|---|---|
/login | GET | 展示扫码二维码(来自 wx-gateway) |
/ | GET | VaultBrowser 主界面(需登录 + 白名单) |
/api/wx/finalize | GET | 扫码完成回调,HMAC 验签 + 5 分钟 skew + signIn |
/api/auth/[...nextauth] | * | NextAuth v5 标准入口 |
/api/projects | GET | 列出 25 个项目元数据 |
/api/projects/[name] | GET | 项目详情 + 该项目所有 secret 元数据(不含值) |
/api/secret | POST | 按 key 取明文值,每次取触发 audit log |
recipient 是你的 ~/.ssh/id_rsa.pub。私钥在你 mac,服务器只能解密不能加密(recipient 单向)。
① wx-gateway HMAC-SHA256 验签 + 时间戳 5 分钟 skew;② openid 必须在 menshen-ui/ADMIN_OPENIDS 白名单。
遵循 secure-admin-path-pattern,敏感页面用环境变量 slug,不暴露在 URL 路径里给爬虫看。
所有 /api/secret 调用进 audit.ts,记 openid + key + ts。
middleware.ts matcher 排除 api/auth · api/wx · api/projects · api/secret · favicon · _next/*,其他全要登录。
WX_GATEWAY_SECRET 只在服务端 env 里,前端永远拿不到。
| 指标 | 数值 | 说明 |
|---|---|---|
| 项目(projects) | 25 | 含资源池项目(azure-resources / _global / mvp-deployer …) |
| secret 总数 | 407 | 每条都已加密 + 带完整 metadata |
| health-check 满分项 | 7 / 7 | desc / vendor / severity / category / tags / 幽灵 meta / 同步 |
| snapshot 文件大小 | 110 KB | menshen-ui 编译进部署包,零 runtime 解密 |
| 线上部署平均耗时 | ~80 秒 | mvp-deployer + Caddy + pm2 + port 3805 |
# 列出所有项目
vault project list
# 看一个项目所有凭据
vault project show wechat-pay
# 查单值
vault get _global/GEMINI_API_KEY
# 全文搜
vault search azure
vault search -t vendor/discord
vault search -p _global
# 改 metadata(注意:不带字段会清空!要么完整 5 个字段,要么直接编辑 index.toml.age)
vault meta _global/X --desc "..." --vendor "..." --severity high --tags "..." --category credential
# 导出某项目为 .env(只能本地,需私钥)
vault export -p echo > ~/Projects/echo/.env.local
# 强制同步 git + 重生 snapshot + 部署
vault sync
~/.vault/hooks/post-write.sh
| 症状 | 大概率原因 | 处置 |
|---|---|---|
| UI 502 | menshen-ui 端口被 .env PORT 覆盖 | 清 manifest.env 里的 PORT,只留 manifest.port |
| 扫码后跳 /login?err=expired | 本地时间偏差 > 5 分钟 | 校时 |
| 扫码后跳 /login?err=sig | WX_GATEWAY_SECRET 不一致 | 对齐 wx-gateway 与 menshen-ui 的 secret |
| 登录后无法看 vault | openid 不在白名单 | vault meta menshen-ui/ADMIN_OPENIDS 加 openid |
| snapshot 落后 | hook 被禁了 / push 失败 | 查 ~/.vault/hooks/post-write.sh.disabled;改回;手动跑一次 |
| UI 显示 ? 图标 | secret 缺 severity | python3 ~/.vault/scripts/health-check.py 找出补上 |
| vault add 一直慢 | vault CLI 单条 git push 4s + hook 3s | ≥10 条用 skill vault-bulk-import,绕过 CLI |
30 秒后清理,避免长时间留在剪贴板。
当前是子串匹配,可换 fzf 风算法。
哪些 secret 一年没动,哪些每周用 ——> 提示轮换。
开放给团队前需要加 RBAC + 审计权限读分离。
当前只有 GitHub 单点。可加 R2 / iCloud 异地。
看 critical 级别凭据时再要一次手机短信验证。