chezmoi ejson 模板函数详解:`ejsonDecrypt` 与 `ejsonDecryptWithKey` 在 dotfiles 中的安全密钥解密实践
chezmoi ejson 模板函数详解ejsonDecrypt与ejsonDecryptWithKey在 dotfiles 中的安全密钥解密实践【免费下载链接】chezmoiManage your dotfiles across multiple diverse machines, securely.项目地址: https://gitcode.com/gh_mirrors/ch/chezmoi本篇技术指南聚焦 chezmoi 在模板中提供的ejson*模板函数族讲解如何从 ejsonShopify 开源的对称密钥加密格式加密文件中解密并提取结构化数据用于在 dotfiles 模板中安全注入密码、令牌等机密。读完本文你将掌握ejsonDecrypt与ejsonDecryptWithKey两个函数的使用方式、配置项keyDir/key的解析优先级、解密缓存机制以及如何在chezmoi.yaml与execute-template中实际落地这套加密工作流。ejson 与 chezmoi 的集成方式ejson 是 Shopify 开发的一种密钥管理工具其核心思路是使用非对称密钥对为 JSON 文件中的字段逐个加密加密后的字段以EJ[1:...]形式包裹文件顶部保留_public_key供加密使用而解密所需的私钥存放在独立的 key 目录中。这样包含机密的.ejson文件可以安全地提交到 dotfiles 仓库私钥则留在机器本地。chezmoi 在模板引擎中内置了对 ejson 的支持。在参考文档中明确指出ejson*函数用于返回 ejson 加密文件中的数据。从源码看这一能力实现在 ejsontemplatefuncs.go它直接调用 Shopify 官方的github.com/Shopify/ejson库中的ejson.DecryptFile完成解密因此只依赖 ejson 库本身无需安装额外的 ejson 命令行工具。模板函数一ejsonDecrypt函数签名与用途ejsonDecrypt *filePath*ejsonDecrypt返回一个 ejson 加密文件解密后的内容*filePath*指明加密文件所在位置。该函数的典型用法是在模板中直接取出解密 JSON 中的某个字段{{ (ejsonDecrypt my-secrets.ejson).password }}解密结果会被解析为 Go 的any即 JSON 反序列化后的 map/slice因此可以直接通过.字段名访问其中的结构化数据。这在 ejson.md 中也有同样的示例。解密缓存机制ejsonDecrypt会对解密结果进行缓存以filePath为 key解密一次后存入内存缓存后续对同一文件再次调用将直接命中缓存不再重复执行解密流程详见 ejsontemplatefuncs.go 中c.Ejson.cache的存取逻辑。这一设计在官方参考文档 ejsonDecrypt.md 中有明确说明。注意该缓存是与ejsonDecryptWithKey共享的即同一文件无论通过哪个函数首次解密另一个函数再调用时都会复用结果。私钥的查找路径ejsonDecrypt不使用调用方传入的密钥而是依赖配置中的ejson.keyDir定位私钥目录私钥文件名即加密文件中的_public_key值。其默认值解析逻辑位于 config.goEjson: ejsonConfig{ KeyDir: cmp.Or(os.Getenv(EJSON_KEYDIR), /opt/ejson/keys), },即若设置了环境变量$EJSON_KEYDIR则优先使用它否则回退到默认目录/opt/ejson/keys。配置项的完整说明见 variables.md.yaml。模板函数二ejsonDecryptWithKey函数签名与用途ejsonDecryptWithKey *filePath* *key*ejsonDecryptWithKey与ejsonDecrypt功能相同都返回 ejson 加密文件的解密内容但额外接受一个*key*参数——即用于解密的私钥由调用方在模板中显式指定而不再依赖 key 目录查找。典型用法{{ (ejsonDecryptWithKey my-secrets.ejson top-secret-key).password }}与ejsonDecrypt的异同对比维度ejsonDecryptejsonDecryptWithKey参数filePathfilePathkey私钥来源ejson.keyDir目录 /$EJSON_KEYDIR/ 默认/opt/ejson/keys调用方显式传入的key参数缓存按filePath缓存与ejsonDecryptWithKey共享按filePath缓存与ejsonDecrypt共享两者在实现上实际上是同一函数的不同入口ejsonDecrypt内部调用ejsonDecryptWithKeyTemplateFunc(filePath, c.Ejson.Key)把配置中的ejson.key作为密钥传入见 ejsontemplatefuncs.go。因此当你在配置中设置了ejson.key时ejsonDecrypt的行为等价于用该密钥调用的ejsonDecryptWithKey。配置项ejson.keyDir与ejson.key在chezmoi.yaml中可以通过ejson配置块控制解密行为ejson: # 存放私钥的目录默认 /opt/ejson/keys # 环境变量 $EJSON_KEYDIR 优先级更高 keyDir: /path/to/ejson/keys # 直接指定解密私钥设置后优先于 keyDir key: 4fed3b88a33a4621b30230f1ad17e175e10f8587e37e84da740711c9fecfe16d配置项语义依据 variables.md.yamlkeyDirstring私钥所在目录的路径。设置$EJSON_KEYDIR环境变量也会设置该值但优先级更低——即配置文件中的keyDir会覆盖环境变量。默认值为/opt/ejson/keys。keystring用于解密的私钥本身。一旦设置将取代keyDir的查找逻辑直接使用该密钥解密。对应地Config结构体中的ejsonConfig定义如下见 ejsontemplatefuncs.gotype ejsonConfig struct { KeyDir string json:keyDir mapstructure:keyDir yaml:keyDir Key string json:key mapstructure:key yaml:key cache map[string]any }实际落地在模板中使用 ejson 解密机密场景一默认 key 目录将私钥放到/opt/ejson/keys下文件名与.ejson文件中的_public_key一致然后在模板中直接解密examplePassword {{ (ejsonDecrypt my-secrets.ejson).password }}场景二指定密钥目录若私钥放在其他目录可通过配置或环境变量指定export EJSON_KEYDIR$HOME/.config/ejson/keys或在chezmoi.yaml中ejson: keyDir: $HOME/.config/ejson/keys场景三模板中显式传入密钥当不便依赖 key 目录例如密钥来自其他来源时用ejsonDecryptWithKey显式传参examplePassword {{ (ejsonDecryptWithKey my-secrets.ejson top-secret-key).password }}用execute-template快速验证在不实际应用模板的情况下可以直接用chezmoi execute-template命令验证解密是否成功这与仓库测试脚本 ejson.txtar 中的验证方式一致# 使用默认 /opt/ejson/keys未配置时解密失败报错提示 key 文件路径 chezmoi execute-template {{ (ejsonDecrypt my-secrets.ejson) }} # 通过环境变量指定 key 目录后解密成功 EJSON_KEYDIRgolden/keys chezmoi execute-template {{ (ejsonDecrypt golden/my-file.ejson).key1 }}源码与测试印证解密调用链整个解密流程的调用链清晰可循模板解析时chezmoi 将ejsonDecrypt/ejsonDecryptWithKey注册为模板函数注册位置在 config.go 的模板函数表中函数内部先检查c.Ejson.cache缓存命中则直接返回未命中时调用ejson.DecryptFile(filePath, keyDir, key)完成解密再用json.Unmarshal解析为结构化数据并写入缓存见 ejsontemplatefuncs.go另外ejsonDecrypt会调用chezmoi.SkipTemplateIf(c.skipSecrets)见 ejsontemplatefuncs.go即在--skip-secrets模式下会跳过机密解密防止敏感数据泄露到模板输出中。仓库中的集成测试 ejson.txtar 覆盖了完整的判定矩阵默认参数下未找到/opt/ejson/keys/...私钥时报错couldnt read key file错误信息中直接包含按_public_key拼出的私钥文件路径设置$EJSON_KEYDIR环境变量后ejsonDecrypt解密成功配置文件中的keyDir优先于环境变量EJSON_KEYDIR测试中同时设置二者结果采用配置值配置文件中的key有效时解密成功、无效时失败ejsonDecryptWithKey传入正确密钥时成功、传入非法密钥时失败且即便配置中的key无效显式传参也能绕过配置正常解密。测试数据 my-file.ejson 展示了 ejson 加密文件的真实结构——顶部是_public_key字段值以EJ[1:...]密文形式存在这正好印证了 ejson 逐字段加密的格式特征。小结ejsonDecrypt与ejsonDecryptWithKey是 chezmoi 模板中读取 ejson 加密机密的两个入口前者走keyDir目录/$EJSON_KEYDIR/配置key的解析链后者在模板中显式指定私钥两者共享按文件路径缓存同一文件在整个模板渲染进程中只解密一次且ejsonDecrypt在--skip-secrets模式下会被跳过配置优先级从高到低为ejsonDecryptWithKey的显式key参数 配置ejson.key 配置ejson.keyDir 环境变量$EJSON_KEYDIR 默认值/opt/ejson/keys私钥文件命名规则为_public_key值本身解密时 chezmoi 会拼接keyDir/_public_key查找密钥。将 ejson 加密文件提交到 dotfiles 仓库、把私钥留在本机配合这两大模板函数即可在不泄露明文机密的前提下让 chezmoi 在不同机器上安全地生成含密钥的配置。【免费下载链接】chezmoiManage your dotfiles across multiple diverse machines, securely.项目地址: https://gitcode.com/gh_mirrors/ch/chezmoi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

RocketMQ 客户端负载均衡机制深度解析:Producer 发送与 Consumer 订阅的全链路原理

RocketMQ 客户端负载均衡机制深度解析:Producer 发送与 Consumer 订阅的全链路原理

RocketMQ 客户端负载均衡机制深度解析:Producer 发送与 Consumer 订阅的全链路原理 【免费下载链接】rocketmq Apache RocketMQ is a cloud native messaging and streaming platform, making it simple to build event-driven applications. 项目地址: https://g…

2026/9/21 13:48:43 阅读更多 →
Pipenv 贡献开发指南:环境搭建、Owned vs Vendored 代码治理与测试体系全解析

Pipenv 贡献开发指南:环境搭建、Owned vs Vendored 代码治理与测试体系全解析

Pipenv 贡献开发指南:环境搭建、Owned vs Vendored 代码治理与测试体系全解析 【免费下载链接】pipenv Python Development Workflow for Humans. 项目地址: https://gitcode.com/gh_mirrors/pi/pipenv Pipenv 是"为人类设计的 Python 开发工作流"…

2026/9/21 13:47:35 阅读更多 →
使用 jax2tf 将 Flax MNIST 模型导出为 TensorFlow Lite:端侧图像分类完整实战指南

使用 jax2tf 将 Flax MNIST 模型导出为 TensorFlow Lite:端侧图像分类完整实战指南

使用 jax2tf 将 Flax MNIST 模型导出为 TensorFlow Lite:端侧图像分类完整实战指南 【免费下载链接】jax Composable transformations of PythonNumPy programs: differentiate, vectorize, JIT to GPU/TPU, and more 项目地址: https://gitcode.com/gh_mirrors/j…

2026/9/20 11:48:16 阅读更多 →

最新新闻

CANN ops-transformer FlashAttn 性能建模:D=256 下基本块 (M, N) 的选择与 Cube Bound 达成分析

CANN ops-transformer FlashAttn 性能建模:D=256 下基本块 (M, N) 的选择与 Cube Bound 达成分析

CANN ops-transformer FlashAttn 性能建模:D256 下基本块 (M, N) 的选择与 Cube Bound 达成分析 【免费下载链接】ops-transformer 本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-t…

2026/9/21 12:04:03 阅读更多 →
VSS横向扩展指南:如何把视频AI处理规模从单机扩展到生产级

VSS横向扩展指南:如何把视频AI处理规模从单机扩展到生产级

VSS横向扩展指南:如何把视频AI处理规模从单机扩展到生产级 【免费下载链接】video-search-and-summarization NVIDIA AI Blueprint for video search and summarization (VSS) is a GPU-accelerated reference architecture for building video analytics agents wi…

2026/9/21 12:02:56 阅读更多 →
MCP Python SDK 依赖注入实战:用 `Resolve` 让工具参数脱离模型幻觉

MCP Python SDK 依赖注入实战:用 `Resolve` 让工具参数脱离模型幻觉

MCP Python SDK 依赖注入实战:用 Resolve 让工具参数脱离模型幻觉 【免费下载链接】python-sdk The official Python SDK for Model Context Protocol servers and clients 项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk 在 MCP&#xff08…

2026/9/21 12:02:56 阅读更多 →
Foam for VS Code 深度指南:用 Markdown + Wikilinks 构建本地优先的个人知识库

Foam for VS Code 深度指南:用 Markdown + Wikilinks 构建本地优先的个人知识库

Foam for VS Code 深度指南:用 Markdown Wikilinks 构建本地优先的个人知识库 【免费下载链接】foam A personal knowledge management and sharing system for VSCode 项目地址: https://gitcode.com/gh_mirrors/fo/foam Foam 是一款运行在 VS Code 之内的…

2026/9/21 12:02:56 阅读更多 →
Nix 1.11 发布说明深度解读:确定性构建验证、Nix 表达式预取与沙箱命名统一

Nix 1.11 发布说明深度解读:确定性构建验证、Nix 表达式预取与沙箱命名统一

Nix 1.11 发布说明深度解读:确定性构建验证、Nix 表达式预取与沙箱命名统一 【免费下载链接】nix Nix, the purely functional package manager 项目地址: https://gitcode.com/gh_mirrors/ni/nix 导读 本文基于 Nix 官方发布说明 rl-1.11.md,系…

2026/9/21 12:01:54 阅读更多 →
Torchvision 内部代码同步脚本 fbcode_to_main_sync.sh 使用指南:将 fbsync 分支变更批量落地为开源 PR

Torchvision 内部代码同步脚本 fbcode_to_main_sync.sh 使用指南:将 fbsync 分支变更批量落地为开源 PR

计算机视觉深度学习图像处理数据集 【免费下载链接】vision Datasets, Transforms and Models specific to Computer Vision 项目地址: https://gitcode.com/gh_mirrors/vi/vision 点击查看 免费下载 本篇文章围绕 scripts/README.rst 所记载的唯一实用脚本 fbcode…

2026/9/21 12:01:54 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →