ARMeeru/clipveil

GitHub: ARMeeru/clipveil

一款 macOS 剪贴板安全代理,在粘贴瞬间检测并遮蔽剪贴板中的敏感凭证,防止用户将密钥意外粘贴到 LLM、聊天或文档中。

Stars: 0 | Forks: 0

# clipveil [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/ARMeeru/clipveil/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/ARMeeru/clipveil)](https://github.com/ARMeeru/clipveil/releases/latest) [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE) ![平台: macOS arm64](https://img.shields.io/badge/platform-macOS%20arm64-lightgrey) **在粘贴之前,遮蔽剪贴板中的敏感信息。** 一个微型(约 1.2 MB,单一静态二进制文件)、零 runtime 的 macOS 代理工具,专为那些从终端复制内容并 粘贴到 LLM、聊天软件或文档中——但偶尔忘记自己刚复制的内容中 包含有效的 GitHub token、AWS key 或 private key 的用户而设计。 `clipveil` 绑定了一个快捷键:**Cmd+Shift+V**。当你按下它时: - 如果剪贴板中**没有**敏感信息,它将直接粘贴。没有任何变化。 - 如果**有**敏感信息,将出现一个原生对话框: 选择 **Paste Plain** 将真实值粘贴到你实际需要的地方(如 `.env`、config 或 `curl`)。选择 **Paste Redacted** 将粘贴掩码处理后的副本—— 非常适合 LLM prompt 和 bug 报告。无论哪种方式,你的真实剪贴板内容都会在之后 恢复。 你正常的 **Cmd+V** 操作永远不会受到影响。 ## 为什么开发它 现有的“安全剪贴板管理器”只对其*保存的历史记录*中的敏感信息进行脱敏—— 而你实际粘贴的内容却未受任何处理。clipveil 则是在你粘贴的**那一刻**,让你自主选择对**粘贴操作本身**进行脱敏。所有检测均在本地运行;任何数据都 不会离开你的机器。 ## 安装 需要 Rust 工具链 (`rustup`) 和 macOS。 ``` git clone clipveil cd clipveil cargo build --release cp target/release/clipveil /usr/local/bin/ ``` ### 授予 Accessibility 权限(仅需一次) 模拟粘贴按键需要 Accessibility 访问权限。当 clipveil 第一次 尝试粘贴时,macOS 会弹出提示——或者你也可以手动添加它: **系统设置 → 隐私与安全性 → Accessibility → +**,然后添加 `clipveil`(或你启动它时所用的终端)。 如果没有此权限,检测和对话框仍然可以正常工作,但最后的粘贴按键 会被 macOS 静默丢弃。 clipveil 会在启动时检查此权限,如果缺少权限则会打印警告, 这样你就不必去猜测为什么粘贴没有生效。 **关于临时签名 (ad-hoc signing) 的说明:** 该 bundle 使用的是临时签名,因此每次重新构建都会获得一个 新的代码哈希,macOS 会将其视为新身份——你需要 在重新构建后重新授予 Accessibility 权限。对于只需安装一次的设置来说,这是一次性的 操作。如果你经常迭代开发,请使用稳定的自签名代码签名 证书进行签名,以便授权在重新构建后依然有效。 ## 用法 ``` clipveil run # start the agent (default). Binds Cmd+Shift+V. clipveil scan # scan piped stdin or the clipboard; exit 1 if a secret is found clipveil redact # print a redacted copy of piped stdin or the clipboard clipveil version clipveil help ``` `scan` / `redact` 子命令也使得 clipveil 可以在脚本和 pre-commit hook 中发挥作用: ``` pbpaste | clipveil scan # "am I about to paste a secret?" cat prod.env | clipveil redact # masked copy for sharing git diff | clipveil scan || echo "secret in staged changes!" ``` ## 登录时运行 复制提供的 launch agent 并加载它: ``` cp dist/com.clipveil.agent.plist ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/com.clipveil.agent.plist ``` ## 检测范围 GitHub token(classic + fine-grained PAT)、GitLab PAT、OpenAI key、Stripe key、AWS access key ID、Google API key、Google OAuth token、Slack token (bot、app 和 webhook)、Discord bot token、Telegram bot token、SendGrid key、 npm token、JWT、`Authorization: Bearer` header、PEM private-key 块,以及 通用的 `password=` / `token=` / `api_key=` 赋值语句。 检测机制宁求安全不求精确:它宁愿标记出误报 (你可以选择 **Paste Plain** 忽略),也不愿泄露真实的敏感信息。匹配规则位于 [`src/detect.rs`](src/detect.rs) ——只需一行代码即可添加你自己的规则。 ## 工作原理 ``` Cmd+Shift+V ──▶ read clipboard ──▶ detect::has_secret? │ no ──────────┤────────── yes │ │ │ paste as-is │ native dialog │ ┌────┴─────┐ Plain Redacted Cancel │ │ │ paste set redacted nothing clipboard, paste, restore original ``` - 通过 Carbon `RegisterEventHotKey` 实现全局快捷键(无需 Accessibility 权限)。 - 通过原生 AppKit (`rfd`) 实现对话框。 - 通过 `enigo` 模拟粘贴(需要 Accessibility 权限)。 - 检测完全基于 regex —— 拥有完整的单元测试,不涉及任何 I/O。 ## 已知限制 (v1) - 粘贴是通过模拟的 **Cmd+V** 实现的,因此目标应用必须能够接受正常的 粘贴操作。对话框关闭后会有一个短暂的焦点稳定延迟;非常快速的 连续粘贴可能需要稍作停顿。 - Regex 检测无法捕捉所有可能的敏感信息格式。它涵盖了 常见且高风险的格式。请将其视为一道安全防线,而不是绝对的保障。 ## 占用空间 发布版的二进制文件大小约为 1.2 MB。其空间占用情况及原因如下: | 区块 | 大小约 | 备注 | |-------|-------|-------| | Rust `std` | ~240 KB | 任何 std 二进制文件的基准;不使用 `no_std` 则不可避免。 | | `regex` 引擎 + Unicode 表 | ~800 KB | 有意为之——详见下文。 | | clipveil 自身代码 | ~11 KB | 检测核心 + 代理。 | | macOS 粘合层 (global-hotkey, rfd, enigo, objc2) | ~25 KB | 所有 OS 管道代码的总和。 | ### 为什么使用 `regex` 而不是 `regex-lite` `regex-lite` 能将二进制文件减小 63%(至约 430 KB)。弃用它是出于实测数据的考量, 而非原则问题。在约 4 KB 的剪贴板样本上对全量匹配模式进行基准测试的结果如下: | 引擎 | 每次扫描耗时 | 二进制大小 | |--------|---------------|--------| | `regex` (lazy DFA) | **~10 µs** | ~1.2 MB | | `regex-lite` (backtracking) | ~1105 µs (**慢 108 倍**) | ~430 KB | `regex-lite` 会进行回溯,因此在这里它不仅慢了约 100 倍,而且 在处理大型剪贴板 payload 时性能可能会严重下降——而剪贴板的 大小是不受限制的。`regex` 的 DFA 无论输入为何都能以线性时间运行, 确保每一次 Cmd+Shift+V 操作都让人无法察觉。剔除 ASCII 以 砍掉 Unicode 表的 `regex` 方案也被否决了:它会强制使用字节模式匹配, 这可能会在 token 中间截断多字节 UTF-8 字符,并导致脱敏器发生 panic。对于 安全工具而言,可预测的正确性才是制胜之道。1.2 MB 是其真实的代价。 ## 开发 ``` cargo test # unit + integration (tests/) + CLI tests cargo test --no-default-features # fast: detection core + corpus only cargo clippy --all-features -- -D warnings cargo build --release ``` 测试位于 `src/detect.rs`(单元测试)、`tests/detection.rs`(检测语料库) 和 `tests/cli.rs`(端到端测试)中。有关覆盖率摘要,请参阅 `QA_REPORT.md`。 ## 许可证 MIT —— 详见 [LICENSE](LICENSE)。
标签:Rust, 剪贴板工具, 可视化界面, 敏感信息脱敏, 数据防泄露, 瑞士军刀, 系统辅助工具, 网络流量审计, 通知系统