news 2026/9/15 20:46:07

APISIX Secret 密钥管理实战:通过环境变量与 HashiCorp Vault 消除配置明文

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
APISIX Secret 密钥管理实战:通过环境变量与 HashiCorp Vault 消除配置明文

APISIX Secret 密钥管理实战:通过环境变量与 HashiCorp Vault 消除配置明文

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

导读

在 APISIX 网关的日常运维中,etcd 密码、Redis/Kafka 凭据、证书私钥、API 密钥以及各类插件的敏感配置字段,往往以明文形式散落在配置文件与 Admin API 请求体中,一旦泄露便意味着整个网关体系失守。APISIX Secret 是官方提供的敏感信息托管方案:它允许将密钥集中存放到环境变量或 HashiCorp Vault 等密钥管理服务中,在插件配置里仅写入$ENV://...$secret://...形式的引用变量,由网关在请求处理时按需解析真实值。读完本文,你将掌握 Secret 的两种存储方式的引用语法、完整的配置与调用步骤,并能结合源码理解其解析、缓存与容错机制,从而将明文密钥彻底从网关配置中剥离。

Secret 是什么:敏感信息的第一道防线

根据 terminology/secret.md 的定义,密钥(Secret)是指 APISIX 运行过程中所需的任何敏感信息,它可能是核心配置的一部分(如 etcd 的密码),也可能是插件中的一些敏感信息。APISIX 中常见的密钥类型包括:

  • 一些组件(etcd、Redis、Kafka 等)的用户名、密码
  • 证书的私钥
  • API 密钥
  • 敏感的插件配置字段,通常用于身份验证、hash、签名或加密

APISIX Secret 允许用户通过密钥管理服务(Vault 等)来存储密钥,在使用的时候根据 key 进行读取,确保密钥在整个平台中不以明文的形式存在。其整体工作流程如下图所示:

从图中可以看到完整的调用链:用户先在 Secret Manager 中创建密钥,随后在 APISIX 中创建 Secret 资源与路由;当真实请求到达网关时,APISIX 调用 Secret 组件向密钥管理服务发起请求获取密钥真实值,最后用该值完成请求校验(如鉴权、加密解密等)。

APISIX 目前支持以下两种密钥存储方式:

  • 环境变量
  • HashiCorp Vault

这两种方式都可以在任意插件的 consumer 配置中通过指定格式的变量来引用,例如key-auth插件。

:::note 关于未命中引用的行为

如果某个配置项为key: "$ENV://ABC",当 APISIX Secret 中没有检索到$ENV://ABC对应的真实值时,key 的值将是"$ENV://ABC"字符串本身,而不是nil。这一设计避免了因密钥缺失导致配置校验意外失败,但同时要求使用者务必确保引用变量的可解析性。

:::

使用环境变量管理密钥

使用环境变量来管理密钥,意味着你可以将密钥信息保存在环境变量中,在配置插件时通过特定格式的变量来引用。APISIX 支持引用两类环境变量:系统环境变量,以及通过 Nginxenv指令配置的环境变量。

引用语法

$ENV://$env_name/$sub_key
  • env_name:环境变量名称
  • sub_key:当环境变量的值是 JSON 字符串时,用于获取某个属性的值

如果环境变量的值是字符串类型,例如:

export JACK_AUTH_KEY=abc

则可以直接按变量名引用:

$ENV://JACK_AUTH_KEY

如果环境变量的值是一个 JSON 字符串,例如:

export JACK={"auth-key":"abc","openid-key": "def"}

则可以通过sub_key提取其中的属性:

# 获取环境变量 JACK 的 auth-key $ENV://JACK/auth-key # 获取环境变量 JACK 的 openid-key $ENV://JACK/openid-key

源码视角:$ENV:// 的解析过程

从源码看,环境变量 Secret 的实现位于 apisix/core/env.lua。模块初始化时通过 FFI 直接遍历进程的environ指针,把全部环境变量快照进apisix_env_vars表(见 env.lua#L44-L61);解析引用时(parse_env_uri)会先校验前缀$ENV://(大小写不敏感),再按/切分出keysub_key;取值时(fetch_by_uri)优先读内存快照、其次回退到os.getenv,若存在sub_key则对值做 JSON 解码后取对应属性。因此在 APISIX 实例启动前完成环境变量的注入至关重要——启动后新增的环境变量不会出现在快照中。

示例:在 key-auth 插件中使用环境变量

第一步:在 APISIX 实例启动前创建环境变量

export JACK_AUTH_KEY=abc

第二步:在key-auth插件中引用环境变量

你可以先从config.yaml中取出admin_key存入 shell 变量,便于后续调用 Admin API:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

然后通过 Admin API 创建 consumer 并引用环境变量:

curl http://127.0.0.1:9180/apisix/admin/consumers \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "username": "jack", "plugins": { "key-auth": { "key": "$ENV://JACK_AUTH_KEY" } } }'

通过以上步骤,key-auth插件中的 key 配置被保存在环境变量中,而不是在配置插件时明文显示。结合 apisix/plugins/key-auth.lua 的consumer_schema可以看到,该字段还声明了encrypt_fields = {"key"},即写入 etcd 时也会做加密存储,双重降低泄露风险。

使用 Vault 管理密钥

使用 Vault 来管理密钥,意味着你可以将密钥信息保存在 Vault 服务中,在配置插件时通过特定格式的变量来引用。APISIX 目前支持对接 Vault KV 引擎的 V1 版本。

引用语法

$secret://$manager/$id/$secret_name/$key
  • manager:密钥管理服务类型,可以是 Vault、AWS 等
  • id:APISIX Secret 资源 ID,需要与添加 APISIX Secret 资源时指定的 ID 保持一致
  • secret_name:密钥管理服务中的密钥名称
  • key:密钥管理服务中密钥对应的 key

源码视角:$secret:// 的解析与缓存

Secret 核心模块位于 apisix/secret.lua,其工作链路非常清晰:

  1. 前缀快筛fetch函数(secret.lua#L166-L185)先判断值是否以$开头,快速过滤普通明文配置,再根据前缀分派——$ENV://走环境变量解析,$secret://走密钥管理服务解析;
  2. URI 解析:parse_secret_uri 按/依次切分出managerconfidkey三段,任一缺失都会返回明确的格式错误;
  3. 配置定位secret_kv函数(secret.lua#L52-L65)从 etcd 的/secrets路径中按manager/id组合键找到对应的 Secret 资源配置;
  4. 服务分派:通过pcall(require, "apisix.secret." .. manager)动态加载对应的密钥管理服务模块,再调用其get(conf, key)接口(fetch_by_uri);
  5. LRU 缓存fetch_secrets(secret.lua#L214-L222)对解析结果使用 LRU 缓存,ttl = 300秒、容量count = 512,并以配置版本号作为缓存键的一部分,保证配置更新后缓存自动失效。

示例:在 key-auth 插件中使用 Vault

第一步:在 Vault 中创建对应的密钥

vault kv put apisix/jack auth-key=value

第二步:通过 Admin API 添加 Secret 资源

配置 Vault 的地址等连接信息(注意uri字段后的全角逗号应替换为半角逗号):

curl http://127.0.0.1:9180/apisix/admin/secrets/vault/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "uri": "https://127.0.0.1:8200", "prefix": "apisix", "token": "root" }'

如果使用 APISIX Standalone 版本,则可以在apisix.yaml文件中添加如下配置:

secrets: - id: vault/1 prefix: apisix token: root uri: 127.0.0.1:8200

:::tip 企业版命名空间

Secret 配置现已支持使用namespace字段设置 HashiCorp Vault Enterprise 和 HCP Vault 所支持的多租户命名空间概念,参见 admin-api.md 的 Secret 配置 body 请求参数。

:::

第三步:在key-auth插件中引用 APISIX Secret 资源

curl http://127.0.0.1:9180/apisix/admin/consumers \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "username": "jack", "plugins": { "key-auth": { "key": "$secret://vault/1/jack/auth-key" } } }'

通过以上操作,当用户请求命中key-auth插件时,会通过 APISIX Secret 组件获取到 key 在 Vault 中的真实值,配置文件中只保留引用变量。

Vault 对接的实现细节

Vault 的对接实现位于 apisix/secret/vault.lua,值得关注的细节包括:

  • Schema 校验:资源配置要求uriprefixtoken三个必填字段(vault.lua#L30-L45),namespace为可选字段,与 docs/zh/latest/admin-api.md 中 body 请求参数表一致;
  • 请求构造make_request_to_vault将请求路径规范化为{uri}/v1/{prefix}/{key},默认超时 5000ms(可通过conf.timeout覆盖),携带X-Vault-Token请求头;若配置了namespace,还会附加X-Vault-Namespace头(vault.lua#L51-L84);
  • Token 也支持引用:配置中的token会先尝试通过env.fetch_by_uri解析为环境变量引用,未命中时再回退为字面值,即 Vault token 本身也可以不落盘明文;
  • 键值提取get函数(vault.lua#L87-L117)以最后一个/为界,将引用切分为 KV 路径主键与子键,向 Vault 发起 GET 请求后从响应 JSON 的data字段中取出对应子键的值。

Secret 资源的 Admin API 管理

从源码看,Secret 资源的 Admin API 定义在 apisix/admin/secrets.lua,其资源名为secrets、kind 为secret,并声明unsupported_methods = {"post"}——即不支持 POST 创建,统一使用 PUT(幂等)写入。完整的请求地址与方法对照如下(摘自 admin-api.md):

名称请求 URI请求 body描述
GET/apisix/admin/secretsNULL获取所有 secret 的列表
GET/apisix/admin/secrets/{manager}/{id}NULL根据 id 获取指定的 secret
PUT/apisix/admin/secrets/{manager}{...}创建新的 secret 配置
DELETE/apisix/admin/secrets/{manager}/{id}NULL删除具有指定 id 的 secret
PATCH/apisix/admin/secrets/{manager}/{id}{...}更新指定 secret 的选定属性,删除某属性可将其值设为 null
PATCH/apisix/admin/secrets/{manager}/{id}/{path}{...}更新路径中指定的属性,其他属性保持不变

{secretmanager}vault时,body 请求参数为:

名称必选项类型描述例子
uriURIVault 服务器的 URI
prefix字符串密钥前缀
token字符串Vault 令牌
namespace字符串Vault 命名空间,无默认值admin

一个完整的使用示例:

curl -i http://127.0.0.1:9180/apisix/admin/secrets/vault/test2 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "uri": "http://xxx/get", "prefix" : "apisix", "token" : "apisix" }'

响应示例如下(当前响应由 etcd 返回):

{"key":"/apisix/secrets/vault/test2","value":{"id":"vault/test2","token":"apisix","prefix":"apisix","update_time":1669625828,"create_time":1669625828,"uri":"http://xxx/get"}}

可见 Secret 资源同样持久化于 etcd,idmanager/id组合而成,与$secret://manager/id/...引用中的前两段一一对应。

总结与最佳实践

APISIX Secret 通过统一的$ENV://$secret://引用语法,为环境变量和 HashiCorp Vault 两种密钥后端提供了透明、一致的接入方式,底层由 apisix/secret.lua 统一解析、分派并配合 LRU 缓存(5 分钟 TTL)降低高频请求下的外部依赖开销。在实战中建议遵循以下原则:

  • 能引则引:插件的敏感字段(鉴权 key、签名密钥、连接密码等)一律写成 Secret 引用,避免明文进入 etcd 与日志;
  • 优先 Vault:多实例、多团队场景下优先使用 Vault 等集中式密钥管理服务,便于轮换与审计;环境变量适合快速验证与轻量部署;
  • 启动前置:环境变量方式务必在 APISIX 实例启动前注入(源码会启动时快照 environ),Vault 的 token 也建议通过环境变量引用间接注入;
  • 善用缓存语义:Secret 的 LRU 缓存以配置版本号为键的一部分,更新 Secret 资源配置后新值会随版本变化自动生效,无需重启网关;
  • 保留兜底意识:若引用解析失败,配置项会保留原始$...字符串而非置空,排障时应先检查 Secret 资源是否存在、URI 格式是否正确、密钥管理服务是否可达。

相关的单元与集成测试可参考 t/admin/secrets.t,其中覆盖了 Secret 资源的 CRUD 与引用解析路径,可作为二次开发与回归验证的入口。

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 20:45:27

Escrcpy 投屏控制快速上手:3 步把安卓手机接进电脑

Escrcpy 投屏控制快速上手:3 步把安卓手机接进电脑 【免费下载链接】escrcpy 📱 Display and control your Android device graphically with scrcpy. 项目地址: https://gitcode.com/GitHub_Trending/es/escrcpy 每周三下午,总有一件…

作者头像 李华
网站建设 2026/9/15 20:44:32

高时效推荐系统实战:从离线批处理到实时流式架构升级

1. 内容整体设计与思路拆解1.1 高时效推荐系统到底在解决什么问题先说个很直接的场景。你晚上十点打开小红书,刷到一条刚发布二十分钟的露营攻略,点进详情页,评论区已经有人在问“这个营地周末还能订吗”。你顺手收藏,再往下滑&am…

作者头像 李华
网站建设 2026/9/15 20:44:06

curl命令实战指南:高频用法、进阶技巧与常见报错排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 20:43:52

Loop macOS 窗口管理上手:装好到桌面清爽,只需要 3 步

Loop macOS 窗口管理上手:装好到桌面清爽,只需要 3 步 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 按下触发键、光标往左一移、松手,窗口就贴进左半屏&#xff0c…

作者头像 李华
网站建设 2026/9/15 20:43:48

WinPE离线运维实战:从启动盘制作到顽固文件删除与系统备份

做运维或者帮人修电脑,最常见的一种绝望是:系统起不来了,数据还在里面,但登不进去、文件被占着删不掉、一开机就蓝屏,甚至杀毒软件还没跑起来就被反向干掉。这种时候,WinPE启动盘就是你挤进一块“病重硬盘”…

作者头像 李华
网站建设 2026/9/15 20:42:56

深圳网站建设制作开发公司避坑指南:看懂报价单再谈合作

深圳网站建设制作开发公司避坑指南:看懂报价单再谈合作 域名备案卡住进度,服务器配置选错导致网站卡顿,这些细节往往比代码更致命。很多老板在找深圳网站建设制作开发公司时,最头疼的不是价格高低,而是面对复杂的【建站报价】单,根本看不懂哪部分是必要开支,哪部分是隐形消费。…

作者头像 李华