打开网易新闻 查看精彩图片

2024年GitHub扫描到1280万个泄露密钥,其中67%来自.env文件。这个数字背后是一套用了十几年的"土办法":新员工入职,老员工从Slack翻一份配置文件发过去,附上一句"别提交到仓库"。

软件工程师Mackenzie Jackson做过一个实验:在公开仓库里放了个假密钥,72小时内被调用了194次。攻击者用爬虫监控git历史的速度,比你删文件的手速快得多。

Slack传文件,本质是"裸奔"

Slack传文件,本质是"裸奔"

env文件的设计初衷是方便,结果成了安全黑洞。五个致命问题环环相扣:

明文存储。你的数据库连接字符串就躺在磁盘上,和node_modules平起平坐。笔记本丢了?密钥跟着裸奔。

传输渠道失控。Slack私信、邮件、Notion文档——这些平台没有端到端加密,消息被索引、被备份、被前员工截图。六个月前发的文件,现在还在Slack的搜索栏里。

静态凭证永不失效。2022年的Stripe密钥,2024年还在某个旧电脑的Time Machine备份里沉睡。攻击者最喜欢这种"长期饭票"。

Git的记忆力太好。哪怕你秒删,git log里永远有备份。GitHub专门做了密钥扫描,就是因为误提交太频繁。

零审计。凌晨三点谁调用了生产数据库?env文件给不出答案。

打开网易新闻 查看精彩图片

开发者不是 careless,是这套流程太顺滑。顺滑到让人忘了它在裸奔。

一个周末的掀桌实验

一个周末的掀桌实验

作者受够了,用Rust写了个叫zenv的工具。核心逻辑一句话:用加密 vault 替代明文文件,运行时注入密钥。

迁移成本被压到最低。一行命令把旧env导进vault,之后启动项目改成zenv run -- npm start。对开发者来说,几乎无感。

加密用的是libsodium,密钥派生走Argon2id。作者没自己造轮子,"密码学领域,原创等于自杀"。

零配置是刻意设计。没有YAML要调,没有集群要部署。单机开发、CI/CD、生产环境,同一套命令。

作者的原话:「我不想说服CTO买企业方案,我只想周一早上不再收到'谁有staging的env文件'这种消息。」

社区反应:有人拍桌,有人摇头

社区反应:有人拍桌,有人摇头

项目在Hacker News上被顶到首页,评论区分成两派。

打开网易新闻 查看精彩图片

拍桌派占多数。一条高赞评论:「我们团队用1Password的CLI,但配置起来像解谜游戏。这个看起来像是人写的工具。」另一条:「终于有人承认.env是'安全剧场'了,演了好多年。」

摇头派的质疑更尖锐。有人指出:vault的密钥存在哪?如果还是本地文件,只是换了个文件名。作者回应:支持硬件密钥和云KMS集成,但默认方案确实依赖本地密钥文件——这是便利性和安全性的权衡,"至少比明文强两个数量级"。

另一个争议是"零配置"的代价。没有RBAC(基于角色的访问控制),没有审计日志,团队规模上去怎么办?作者的定位很清晰:先解决"一个人开发"和"五人小团队"的痛点,企业级需求不是现阶段目标。

Rust写的,但不是为了炫技

Rust写的,但不是为了炫技

选Rust的理由很务实。作者之前用Go写过类似工具,二进制体积20MB,冷启动慢到被同事吐槽。Rust编译出来3MB,启动毫秒级。

更关键的是错误处理。密钥注入失败时,程序必须立刻崩溃——不能带着半套环境变量继续跑。Rust的Result类型让这种"强制处理失败"变得自然,"换Python我可能漏掉三个边界情况"。

代码开源在GitHub,MIT协议。作者拒绝了两次投资意向,"不想变成卖订阅的公司,然后逼着你把数据存我这儿"。

目前星标数刚过4000,但issue区很活跃。有人提交了Windows支持,有人在折腾Podman集成。作者每周花五小时维护,"比我想象的轻松,Rust确实省内存安全的心"。

最后一个细节:工具的初始化命令是zenv init,会生成一个.gitignore自动排除本地密钥文件。作者说,这是"用技术手段解决社会工程问题"——既然总有人忘记配置gitignore,那就让工具替你记住。

你的团队现在怎么传密钥?Slack、邮件,还是已经上了vault方案?