一个面向所有人的本地密码管理器
<div align="center"> # APM **一款面向所有人的更好的本地密码管理器。** [](https://golang.org) [](LICENSE) [](https://aaravmaloo.github.io/apm) [](https://github.com/aaravmaloo/apm/actions/workflows/ci.yml) [](https://github.com/aaravmaloo/apm/releases/latest) [](https://github.com/aaravmaloo/apm/stargazers) [](https://github.com/aaravmaloo/apm/issues) </div> APM 是一款用 Go 和 Rust 编写的快速、零知识 CLI 密码管理器。它将 **25+ 种结构化机密类型**存储在单个加密保险库中——从密码和 TOTP 验证码到 SSH 密钥、医疗记录、照片和二进制文件。本仓库发布两个二进制文件:用于个人使用的 `pm` 和用于共享组织保险库的 `pm-team`。 --- ### 为什么选择 APM? - **快速且易于学习**——无需记忆命令或标志。APM 会提示你输入所需的一切。对于追求极致速度的高级用户,也提供 CLI 标志。 - **零知识**——你的主密码永远不会被存储。使用 Argon2id 派生三个独立的 32 字节密钥。除你之外,任何人都无法解密你的保险库。 - **双重加密**——可选择 AES-256-GCM 或 XChaCha20-Poly1305。在 AEAD 认证之上通过 HMAC-SHA256 提供双层完整性保护。 - **便携**——一个保险库文件,一个二进制文件。随身携带你的保险库。 - **可选云同步**——同步到 Google Drive、GitHub 或 Dropbox。完全可选加入;使用 APM 无需账户。 - **AI 就绪**——原生 MCP 服务器,配备作用域令牌,使 Claude、Cursor 或任何兼容 MCP 的代理能够安全访问你的保险库。 - **团队就绪**——`pm-team` 中提供完整的 RBAC、部门、审批工作流和共享保险库。 --- ### 快速开始 ```sh go build -o pm . pm setup # initialize vault and choose security profile pm unlock # start a session pm add # add a secret (interactive) pm get github # fuzzy search and retrieve pm lock # end session ``` **团队版:** ```sh cd team go build -o pm-team . ``` --- ### 密钥类型 APM 支持 **25 种结构化密钥类型**,具有经过验证的字段和类型特定的显示逻辑: | # | 类型 | # | 类型 | |---|------|---|------| | 1 | 密码 | 14 | Docker Registry | | 2 | TOTP | 15 | CI/CD 密钥 | | 3 | 政府证件 | 16 | 安全笔记 | | 4 | 医疗记录 | 17 | 恢复代码 | | 5 | 旅行信息 | 18 | 证书 | | 6 | 联系人 | 19 | 银行信息 | | 7 | Wi-Fi | 20 | 文档 | | 8 | API 密钥 | 21 | 软件许可证 | | 9 | 令牌 | 22 | 法律合同 | | 10 | SSH 密钥 | 23 | 照片 | | 11 | SSH 配置 | 24 | 音频 | | 12 | 云凭证 | 25 | 视频 | | 13 | Kubernetes | | | --- ### 功能特性 **安全** - 零知识 Argon2id 密钥派生 — 主密码从不存储 - 双 AEAD 加密算法:AES-256-GCM 和 XChaCha20-Poly1305 - HMAC-SHA256 双层完整性校验 - 四种可调安全配置:`standard`、`hardened`、`paranoid`、`legacy` - Watchtower(`pm watchtower`):0–100 安全评分,涵盖弱密码、重复使用、过期、已泄露(可选加入,k-匿名)和已暴露的密码、即将过期的项目、缺失的双因素认证和通行密钥、有风险的密钥和设置检查,以及逐项信任评分和活动审查 - 错误密码会增加逐渐延长的等待时间(绝不会永久锁定),由 CLI、应用和扩展共享 - 防篡改审计日志存储在保险库之外 **保险库** - 单一加密保险库文件 — 可在任何设备间移植 - 用于逻辑分区的空间(类似文件夹) - 模糊搜索,支持交互式浏览器和键盘导航 - 元数据检查器:创建日期、最后访问时间、访问次数、信任评分 **TOTP** - 交互式列表中的实时倒计时计时器 - 持久化的自定义排序 - 直接复制:`pm totp github` - 自动填充守护进程集成,用于自动注入 2FA 代码 **云同步** - Google Drive(OAuth2 PKCE)、GitHub(PAT)、Dropbox(OAuth2 PKCE) - 端到端加密 — 提供商永远看不到明文 - `.apmignore` 用于按提供商过滤条目 - 冲突解决:覆盖、保留本地或取消 - 后台自动同步 **会话** - 显式解锁/锁定,可配置过期时间和不活动超时 - 为自动化和 AI 代理访问提供委托的临时会话 **MCP 服务器** - 原生模型上下文协议服务器 - 作用域权限令牌:`read`、`secrets`、`write`、`admin` - 写操作在桌面应用中等待您的批准;助手无法批准自己的更改 - 适用于 Claude Desktop、Cursor、Windsurf 以及任何 MCP 客户端 **恢复** | 因素 | 命令 | |--------|---------| | 邮件 OTP | `pm auth email` | | 恢复密钥 | `pm auth recover` | | 法定份额(Shamir) | `pm auth quorum-setup` | | WebAuthn 通行密钥 | `pm auth passkey register` | | 一次性恢复代码 | `pm auth codes generate` | **导入 / 导出** | 格式 | 导入 | 导出 | |--------|--------|--------| | JSON | `pm import json` | `pm export json` | | CSV | `pm import csv` | `pm export csv` | | TXT | `pm import txt` | `pm export txt` | **策略引擎** ```yaml name: corporate-standard password_policy: min_length: 14 require_uppercase: true require_numbers: true require_symbols: true rotation_policy: rotate_every_days: 90 notify_before_days: 14 ``` ```sh pm policy load ./policies/ ``` **团队版(`pm-team`)** - 基于角色的访问控制(RBAC),支持多种角色 - 部门拥有相互隔离的加密域 - 针对敏感条目的审批工作流 - 用于多用户凭据共享的共享保险库 --- ### 浏览器扩展 APM 浏览器扩展可填充登录信息、在所属网站上提供一次性验证码、保存新的登录信息,并创建和使用通行密钥(passkey)。它始终无法看到你的主密码或通行密钥的私钥。它通过一个由 APM 在你本机 `127.0.0.1:41417` 上提供的小型桥接服务进行通信(可设置 `APM_BRIDGE_PORT` 以使用其他端口)。 **访问保险库的三种方式** - 使用桌面应用:应用打开期间桥接服务会运行。配对请求和浏览器解锁会显示在应用中。 - 仅使用 CLI,已链接(推荐):运行一次 `pm extension link`。它会将 `pm` 注册为各 Chromium 浏览器(Chrome、Edge、Brave、Arc、Vivaldi、Chromium)的原生消息传递主机,此后只要应用关闭,浏览器便会自行启动 `pm`。 - 仅使用 CLI,从终端启动:运行 `pm extension serve` 并保持其打开。它提供与桌面应用相同的 API,并在每次解锁、锁定和配对请求发生时显示出来。 ```sh pm extension link # once per computer; confirm the code the extension shows pm extension serve # unlocks with your CLI session, or asks for the master password pm extension serve --locked # starts locked; unlock from the extension pm extension serve --idle 5m # locks after 5 minutes without browser activity (default 15m, 0 turns it off) ``` `pm extension serve` 在保险库解锁或锁定时会打印一行信息。按 Ctrl+C 停止它;保险库密钥会从内存中清除。如果端口已被占用,它会退出并提示你 APM 应用可能已经在提供该扩展服务。 **配对浏览器** 1. 在扩展中,选择 Connect。扩展会显示一个 6 字符的代码,例如 `K7M-2QX`。 2. 检查 APM 是否显示相同的代码:桌面应用会打开一个对话框,而 `pm extension link` 或 `pm extension serve` 会在终端中询问,例如 `Connect Chrome on macOS? Code K7M-2QX [y/N]`。 3. 批准它。扩展会收到其令牌并完成配对。 请求会在 2 分钟后过期,且同一时间只能有一个请求等待处理。当 `pm extension serve` 未在终端中运行时,它会自行拒绝请求。若要改为手动配对,请运行 `pm extension token --show`,并将令牌粘贴到扩展的手动配对字段中。 **命令** | 命令 | 作用 | |---------|--------------| | `pm extension link [--browser chrome,edge] [--no-wait]` | 允许浏览器在桌面应用关闭时为扩展启动 `pm` | | `pm extension unlink` | 阻止浏览器启动 `pm`。配对关系会保留 | | `pm extension status [--port N]` | 显示哪些浏览器已链接、当前是什么在提供扩展服务、保险库的锁定状态和条目数量,以及令牌指纹 | | `pm extension serve [--port N] [--locked] [--idle 15m]` | 从此终端提供扩展服务,直到按 Ctrl+C | | `pm extension token [--show]` | 打印配对令牌,除非指定 `--show`,否则会掩码显示 | | `pm extension rotate` | 替换配对令牌。每个已配对的浏览器都必须重新配对。正在运行的桥接会在下一次请求时获取新令牌 | | `pm totp link <entry> <domain>` | 将一次性代码链接到某个站点,以便扩展在该站点提供它 | | `pm totp unlink <entry> [domain]` | 移除一次性代码的站点链接 | `pm get` 会显示某个登录项拥有的通行密钥以及链接到它的一次性代码,而 `pm totp` 会显示每个代码所链接的站点。 **桥接如何保持私密** - 它只监听 `127.0.0.1`,并且只应答发往 `127.0.0.1` 或 `localhost` 的请求,从而阻止 DNS 重绑定。 - 它会拒绝任何 `Origin` 为网页的请求。只有 `chrome-extension://`、`moz-extension://` 和 `safari-web-extension://` 来源会获得 CORS 头。 - 除配对外的每次调用都需要配对令牌,该令牌存储在 APM 配置目录中的 `bridge_token` 里,并以恒定时间进行比较。 - 列表和详情调用从不包含秘密值。当你显示或填充时,扩展会一次请求一个字段,APM 会记录该访问。 - 通行密钥在 APM 内部创建和签名。扩展会发送站点的来源和客户端数据的哈希,APM 在签名前会检查该站点是否可以使用该依赖方。 **每个登录项对应多个网站** 登录项将其主地址保存在 `website` 中,其他地址保存在 `urls` 中,在桌面应用中显示为“其他网站”。扩展会在匹配其中任一地址的页面上提供该登录项。默认情况下,匹配是指相同的可注册域名,因此 `accounts.google.com` 和 `mail.google.com` 都会匹配 `google.com`。 - 在弹出窗口中,你可以将当前所在站点添加到某个登录项、添加或移除网站,以及保存带有多个网站的新登录项。 - 如果你在某个未保存该登录项的站点上填充它,扩展会先询问。选择“填充并记住”以填充它并将该站点添加到登录项。 - `pm totp link <entry> <domain>` 对一次性代码执行相同操作。 **网站徽标** 桌面应用和扩展会显示每个登录项自己的徽标,而不是其首字母。APM 会自行从站点本身获取徽标,绝不会请求第三方 favicon 服务,因为那会泄露你保险库中的每个站点。 - 内容:登录时首个网站的主机名(一次性验证码使用其关联站点),转为小写并去除 `www.` 或端口。`localhost`、IP 地址、`.local`、`.internal` 以及不含点的名称永远不会被获取。 - 方式:APM 加载 `https://<host>/`(最多 512 KiB),选取页面声明的最佳图标(先是 `apple-touch-icon`,然后最大的 PNG,再是 SVG),并回退到 `https://<host>/favicon.ico`。仅使用 HTTPS,最多 3 次重定向,每个站点 6 秒,图像最大 256 KiB,不使用 Cookie。解析到回环、私有、链路本地或 CGNAT 范围的地址会被拒绝。请求直接发往站点,不经过系统代理。 - 时机:仅在保险库已解锁且桌面应用或 `pm extension serve` 正在运行时,最多同时处理 4 个站点。失败的站点在 3 天后重试;徽标在 30 天后刷新。 - 位置:APM 配置目录中的 `icons/`(macOS 上为 `~/Library/Application Support/apm/icons`,Linux 上为 `~/.config/apm/icons`,Windows 上为 `%AppData%\apm\icons`)。每个文件以其主机名的 SHA-256 命名,最多保留 2000 个。缓存未加密:图像旁的每个 `.json` 文件都标明了其主机名,因此任何能读取你配置目录的人都能看到哪些站点有徽标。 - 站点获知的信息:你的 IP 地址以及 APM 请求了其图标(用户代理为 `APM/<version> (+icon)`)。不涉及你的账户信息。 - 关闭方式:在桌面应用中,进入“设置”→“外观”,关闭“显示网站图标”(保险库设置 `siteIcons`,`pm extension serve` 也会遵循该设置),并选择“清除图标缓存”以删除缓存。设置 `APM_ICONS_OFFLINE=1` 可阻止某个进程的所有获取操作,例如在测试或 CI 中。已缓存的徽标仍会显示,直到你清除它们。 --- ### 安全配置文件 | 配置文件 | Argon2 内存 | 迭代次数 | 并行度 | 使用场景 | |---------|--------------|------------|-------------|----------| | `standard` | 64 MB | 3 | 2 | 大多数机器 | | `hardened` | 256 MB | 5 | 4 | 工作站(≥8 GB RAM) | | `paranoid` | 512 MB | 6 | 4 | 服务器(≥16 GB RAM) | | `legacy` | PBKDF2 | 600,000 | 1 | 向后兼容 | APM 会自动检测你的 CPU 核心数和 RAM,以在 `pm setup` 期间推荐最佳配置文件。 ### 开发状态与历史 (本说明来自所有者) 截至 2026 年 3 月 30 日,我目前正在开发 APM 的 GUI。起初它是一个 CLI 应用程序。Issue #38 详细解释了一切。总体而言,我希望 APM 能覆盖 更广泛的人群。我会将 GUI 单独放在 apm-gui 仓库中,或者创建一个组织并将两个仓库都移到那里。 我最初将 APM 作为一个真正的个人项目。它始于一个随机的夜晚,当时我想创建自己的密码管理器。我受够了 zoho password,因为我用它来管理 TOTP。它运行起来极其缓慢,而且我用明文文件存储令牌,这并不安全。 截至目前,我**不**计划放弃/停止该项目。它将在很长一段时间内保持可用。我每天都尝试改进它并使用它。有时仓库可能不活跃,那是我在测试和试验该应用程序的时候。 --- ### 发布结构 | 层级 | 稳定? | 保险库安全? | 用途 | |------|---------|-------------|---------| | Canary | ❌ | ❌ | 最早的功能预览——可能损坏保险库 | | Alpha | ❌ | ✅ | 不稳定功能,保险库完整性得到保留 | | Beta | ✅ | ✅ | 经过充分测试的功能,谨慎推出 | | Stable | ✅ | ✅ | 生产就绪版本 | > 在尝试 Canary 版本之前,请务必备份你的保险库。 附注:对于某些发布,某些层级可能不会发布,这取决于在不创建超出必要层级的情况下发布它们的速度和难易程度。 --- # AI 使用 开发 APM 并维护整个套件并非易事,无法一蹴而就。因此,我们使用 **25%** 的 AI 生成代码(主要是 UI 更改以及非关键、非加密相关的更改)。不过,在 APM,我们对使用 AI 有一些政策;列于下方。 - AI 仅用于开发小型功能以及不会干扰 vault 的功能 - AI 编辑必须谨慎对待并仔细审查 - AI 编辑必须经过充分测试 这些政策确保我们负责任地使用 AI,并让 APM 对所有人来说都更好! ### 文档 完整文档见 **[aaravmaloo.github.io/apm](https://aaravmaloo.github.io/apm)** - [安装](https://aaravmaloo.github.io/apm/getting-started/installation/) - [第一步](https://aaravmaloo.github.io/apm/getting-started/first-steps/) - [CLI 参考](https://aaravmaloo.github.io/apm/reference/cli/) - [架构](https://aaravmaloo.github.io/apm/concepts/architecture/) - [加密](https://aaravmaloo.github.io/apm/concepts/encryption/) - [团队版](https://aaravmaloo.github.io/apm/guides/team-edition/) - [MCP 集成](https://aaravmaloo.github.io/apm/guides/mcp-integration/) - [贡献](https://aaravmaloo.github.io/apm/contributing/) --- ### 贡献 欢迎贡献。请参阅 [CONTRIBUTING.md](https://aaravmaloo.github.io/apm/contributing/) 了解指南。 --- ### 许可证 [GPL-3.0 License](https://github.com/aaravmaloo/apm/blob/master/LICENSE) © Aarav Maloo