配置密钥管理
API7 企业版支持密钥提供商,可避免硬编码 API Key、SSL 证书和插件凭证等敏感数据。通过 $secret:// 引用语法 ,可以将外部系统中的密钥注入网关资源,同时保留密钥值在外部系统中。
密钥提供商通过 Admin API 创建和管理。ADC 不管理密钥提供商,但可以在支持的资源中使用 $secret://... 引用现有提供商的密钥。
前置条件
- API7 企业版实例正在运行。
- 已创建网关组且网关实例正在运行。
- 一个 Dashboard Token。
- 如果要测试网关完整的密钥解析流程,需要可用的密钥后端。
配置 HashiCorp Vault 密钥提供商
HashiCorp Vault 可用于管理密钥。可以在 API7 企业版中将其配置为密钥提供商。
启动 Vault 进行评估
如果已有 Vault 和 API7 企业版使用的受限 Token,可跳过本节。否则启动 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"。
创建网关策略和 Token
授予网关读取 kv/api7/* 的权限并创建受该策略限制的 Token:
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"
保存命令输出的 hvs.... Token,在下一步注册提供商时使用。
写入测试密钥
docker exec api7-quickstart-vault vault kv put kv/api7/demo key=demo-value
下面的在配置中引用密钥将展示如何将其作为 $secret://vault/my-vault/demo/key 使用。
注册 Vault 提供商
注册 Vault 时传入上一步生成的 Token。使用 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 Secrets Manager 文档创建密钥和具备读取权限的 IAM 凭据,然后注册提供商:
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 Secrets 文档创建 Secret 和具备 get 权限的 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 证书中使用密钥
你可以引用密钥提供商中的密钥,避免以明文存储私钥。
- Admin API
- ADC
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"
}'
ssls:
- id: example-com-ssl
snis:
- example.com
certificates:
- certificate: "$secret://vault/my-vault/ssl/cert"
key: "$secret://vault/my-vault/ssl/key"
在插件配置中使用密钥
例如,将 key-auth插件的 Key 存储在外部提供商中:
- Admin API
- ADC
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"
}
}
}'
consumers:
- username: user-1
credentials:
- name: user-1-key
type: key-auth
config:
key: "$secret://vault/my-vault/consumer/api-key"