@asafarim/envage

中文文档
0.5.0发布于 2026/11/04MITTypeScriptES Module近 30 天下载 1967

对 .env 文件进行安全、基于年龄的加密/解密, 跨越多个环境和单一repo app文件夹

中文使用文档
文档目录30 节
  1. @asafarim/envag TS套件
  2. 特征
  3. 兼容性
  4. 安装
  5. 快速启动
  6. 1. 生成键盘
  7. 2. 创建您的配置
  8. 3. 加密您的内存文件
  9. 4. 检查情况
  10. 5. 在新机器上解密
  11. CLI 参考
  12. envage init-key
  13. envage encrypt
  14. envage decrypt
  15. envage recipient add/list/remove
  16. envage status
  17. 配置 - envage.config.json
  18. 根内-平面 .env 文件
  19. 球形图案在 apps
  20. 配置字段
  21. 程序化 API
  22. 团队加密(v0.5.0)
  23. Git 整合
  24. .gitignore 规则
  25. 已分阶段文件警告
  26. 可选: 承诺前钩
  27. Monorepo 结构
  28. 安全说明
  29. 发展
  30. 许可证

自信地提交加密的.env文件

@asafarim/envag TS套件

安全、基于年龄的加密 .env 横跨 monrepo 环境的文件.

envage 让您安全地执行加密任务 .env 保存到 Git 的文件 解密解密出版本控制. 它使用战斗测试 年龄 加密格式——与使用的工具相同 Go, Rust, and DevSecOps toolchains worldwide. 滚,鲁斯特,和DevSecOps 工具链全球.


特征

  • 🔐 年龄加密 - 用途 age-encryption (纯类型脚本,无原生道克)
  • 🌍 多种环境 —— 说 dev, (中文(简体) ), staging, (中文(简体) ), prod,任何自定义名称,或 root 为平地 .env 文件
  • 📁 单发觉 - 立即加密/解密所有应用程序 --all
  • 👥 团队接受者 ——独立身份解密共享密码;无私钥共享
  • 🔑 密钥或密码句 ——支持 X25519 密钥派和基于密码口的加密
  • 🛡 吉特安全系统 自动更新 .gitignore; 警告您是否设置已解密的文件
  • ✅ 生产警卫 ——解密所需的交互确认 prod 文件
  • 🧩 程序化 API ——在您自己的脚本中用作库
  • 📦 pnpm / 单重力 与 pnpm 工作空间无缝工作

兼容性

需要20号或更新的节点。 信封没有反应依赖性或对等版本 限制并工作在React 18和React 19项目工具. 其综合指数和 文件系统 API 在 Node.js 中运行,外部浏览器发送组件. 演示 使用React 18,在CI中有一个单独的React 19构建. 演示默认为黑暗 模式,记住您的主题选择,并包含 CLI/API 团队接收实例 和与当前里程碑相联系的路线图.

安装

# In your monorepo root
pnpm add -D @asafarim/envage

# Or globally
pnpm add -g @asafarim/envage

快速启动

1. 生成键盘

npx envage init-key

这就产生了:

.age/key.txt   ← private key (mode 0600, gitignored automatically)
.age/key.pub   ← public key  (safe to share with teammates)

2. 创建您的配置

# envage.config.json (add it to the monorepo root)
# use relative paths from the monorepo root
# use 'root' for the .env files regardless of environment, 'dev' for development environment .env.dev, 'staging' for staging environment .env.staging, 'prod' for production environment .env.prod
# use '.' for the current directory (monorepo root): "apps": [".", "apps/web"],
{
  "apps": [".", "apps/web", "apps/admin", "packages/api"],
  "envs": ["root", "dev", "staging", "prod"],
  "keyFile": ".age/key.txt"
}

3. 加密您的内存文件

# Encrypt a single app/env
npx envage encrypt apps/web --env dev

# Encrypt all apps at once
npx envage encrypt --all --env prod

# Encrypt plain .env files across all apps (one environment per invocation)
npx envage encrypt --all --env root

4. 检查情况

npx envage status
apps/web
  dev        🔒 encrypted
  staging    🔒 encrypted
  prod       🔒 encrypted

apps/admin
  dev        🔓 decrypted (not yet encrypted)
  prod       🔒 encrypted

packages/api
  dev        🔒 encrypted
  prod       🔒 encrypted

9 entries — 8 encrypted  1 decrypted

5. 在新机器上解密

# Restore your own private identity from secure backup, or have an authorized
# teammate add your new public recipient (see Team encryption below).
npx envage decrypt apps/web --env dev

# Decrypt all at once
npx envage decrypt --all --env dev

CLI 参考

envage init-key

生成新时代的X25519 keypair.

envage init-key [--output <folder>]
选项默认说明
--output.age输出文件夹 key.txt 财务报告和审定财务报表 key.pub

envage encrypt

加密 .env.<env> → .env.<env>.age (或 .env → .env.age 何时 --env root) (中文(简体) ).

envage encrypt [path] [options]
选项默认说明
--envdev环境名称
--key自动检测年龄密钥文件路径
--passphrase—— 说密码句( 如果省略了 )
--all—— 说加密所有应用程序 envage.config.json

实例:

envage encrypt apps/web --env dev
envage encrypt apps/web --env prod --key .age/key.txt
envage encrypt --all --env staging
envage encrypt apps/web --env dev --passphrase "my secret"

# Root env — targets the plain .env file (no suffix)
envage encrypt apps/portal --env root
envage encrypt --all --env root

envage decrypt

解密 .env.<env>.age → .env.<env> (或 .env.age → .env 何时 --env root) (中文(简体) ).

envage decrypt [path] [options]
选项默认说明
--envdev环境名称
--key自动检测年代私钥文件路径
--passphrase—— 说密码句
--all—— 说解密所有应用程序 envage.config.json

解密 prod 或者说 production 环境总是促使 手动确认.

实例:

envage decrypt apps/web --env dev
envage decrypt --all --env prod

# Root env — targets .env.age → .env
envage decrypt apps/portal --env root
envage decrypt --all --env root

envage recipient add/list/remove

管理团队成员并重新加密所有已配置的密码文本 . add 财务报告和审定财务报表 remove 带一个完整的公共收件人 加上可选 --key <identity-file>。 。 。 . 见 团队加密 用于配置、恢复和撤销限制.

envage status

显示所有配置的应用程序和环境的加密状态 .

envage status [path]
选项说明
--env过滤输出到单个环境

配置 - envage.config.json

将此文件放入您单曲的根 :

{
  "apps": [
    "apps/web",
    "apps/admin",
    "packages/api"
  ],
  "envs": ["dev", "staging", "prod"],
  "keyFile": ".age/key.txt",
  "keyPubFile": ".age/key.pub"
}

根内-平面 .env 文件

使用 "root" 作为锁定赤裸的巢穴名称 .env 每个应用程序文件夹中的文件(无后缀). 这对已经使用单个的项目有用 .env 并且不想重命名它.

{
  "apps": [".", "apps/web", "apps/admin", "packages/api"],
  "envs": ["root", "dev", "staging", "prod"],
  "keyFile": ".age/key.txt"
}
内存名称纯文本文件加密文件
root.env.env.age
dev.env.dev.env.dev.age
staging.env.staging.env.staging.age
prod.env.prod.env.prod.age

球形图案在 apps

App 条目可能使用 glob 模式, 相对于文件系统扩展 选择 目录 这是存在的。 这对单簧管有帮助 你不想逐个列出.

{
  "apps": [".", "apps/*", "packages/*"],
  "envs": ["root", "production"],
  "keyFile": ".age/key.txt",
  "keyPubFile": ".age/key.pub"
}
  • * 匹配单个路径段(例如). apps/* → apps/web, (中文(简体) ), apps/admin) (中文(简体) ).
  • ** 匹配任何深度的嵌入目录.
  • 只匹配已有目录; 文件被忽略 .
  • 非 glob 条目( 如 . 或者说 apps/web) 保存为-s,即使文件夹 目前还不存在.
  • 结果是去重复的,所以重叠的模式是安全的.

配置字段

外地类型默认说明
appsstring[][]App文件夹路径( 相对 cwd) 。 支持球状图案(见下文)
envsstring[]["dev","staging","prod"]管理的环境名称
keyFilestring.age/key.txt私钥路径
keyPubFilestring.age/key.pub公钥路径
recipientsstring[]删除公共年龄接受者; 省略保留遗留的单键模式

程序化 API

import {
  encryptEnv,
  decryptEnv,
  generateKeyPair,
  generateKeyPairToFolder,
  getEnvStatus,
  loadConfig,
  resolveApps,
  ensureGitignore,
  updateRecipient,
} from "@asafarim/envage";

// Generate a keypair
const { identity, recipient } = await generateKeyPair();

// Write keypair to disk
await generateKeyPairToFolder(".age");

// Encrypt a named env file (.env.dev → .env.dev.age)
await encryptEnv({
  folder: "apps/web",
  env: "dev",
  keyFile: ".age/key.txt",
});

// Encrypt the root env (.env → .env.age)
await encryptEnv({
  folder: "apps/portal",
  env: "root",
  keyFile: ".age/key.txt",
});

// Passphrase-based encryption
await encryptEnv({
  folder: "apps/web",
  env: "dev",
  passphrase: "my-secret-passphrase",
});

// Decrypt a named env file (.env.dev.age → .env.dev)
await decryptEnv({
  folder: "apps/web",
  env: "dev",
  keyFile: ".age/key.txt",
});

// Decrypt the root env (.env.age → .env)
await decryptEnv({
  folder: "apps/portal",
  env: "root",
  keyFile: ".age/key.txt",
});

// Expand app globs ("apps/*") to actual folder paths
const config = await loadConfig();
const folders = await resolveApps(config);
// → ["/repo/apps/web", "/repo/apps/admin", ...]

// Check status (globs in config are expanded automatically)
const statuses = await getEnvStatus(config);
statuses.forEach((s) => {
  console.log(`${s.folder} [${s.env}]: encrypted=${s.encrypted} decrypted=${s.decrypted}`);
});

// Ensure .gitignore rules are present
await ensureGitignore();

团队加密(v0.5.0)

每个队友跑 envage init-key 当地份额 仅限 他们的公众 key.pub将私人身份保存在他们所有者的机器上或安全备份中. 现有获得授权的成员可登上另一个公共接收人:

envage recipient add age1... --key .age/key.txt
envage recipient list
envage recipient remove age1... --key .age/key.txt

替换 age1... 完全年龄的X25519公用钥匙。 命令从 项目根并需要已有 envage.config.json 无空 apps 财务报告和审定财务报表 envs添加/重新加密 所有已存在的密码文本 在那些配置中 插槽,包括被扩大的应用程序和 root 环境。 未配置的文件 不属于他们的范围。 缺少的密码文本被跳过 。 密码句加密或 不可解密的文件在替换开始前中止整个操作 .

公共收件人保存在版本配置中 :

{
  "apps": [".", "apps/*"],
  "envs": ["root", "dev", "prod"],
  "keyFile": ".age/key.txt",
  "recipients": ["age1...", "age1..."]
}

将更新的配置和密码文本一起提交。 普通 CLI 加密用途 配置收件人, 即使当 --key ,不需要私钥. 明确 --passphrase 选择密码句加密。 无配置 recipients 保持传统的单键行为。 第一个 recipient add 保留所提供身份的公用钥匙作为初始授权成员. 重复的,无效的,未知的,或最后接收的清除请求安全地失败.

方案API接受明确的公共接受者:

await encryptEnv({ folder: "apps/web", env: "dev", recipients: [alicePublic, bobPublic] });
await updateRecipient("add", bobPublic, { cwd: projectRoot, keyFile: ".age/key.txt" });

encryptEnv 不自动装入配置; 通过 config.recipients 你自己来. 收件人仅在内存中更改解密, 绝不更改为纯文本文件 。 替换 使用同名目录的临时文件和原子重命名. 写作失败时, 完成的替换被卷回。 多文件替换为 没有 一个 文件系统交易: 不运行并行加密/配置作者。 锁 防止同时接收者更新。 原件和清单保存在 私营 .envage-recovery-* 目录直到成功或回滚成功. 在进程中断或回滚失败后, 停止所有写入, 恢复 每个 该目录中的原始列表 manifest.json,验证解密,然后 删除回收目录 envage.config.json.lock从不执行这些 回收文物。 在更改前保持安全备份或清理 Git 检查站 .

仅删除新加密文件的收件人屏蔽访问 。 旧吉特 历史 密码副本 以及以前学到的秘密. 如果必须取消访问, 则单独旋转基本的 API 证书 .


Git 整合

.gitignore 规则

运行 envage init-key 规则自动添加到您 .gitignore数字 :

# --- envage managed ---
# Decrypted env files — never commit
.env*
!.env*.age
!.env.example
!.env.template
# Age private key
.age/key.txt
# --- end envage ---

已分阶段文件警告

如果你不小心的话 git add 加密前解密的内存文件 encrypt 命令将抓取并退出 :

✖ You are trying to commit a decrypted env file.
✖ Only encrypted .age files are allowed.
  apps/web/.env.prod

可选: 承诺前钩

将此添加到 .git/hooks/pre-commit 完全防止意外犯罪:

#!/usr/bin/env bash
npx envage status 2>/dev/null | grep -q "decrypted" && \
  echo "❌ You have decrypted env files. Run: npx envage encrypt --all" && \
  exit 1
exit 0

Monorepo 结构

monorepo/
├── .age/
│   ├── key.txt              ← private key (gitignored)
│   └── key.pub              ← public key  (commit this)
├── apps/
│   ├── web/
│   │   ├── .env.dev         ← decrypted (gitignored)
│   │   ├── .env.dev.age     ← encrypted (committed ✅)
│   │   ├── .env.prod        ← decrypted (gitignored)
│   │   └── .env.prod.age    ← encrypted (committed ✅)
│   ├── admin/
│   │   ├── .env.dev.age
│   │   └── .env.prod.age
│   └── portal/              ← app using root env (plain .env)
│       ├── .env             ← decrypted (gitignored)
│       ├── .env.age         ← encrypted (committed ✅)
│       └── .env.staging.age ← encrypted (committed ✅)
├── packages/
│   └── api/
│       ├── .env.dev.age
│       └── .env.prod.age
├── envage.config.json       ← committed ✅
└── .gitignore               ← auto-updated by envage

安全说明

  • 永不承诺或共享 .age/key.txt - 这是你的私人身份. 给每个队友自己的身份,只增加他们的公收人.
  • 解密的数值从未被记录 ——不采用动词模式,不采用出错模式
  • 生产解密设闸 - 总是要求明确 y 确认
  • 加密文件为 二进制 ——不能不小心读作正文
  • 这个 age 格式提供认证加密; 篡改可被检测到

发展

# Install dependencies
pnpm install

# Build
pnpm build

# Run tests
pnpm test

# Type-check only
pnpm lint

许可证

麻省理工学院 阿里·萨法里姆

版本与发布记录

@asafarim/envage 共发布 10 个版本,首次发布于 2026/05/22;过去 12 个月发布了 10 个版本。

版本发布日期距今
0.5.0latest2026/11/043 天前
0.4.22026/07/064 个月前
0.4.12026/07/064 个月前
0.4.02026/07/064 个月前
0.3.32026/06/015 个月前
0.3.22026/05/225 个月前

关于 @asafarim/envage 的常见问题

@asafarim/envage 是什么?

对 .env 文件进行安全、基于年龄的加密/解密, 跨越多个环境和单一repo app文件夹

如何安装 @asafarim/envage?

在项目目录运行 npm install @asafarim/envage,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 envage,可以用 npx envage 直接运行。

@asafarim/envage 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@asafarim/envage 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@asafarim/envage 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@asafarim/envage 可以商用吗?

@asafarim/envage 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@asafarim/envage 的下载量有多少?

根据 npm 官方下载统计,@asafarim/envage 在 2026/10/07 – 2026/11/05 这 30 天内被下载 1,967 次,日均约 66 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@asafarim/envage 还在维护吗?

最新版本 0.5.0 发布于 2026/11/04(3 天前);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/05/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。