关于 varlock
使用 varlock 管理项目环境变量和密钥的 skill。它以纳入版本控制的 `.env.schema` 描述配置,并通过命令行校验和加载变量,同时遮蔽敏感值。
主要功能
- 01在 `.env.schema` 中定义配置
- 02校验并加载环境变量
- 03在 Agent 输出中遮蔽敏感值
- 04加密本地密钥
- 05从外部提供方解析值
适用场景
- 01记录必需和可选的环境配置
- 02加载变量而不向 Agent 暴露密钥
- 03校验特定环境的配置
- 04引用来自 1Password 或 AWS 等提供方的密钥
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dmno-dev/ varlock --skill varlock安装后在 Claude Code 中输入/varlock确认已加载。
详细介绍
Varlock
此技能可帮助你使用 varlock 安全地管理项目中的环境变量和密钥。
文档:https://varlock.dev 代码仓库:https://github.com/dmno-dev/varlock
Varlock 使用 .env.schema(而不是 .env.example)作为项目环境变量的唯一真实来源。架构信息使用 @decorator 风格的注释来表示。敏感值可以设置在被 Git 忽略的 .env.local 文件中、通过环境传入,或使用函数从 1Password、Vault、AWS 等安全后端加载。
基本的 .env.schema 示例:
# @defaultSensitive=false @defaultRequired=infer
# @currentEnv=$APP_ENV
# @generateTsTypes(path=env.d.ts)
# ---
# @type=enum(dev, staging, prod)
APP_ENV=dev
# @type=url
API_URL=https://api.example.com
# Description of this var
# @sensitive @required @type=string(startsWith=sk-)
# @docs(https://xyzapi.com/docs/auth)
XYZ_API_KEY=
.env.schema 会提交到版本控制中,Agent 可以安全地读取和更新它。varlock CLI 可帮助加载和验证环境变量,同时屏蔽所有敏感内容,还可以安全地将环境变量注入命令。
注意: 如果通过 package.json 在本地安装了 varlock(而不是作为独立二进制文件安装),请通过包管理器调用它,例如 pnpm exec varlock load、bunx varlock load、npm exec varlock load。运行 CLI 命令前,请先确认项目使用的包管理器。
关键:安全规则
以下规则不可妥协:
不要暴露密钥
# NEVER do these - exposes secrets to agent context
cat .env
cat .env.local
echo $SECRET_KEY
printenv | grep API
# SAFE alternatives
varlock load --agent # JSON output, sensitive values redacted
varlock load # human-readable, sensitive values masked
cat .env.schema # schema only, no secret values
如果用户需要查看敏感值,请让他们运行 varlock reveal VAR_NAME。
文件访问规则
- 可以安全读取和编辑:
.env.schema和其他已提交到 Git 的.env文件(通常是特定环境的文件,例如.env.development) - 不要读取或编辑:
.env、.env.local、.env.[env].local或其他被 Git 忽略的值/覆盖文件——这些文件可能包含未加密的密钥 - 不要在代码、注释或聊天中记录或引用原始密钥值
敏感度规则
- 未经用户确认,不得移除标记为
@sensitive的项目上的该装饰器 - 请用户在其本地/被 Git 忽略的环境文件或密钥提供方(1Password、AWS 等)中编辑密钥值——绝不要自行填写密钥
用户要求“给我看看 .env 文件”时
不要直接读取 .env 或 .env.local。应运行 varlock load 来显示经过屏蔽的值,或读取 .env.schema 来展示架构。请说明直接读取环境文件可能会暴露密钥。
用户要求“更新/设置密钥”时
不要自行写入密钥值。请告知用户可以:
- 在其密钥提供方(1Password、AWS 等)中更新密钥,然后协助他们完成接入
- 手动编辑其
.env.local文件中的值
- 最好将
varlock(prompt)用作该值以加密,然后运行varlock load,按提示操作
然后运行 varlock load --agent 进行验证。
文件用途
| 文件 | 用途 | Agent 可以编辑吗? |
|---|---|---|
.env.schema | 架构、默认值、装饰器、描述 | 可以 |
.env.[env] | 特定环境的受版本控制配置(例如 .env.production) | 可以 |
.env、.env.local | 本地/被 Git 忽略的值和覆盖项 | 不可以——请告知用户自行编辑 |
.env.[env].local | 特定环境的本地覆盖项(被 Git 忽略) | 不可以——请告知用户自行编辑 |
.env.example | 旧版示例文件;迁移到架构文件中 | 与用户确认 |
确保 .env.schema 和受版本控制的特定环境文件未被 Git 忽略(必要时在 .gitignore 中添加 !.env.schema、!.env.production 等)。
特定环境文件及优先级
在 .env.schema 中设置 @currentEnv 时(例如 @currentEnv=$APP_ENV),varlock 会自动加载匹配的特定环境文件。文件按优先级从低到高依次应用:
.env.schema < .env < .env.local < .env.[currentEnv] < .env.[currentEnv].local < process.env
例如,如果 APP_ENV=staging,则存在时会自动加载 .env.staging 和 .env.staging.local。.env.local 中的值会覆盖 .env.schema 中的值,而 process.env 的优先级始终最高。
单独的 KEY= 表示没有设置值,因此不会覆盖优先级较低的文件中的值。使用 KEY="" 可将其覆盖为空字符串。
架构语法
根装饰器(文件头)
根装饰器应放在文件顶部的注释块中,位于第一个条目之前。通常使用 # --- 分隔符将文件头与条目分开。
| 装饰器 | 用途 | 缺省时 |
|---|---|---|
@currentEnv=$VAR | 设置用于确定当前环境的条目 | — |
@defaultRequired=bool|infer | 设置此文件中条目的默认必需状态 | true |
@defaultSensitive=bool|inferFromPrefix(PREFIX) | 设置此文件中条目的默认敏感状态 | true |
@generateTsTypes(path=./env.d.ts) | 自动生成 TypeScript 环境声明(已弃用的别名:@generateTypes(lang=ts)) | — |
@generatePythonEnv / @generateRustEnv / @generateGoEnv / @generatePhpEnv / @generateJavaEnv / @generateCsharpEnv (path=...) | 为相应语言生成带类型的环境模块 | — |
@import(path, ...keys?) | 从另一个 .env 文件或目录导入架构/值 | — |
@plugin(@varlock/name-plugin) | 加载插件 | — |
@setValuesBulk(resolver) | 从外部来源注入多个值 | — |
@disable | 禁用此文件的加载(可使用 =forEnv(test)) | false |
@defaultSensitive默认为true—— 除非显式标记为@public或@sensitive=false,否则所有条目都属于敏感项。设置@defaultSensitive=false可反转此默认值。@defaultRequired=infer:架构中有值的条目为必需项,没有值的条目为可选项。如果没有此装饰器,条目默认均为必需项。varlock init会在其生成的架构中写入@defaultRequired=infer和@defaultSensitive=false,因此大多数现有项目使用的是这些设置,而非未设置装饰器时的行为。请先阅读文件头,再判断这两项设置。- 条目默认值(
@defaultRequired、@defaultSensitive)只适用于在同一文件中定义的条目。仅在.env.local或导入文件中定义的条目会采用内置默认值(必需、敏感),不受根架构设置影响。 @defaultSensitive=inferFromPrefix(PUBLIC_):键名以PUBLIC_开头的条目不敏感,其余条目均敏感。@import()支持使用enabled=expr进行条件导入,也支持使用allowMissing=true进行可选导入。
条目装饰器
紧挨着配置条目之前的注释行中的装饰器会关联到该条目。空行会中断这种关联。
| 装饰器 | 用途 |
|---|---|
@required / @optional | 覆盖默认必需状态 |
@sensitive / @public | 覆盖默认敏感状态 |
@type=dataType | 设置验证/类型转换类型 |
@example="value" | 示例值(用于文档,不会在运行时使用) |
@docs(url) 或 @docs(label, url) | 链接到相关文档(可重复使用) |
@icon=collection:name | 用于生成文档的 Iconify 图标 ID |
@auditIgnore | 抑制 varlock audit 发出的“代码中未使用”警告 |
装饰器值可使用解析器函数:@required=forEnv(prod)、@sensitive=not(forEnv(dev))。
常见数据类型(@type=)
string(startsWith=X)、string(matches=regex("^pattern$"))、number、boolean、url、email、port、enum(a, b, c)、ipAddress、semver
普通 string 是默认值——无需添加 @type=string,直接省略 @type 即可。仅在需要指定类型或字符串约束时使用 @type。请参阅 https://varlock.dev/reference/data-types/
解析器函数(值)
条目可以使用解析器函数代替静态值:
# Reference another item ($VAR and ${VAR} are shorthand for ref(VAR))
FULL_URL=${API_URL}/v2/users
# Execute a CLI command
SECRET=exec(`op read "op://vault/item/field"`)
# Conditional logic
API_URL=if(eq($APP_ENV, prod), https://api.example.com, http://localhost:3000)
# First non-empty value
FALLBACK_VAR=fallback($PRIMARY, $SECONDARY, "default")
# Map one value to another
APP_ENV=remap($CI_BRANCH, "main", production, regex(".*"), preview, undefined, development)
# Check environment (based on @currentEnv)
# @required=forEnv(prod, staging)
PROD_ONLY_KEY=
主要函数:ref()、concat()、exec()、fallback()、if()、eq()、not()、and()、or()、isEmpty()、ifs()、remap()、forEnv()
请参阅 https://varlock.dev/reference/functions/
设置敏感值
主要有两种方式,可同时使用。
方案 1:插件(版本控制的密钥引用)
Varlock 插件允许你在 .env.schema 中以声明方式直接引用外部提供方的密钥。这些引用可以安全地提交到版本控制中,实际值会在加载时获取。
# @plugin(@varlock/1password-plugin)
# @initOp(token=$OP_TOKEN, allowAppAuth=forEnv(dev))
# ---
# @sensitive @type=opServiceAccountToken
OP_TOKEN=
# @sensitive
MY_SECRET=op(op://my-vault/item-name/field-name)
每个插件都提供自己的解析函数(例如,1Password 使用 op(),AWS 使用 awsSecret())。完整列表请参阅下文的插件,设置详情请访问 https://varlock.dev/guides/plugins/。
方案 2:使用 varlock() 进行本地加密(被 git 忽略的文件)
对于存储在 .env.local 等被 git 忽略的文件中的密钥,请使用 varlock() 函数进行设备本地加密,避免以明文形式存储:
# Encrypted value — decrypted automatically at load time
API_KEY=varlock("local:<encrypted-payload>")
# Prompt mode — on next `varlock load`, user is prompted to enter the value
# which is encrypted and written back to this file automatically
NEW_SECRET=varlock(prompt)
如何加密值:
- 交互式提示: 将值设为
varlock(prompt)并运行varlock load——系统会安全地提示用户输入,随后加密值会自动替换占位符 - 批量加密:
varlock encrypt --file .env.local会就地加密所有敏感明文值 - 加密单个值:
varlock encrypt会提示输入一个值,并输出加密结果以供复制粘贴 - 通过 stdin 管道传入: 若要在不将值暴露于上下文中的情况下加密(例如,生成的密钥或从其他工具读取的值),请将其通过管道传入
varlock encrypt:
这样可以避免明文密钥出现在 shell 历史记录和 Agent 上下文中。some-cli-that-outputs-secret | varlock encrypt # prints: SOME_SENSITIVE_KEY=varlock("local:<encrypted>")
加密在 macOS(Secure Enclave + Touch ID)、Windows(DPAPI + Windows Hello)和 Linux(TPM2)上由硬件支持,所有平台也都提供基于文件的回退方案。在 macOS 上,还可以使用内置的 keychain() 作为替代方案,将值存储在系统钥匙串中。
请参阅 https://varlock.dev/guides/local-encryption/
组织结构
设计环境变量布局之前,先询问用户其代码仓库的组织结构。
单个项目: 通常只需在代码仓库根目录放置一个 .env.schema。
Monorepo / 多应用: 使用 @import() 共享通用配置:
# Import shared config from root (directory form: also loads root .env / .env.local)
# @import(../../)
# Import from a sibling service (specific keys only)
# @import(../api/.env.schema, pick=[SHARED_API_URL, SHARED_DB_HOST])
# ---
APP_PUBLIC_URL=http://localhost:3000
- 根 schema — 共享服务 URL、组织级默认值和通用键
- 各应用的 schema — 应用专属项目,按需导入根目录或同级应用中的配置
- 明确声明导入;避免循环导入
与用户讨论:哪些值应放在根目录,哪些应按包分别设置,以及他们使用哪些环境。
请参阅 https://varlock.dev/guides/import/
插件
插件会为外部密钥提供方添加解析函数、数据类型和装饰器。在 .env.schema 中使用 @plugin() 安装:
# @plugin(@varlock/1password-plugin)
在 JS 项目中,还需安装 npm 包。使用独立二进制文件时,请固定版本:@plugin(@varlock/[email protected])。
可用插件: 1Password、AWS Secrets Manager、Azure Key Vault、Bitwarden、Dashlane、Doppler、Google Secret Manager、HashiCorp Vault、Infisical、Akeyless、KeePass、Keeper、Passbolt、Proton Pass、Pass、macOS Keychain(内置)。
各插件的设置详情请访问 https://varlock.dev/plugins/overview/。
集成(框架 / 运行时)
选择与项目框架对应的官方集成,不要猜测。请查看 https://varlock.dev/integrations/overview/ 中的具体指南(Next.js、Vite、Astro、SvelteKit、Bun、Cloudflare、Expo 等)。
典型步骤:
- 确认已安装
varlock(运行varlock init --agent或确认已有依赖) - 按照集成指南配置构建 / 开发流程、生成类型以及任何必需的配置
- 优先使用集成推荐的入口点(
varlock/auto-load、Vite 插件等),而不是临时使用process.env
启用框架集成后,它会自动处理环境变量的加载和注入——框架自身的开发 / 构建命令无需使用 varlock run。仅对集成未涵盖的其他脚本或工具使用 varlock run -- <cmd>(例如一次性迁移、CLI 工具、非 JS 命令)。
从 dotenv 迁移: 将 dotenv/config 或 dotenvx run 替换为 varlock 的对应方案,参见 https://varlock.dev/guides/migrate-from-dotenv/
非 JS 应用 / 服务: 使用 varlock run 或通过管道传递 varlock load --format shell,参见 https://varlock.dev/integrations/other-languages/
设置
安装 varlock:
- JS 项目: 将其安装为开发依赖 —
npm install -D varlock(或bun add -D varlock、pnpm add -D varlock) - 独立二进制文件(非 JS 项目或全局使用): 参见 https://varlock.dev/getting-started/installation/
开始使用:
- 运行
varlock init --agent,根据现有的.env/.env.example文件自动生成初始.env.schema - 与用户一起检查生成的架构 — init 的启发式结果只是草稿,并非最终版本
- 可选:安装此技能:
- skills(推荐):
npx skills add dmno-dev/varlock— 使用npx skills update varlock更新 - GitHub CLI(v2.90+):
gh skill install dmno-dev/varlock varlock— 使用gh skill update varlock更新
- skills(推荐):
架构检查清单
运行 init 后或编辑 .env.schema 时:
- 检查自动生成的条目 — 启发式结果并非最终版本
- 对名称含义不明确的条目添加描述注释
- 仅在值不是普通字符串时设置
@type(省略@type=string) - 根据需要标记
@required/@optional(或调整根级@defaultRequired) - 与用户确认是否为密钥、令牌和凭证设置了
@sensitive - 将有用的值移至
@example;删除虚假的占位值 - 在适当之处添加
@docs()链接 - 默认值移入架构后,从其他
.env文件中删除重复值
验证循环
更改架构后:
varlock load --agent
根据验证错误修复架构和已跟踪的环境变量文件。不要为了消除架构错误而修改被 git 忽略的 .local 值文件 — 请让用户在本地更新密钥。
CLI 快速参考
运行 varlock --help 或 varlock <command> --help 查看完整标志和选项。
| 命令 | 使用场景 |
|---|---|
varlock init --agent | 以非交互方式设置 varlock |
varlock load --agent | 安全地验证配置(JSON,敏感值会被隐藏) |
varlock load | 向用户显示易读的验证结果 |
varlock run -- <cmd> | 将解析后的环境变量注入进程 |
varlock printenv VAR_NAME | 将单个已解析的环境变量打印到标准输出 |
varlock reveal | 安全地查看 / 复制敏感值 |
varlock encrypt | 加密值(单个值,或使用 --file 批量加密) |
varlock scan | 扫描文件以查找泄露的密钥(提交前使用 --staged,使用 --install-hook 进行设置) |
varlock audit | 检测架构与代码用法之间的偏差 |
varlock codegen | 显式触发根据架构生成代码(通常会自动触发;typegen 是已弃用的别名) |
varlock lock | 锁定生物识别会话(下次解密时需要重新验证) |
varlock freeze | 在部署时解析一次并写入加密文件,应用启动时从该文件读取(运行时设置 _VARLOCK_USE_FROZEN_ENV=1) |
更新现有项目
将 .env.schema 作为事实来源。仅编辑 schema 和受 Git 跟踪的 .env.[env] 文件,不要编辑被 Git 忽略的 .local 文件。
- Schema 变更 — 在
.env.schema中添加、删除或重命名条目,更新代码以保持一致,然后运行varlock load --agent - 密钥 — 在 schema 中将敏感值留空;请用户在本地或密钥提供方中设置这些值
- 插件 — 在文件头部添加
@plugin(),并在可用时优先使用插件解析器,而非原始的exec() - 代码生成 — 默认情况下,加载时会运行
@generateTsTypes(以及其他@generate*Env装饰器);如果需要显式控制,请使用auto=false和varlock codegen - 提交前 — 运行
varlock load --agent,然后运行varlock scan --staged;如果重命名了键或怀疑存在偏差,请运行varlock audit
有关更深入的模式,请参阅 Schema、密钥和 Monorepos。
高级用法
- 多个环境:https://varlock.dev/guides/environments/
- 部署:框架集成会在构建时烘焙解析后的值;没有构建步骤的应用(Elysia、Hono、Fastify)使用
varlock freeze:https://varlock.dev/guides/frozen-env/ - 使用
@import拆分大型 schema:https://varlock.dev/guides/import/ - 设备本地加密:https://varlock.dev/guides/local-encryption/
package.json配置(varlock.loadPath):https://varlock.dev/reference/cli-commands/- 内置变量(用于自动检测环境的
$VARLOCK_ENV):https://varlock.dev/reference/builtin-variables/
文档
如需了解此技能之外的详细信息,请使用 AI 工具中已安装的 Varlock Docs MCP 工具,或从 https://varlock.dev/guides/schema 开始查阅。