跳到主要内容
版本:3.10.x

配置密钥管理

API7 企业版支持密钥提供方,可避免硬编码 API Key(API 密钥)、SSL 证书和插件凭证等敏感数据。通过 $secret:// 引用语法,可以将外部系统中的密钥注入网关资源,同时将密钥值保留在外部系统中。

密钥提供方通过 Admin API 创建和管理。ADC 不管理密钥提供方,但可以在支持的资源中使用 $secret://... 引用现有密钥提供方中的密钥。

前置条件

  • API7 企业版实例正在运行。
  • 已创建网关组且网关实例正在运行。
  • 按照从控制台获取令牌中的步骤准备一个令牌。
  • 如果要测试网关完整的密钥解析流程,需要可用的密钥后端。

配置 HashiCorp Vault 密钥提供方

HashiCorp Vault 可用于管理密钥。可以在 API7 企业版中将其配置为密钥提供方。

启动 Vault 进行评估

如果已有 Vault 和供 API7 企业版使用的受限令牌,可跳过本节。否则,请启动一个开发模式的 Vault 容器,并将 KV v1 引擎挂载到 kv/

docker run -d --cap-add=IPC_LOCK \
-e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \
-e 'VAULT_ADDR=http://127.0.0.1:8200' \
-e 'VAULT_DEV_ROOT_TOKEN_ID=api7-quickstart-vault-token' \
-e 'VAULT_TOKEN=api7-quickstart-vault-token' \
--name api7-quickstart-vault \
-p 8200:8200 vault:1.13.0

docker exec api7-quickstart-vault vault secrets enable -path=kv -version=1 kv

如果要改用 KV v2,请按以下方式调整上述步骤(一个挂载路径只能承载一个引擎,因此 v1 和 v2 不能共存于 kv/):

  • 使用 vault secrets enable -path=kv kv-v2 替代 -version=1 kv 命令启用引擎。
  • 策略路径使用 kv/data/api7/*,因为 KV v2 会将密钥存储在 <mount>/data/<path> 下。
  • 注册密钥提供方时设置 "kv_version": "kv-v2"

创建网关策略和令牌

授予网关读取 kv/api7/* 的权限并创建受该策略限制的令牌:

docker exec api7-quickstart-vault /bin/sh -c "echo '
path \"kv/api7/*\" {
capabilities = [\"read\"]
}
' > /etc/api7-policy.hcl"

docker exec api7-quickstart-vault vault policy write api7-policy /etc/api7-policy.hcl

docker exec api7-quickstart-vault vault token create -policy="api7-policy"

token create 命令会输出一个 hvs.... 令牌。请保存该值,并在下一步注册密钥提供方时使用。

写入测试密钥

在该前缀下存储一个密钥,以便网关能够解析实际内容:

docker exec api7-quickstart-vault vault kv put kv/api7/demo key=demo-value

下面的在配置中引用密钥将展示如何将其作为 $secret://vault/my-vault/demo/key 使用。

注册 Vault 密钥提供方

注册 Vault 时传入上一步生成的令牌。使用 host.docker.internal 而不是 127.0.0.1,确保该 URL(从网关容器内部访问时)解析到主机上的 Vault;在 Docker 容器中,127.0.0.1 指向网关自身。在 Docker Desktop 上该配置开箱即用;在 Linux 上运行 Docker 时,可以使用 --add-host=host.docker.internal:host-gateway 启动网关,或者将两个容器连接到同一用户自定义网络,并使用 Vault 容器名称(例如 http://api7-quickstart-vault:8200)。

curl -k "https://localhost:7443/apisix/admin/secret_providers/vault/my-vault?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-d '{
"uri": "http://host.docker.internal:8200",
"prefix": "kv/api7",
"token": "hvs.example-vault-token"
}'

配置 AWS Secrets Manager

如果基础设施运行在 AWS 上,可以使用 AWS Secrets Manager 存储 API 密钥。按照 AWS Secrets Manager 文档创建密钥和具有读取权限的 IAM 凭证,再使用得到的 access_key_idsecret_access_keyregion 注册密钥提供方:

curl -k "https://localhost:7443/apisix/admin/secret_providers/aws/my-aws?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-d '{
"access_key_id": "AKIAxxxxxxxx",
"secret_access_key": "xxxxxxxx",
"region": "us-east-1"
}'

配置 Kubernetes Secrets 密钥提供方

在 Kubernetes 原生部署中,可以直接使用 Kubernetes Secret 作为密钥提供方。按照 Kubernetes Secrets 文档创建 Secret 和对 secrets 资源具有 get 权限的 ServiceAccount,再使用集群 API Server 地址和 ServiceAccount 令牌注册密钥提供方:

curl -k "https://localhost:7443/apisix/admin/secret_providers/kubernetes/my-k8s?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"apiserver_addr": "https://kubernetes.default.svc",
"token": "example-service-account-token"
}'

在配置中引用密钥

使用 $secret://{provider_type}/{provider_id}/{secret_key} 语法引用密钥。

在 SSL 证书中使用密钥

你可以引用密钥提供方中的密钥,避免以明文存储私钥。

curl -k "https://localhost:7443/apisix/admin/ssls/example-com-ssl?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"snis": ["example.com"],
"cert": "$secret://vault/my-vault/ssl/cert",
"key": "$secret://vault/my-vault/ssl/key"
}'

在插件配置中使用密钥

密钥也可以用于插件凭证,例如 key-auth 插件的 key 字段(即 API Key):

curl -k "https://localhost:7443/apisix/admin/consumers/user-1/credentials/user-1-key?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "user-1-key",
"plugins": {
"key-auth": {
"key": "$secret://vault/my-vault/consumer/api-key"
}
}
}'

后续步骤