门神 Menshen · 架构与使用说明

爸爸的私人凭据保管库 · 微信扫码登录 · 浏览器 1Password 体验

Domain menshen.mvp.restry.cn Stack Next.js 15 · NextAuth v5 · age 仓库 Restry/menshen-ui Vault 数据 Restry/vault-data 更新 2026-05-09
25 项目 407 secrets 线上 ✓ 仅爸爸可登录

01它是什么

门神 = 个人版 1Password + 企业版 Vault 的混血——但完全长在自己的开发流里,不依赖任何第三方 SaaS

🔐 加密存储

所有 secret 用 age (SSH 公钥)加密成 .age 文件,git 当后端,明文从不落盘。

🔑 微信扫码登录

白名单 openid 才能进。CLI 与 Web 端共用同一份 vault

🧠 AI 友好

每条凭据有 desc/vendor/severity/category/tags,AI agent 也能精准检索调用。

02整体架构

三个层次:CLI 写入(你的 mac)→ Git 同步(Restry/vault-data)→ Web 只读(线上 menshen-ui)。

本地 · 你的 MAC GIT 远程 线上 · 门神 UI vault CLI ~/.vault/bin/vault add / get / list / project / export ~/.vault/store/ project/KEY.age + index.toml.age age -R .age-recipients (SSH) post-write hook regen-snapshot → 触发部署 Restry/vault-data github.com (private) .age 文件 + index.toml.age .vault-snapshot.json 解密后的扁平索引 menshen-ui 内嵌读取 menshen-ui (Next.js 15) menshen.mvp.restry.cn App Router · NextAuth v5 · Tailwind v4 微信扫码登录 wx-gateway → /api/wx/finalize HMAC-SHA256 验签 + openid 白名单 VaultBrowser (React) 项目导航 + 搜索 + tag 过滤 点 secret → POST /api/secret 取真值 deploy.mvp.restry.cn manifest+zip 打包上传 Caddy · pm2 · port 3805 写入 / 读取 自动触发流程 部署 / 同步

03三种典型流程

① 你新增一条凭据(CLI 路径)
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 秒

② AI 批量入库(推荐 ≥10 条时)

遵循 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 解密返回真值 → 复制即走。

04关键路由

路径方法作用
/loginGET展示扫码二维码(来自 wx-gateway)
/GETVaultBrowser 主界面(需登录 + 白名单)
/api/wx/finalizeGET扫码完成回调,HMAC 验签 + 5 分钟 skew + signIn
/api/auth/[...nextauth]*NextAuth v5 标准入口
/api/projectsGET列出 25 个项目元数据
/api/projects/[name]GET项目详情 + 该项目所有 secret 元数据(不含值)
/api/secretPOST按 key 取明文值,每次取触发 audit log

05安全层

🔒 加密:age + SSH 公钥

recipient 是你的 ~/.ssh/id_rsa.pub。私钥在你 mac,服务器只能解密不能加密(recipient 单向)。

🆔 登录:双重门

① wx-gateway HMAC-SHA256 验签 + 时间戳 5 分钟 skew;② openid 必须在 menshen-ui/ADMIN_OPENIDS 白名单。

🛡️ 路径:env slug

遵循 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 里,前端永远拿不到。

06当前数据规模

指标数值说明
项目(projects)25含资源池项目(azure-resources / _global / mvp-deployer …)
secret 总数407每条都已加密 + 带完整 metadata
health-check 满分项7 / 7desc / vendor / severity / category / tags / 幽灵 meta / 同步
snapshot 文件大小110 KBmenshen-ui 编译进部署包,零 runtime 解密
线上部署平均耗时~80 秒mvp-deployer + Caddy + pm2 + port 3805

07常用 CLI 速查

# 列出所有项目
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

08故障速查

症状大概率原因处置
UI 502menshen-ui 端口被 .env PORT 覆盖清 manifest.env 里的 PORT,只留 manifest.port
扫码后跳 /login?err=expired本地时间偏差 > 5 分钟校时
扫码后跳 /login?err=sigWX_GATEWAY_SECRET 不一致对齐 wx-gateway 与 menshen-ui 的 secret
登录后无法看 vaultopenid 不在白名单vault meta menshen-ui/ADMIN_OPENIDS 加 openid
snapshot 落后hook 被禁了 / push 失败~/.vault/hooks/post-write.sh.disabled;改回;手动跑一次
UI 显示 ? 图标secret 缺 severitypython3 ~/.vault/scripts/health-check.py 找出补上
vault add 一直慢vault CLI 单条 git push 4s + hook 3s≥10 条用 skill vault-bulk-import,绕过 CLI

09未来可加

📲 一键复制 + 自动清剪贴板

30 秒后清理,避免长时间留在剪贴板。

🔍 模糊搜索 (fuzzy)

当前是子串匹配,可换 fzf 风算法。

📊 凭据热度仪表板

哪些 secret 一年没动,哪些每周用 ——> 提示轮换。

🤝 多人受信白名单

开放给团队前需要加 RBAC + 审计权限读分离。

📦 备份策略

当前只有 GitHub 单点。可加 R2 / iCloud 异地。

🔐 二级口令

看 critical 级别凭据时再要一次手机短信验证。

核心理念:门神 = "你的 SSH 私钥能解密的一切都你说了算"。它本身不是新加密协议,而是把 age + git + Next.js 三个成熟工具用最少的胶水粘成 1Password 体验。没有它没法用,但删了也只丢线上 UI——本地数据永远在。