如果您提供的产品或运营的服务允许客户分析或管理数据或资源,客户可能会想要访问其 Google Cloud 环境中的数据或其他资源。此类产品和服务的示例包括:
- 数据分析产品:您的客户可能希望使用此类产品分析 BigQuery 中的数据。
- CI/CD 产品和服务:您的客户可能会使用此类服务将基础架构和应用部署到其 Google Cloud 项目。
- 机器人流程自动化 (RPA):您的客户可能会将 RPA 用于工作流,例如在 Google Cloud 中创建项目、管理访问权限或自动执行管理任务。
为了使本地或软件即服务 (SaaS) 产品向 Google Cloud 进行身份验证,客户通常依赖服务账号密钥,但这些密钥可能难以安全地管理和存储。
作为本地或 SaaS 产品的供应商,您可以让客户使用工作负载身份联合来访问其 Google Cloud 资源,从而帮助保护客户的 Google Cloud 资源。已经允许其客户使用工作负载身份联合的服务包括 Terraform Cloud、GitHub 和 GitLab 等。
本文介绍如何扩展产品以支持工作负载身份联合,并介绍了您可以遵循的最佳实践。本文假定您熟悉工作负载身份联合和 OpenID Connect。
架构
工作负载身份联合可让您的客户将您的产品或服务与其 Google Cloud 环境联合,从而无需使用服务账号密钥。然后,您的客户可以使用您的产品或服务声明的身份来访问其 Google Cloud 资源。
为了让您的客户使用工作负载身份联合,您的产品或服务必须实现 OpenID Connect 的子集。具体而言,您必须允许工作负载获取符合以下条件的 ID 令牌:
- 该令牌标识您的产品或平台中的工作负载
- 该令牌标识您的产品或平台的实例、租户或安装
- 该令牌包含加密签名,工作负载身份联合可以使用该签名来验证令牌的真实性
使用要求
如需支持工作负载身份联合,您必须确保您的产品或服务满足以下要求:
工作负载可以访问有效的 ID 令牌。
在生命周期内,工作负载必须可以随时访问 ID 令牌,该 ID 令牌声明工作负载的身份并符合 OpenID Connect 1.0 定义的要求。
由于 ID 令牌的有效期有限,因此您必须确保 ID 令牌的寿命比工作负载更长,或者工作负载可以定期获取新的 ID 令牌。
ID 令牌唯一标识工作负载。
ID 令牌必须包含至少一个唯一标识工作负载的声明。工作负载标识符必须是不可变的。
对于支持多租户的产品或服务,令牌还必须至少包含一个唯一标识租户的声明。租户标识符也必须不可变。
ID 令牌已签名,但未加密。
OpenID 提供方元数据可公开访问,并且可从 ID 令牌发现。
您必须在可公开访问的端点上提供 OpenID 提供方配置文档,该文档可以使用 OpenID 颁发者发现协议发现。例如,如果 ID 令牌包含值为
https://service.example.com/v1/
的iss
声明,则您必须在https://service.example.com/v1/.well-known/openid-configuration
上提供 OpenID 提供方配置文档,并且端点必须可通过互联网从任何 IP 地址公开访问。签名密钥可公开访问,并且可以从 OpenID 提供方元数据发现。
您必须在可公开访问的端点上提供 JSON Web 密钥集 (JWKS) 文档,该文档可以从 OpenID 提供方元数据中的
jwks_uri
字段发现。
最佳做法
在扩展产品或服务以支持工作负载身份联合时,请考虑以下最佳实践。
最佳做法:
区分身份和访问令牌。以与客户端库兼容的方式公开 ID 令牌。
使用特定于租户的颁发者网址。
允许用户指定 ID 令牌目标对象。
在 ID 令牌声明中使用不可变且不可重复使用的标识符。
在 ID 令牌中包含上下文信息。
将 ID 令牌的生命周期限制为 30-60 分钟。
区分身份和访问令牌
在工作负载身份联合的上下文中,ID 令牌的用途是声明工作负载的身份:令牌必须包含足够的信息供工作负载身份联合用于识别工作负载以及将该工作负载与其他工作负载区分。
与 ID 令牌相比,访问令牌通常具有不同的用途:它们用于做出访问权限决策,并且可能包含有关工作负载具有哪些权限或允许访问哪些 API 的信息。
如果您的产品或服务目前使用访问令牌来实现让工作负载调用您产品的 API 这类目的,则这些访问令牌可能不适合工作负载身份联合。请考虑引入与 ID 令牌的定义匹配的第二类令牌并让工作负载将 ID 令牌用于工作负载身份联合,而不是更改访问令牌的用途并用作 ID 令牌。
以与客户端库兼容的方式公开 ID 令牌
Google Cloud 客户端库可以自动从多个来源获取 ID 令牌,包括:
- HTTP 端点(网址溯源凭据)
- 本地文件(文件溯源凭据)
如需从其他来源获取 ID 令牌,您的客户可能需要修改其代码,或部署其他工具或库。通过以与客户端库兼容的方式公开 ID 令牌,您可以避免此类额外的复杂性,并使您的客户可以更轻松地采用工作负载身份联合。
使用特定于租户的颁发者网址
工作负载 ID 令牌中嵌入的声明在产品或服务的特定实例中可能具有唯一性,但在产品或服务的多个实例中可能不是唯一的。例如,您的两个客户可能使用您的产品或服务部署工作负载,并无意中为这些工作负载分配了相同的名称和 ID。
工作负载身份联合会尝试验证 ID 令牌的颁发者网址 (iss
),并仅允许每个工作负载身份池中一个颁发者的令牌,以此来弥补这种缺乏唯一性的问题。
如果您的产品或服务支持多租户,则多个客户可能会共享产品或服务的单个实例,并且其工作负载的 ID 令牌可能使用相同的颁发者网址。在多个租户中使用相同的颁发者网址可能会让您的客户面临仿冒攻击。例如,作恶方可能会在自己的租户中创建工作负载,为其分配与受害者租户中的工作负载相同的 ID 或名称,并使用其工作负载的 ID 令牌仿冒受害者的工作负载的身份。
为了帮助保护您的客户免受仿冒攻击,请避免在多个租户中使用相同的颁发者网址,并在颁发者网址中嵌入唯一的租户 ID,例如 https://saas.example.com/tenant-123/
。
允许用户指定 ID 令牌目标对象
您客户的某些工作负载可能需要访问 Google Cloud 以及其他第三方服务。当客户决定将您的产品或服务与多个依赖方联合时,他们可能会发现工作负载的 ID 令牌被意外或恶意地用于错误的依赖方。例如,作恶方可能会诱骗工作负载泄露本应用于第三方服务的 ID 令牌,然后将该 ID 令牌用于工作负载身份联合。
为了帮助您的客户免遭此类混淆代理攻击,请避免在 ID 令牌中使用静态目标对象(aud
声明)。您可以让工作负载在获取 ID 令牌时指定目标对象,并视需要维护工作负载可以请求的目标对象的允许列表。
默认情况下,工作负载身份联合要求 ID 令牌的目标对象与网址 https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
匹配。确保工作负载可以使用网址作为 ID 令牌的目标对象,并且目标对象长度不得超过 180 个字符。
在 ID 令牌声明中使用不可变且不可重复使用的标识符
当客户希望向某个工作负载授予对 Google Cloud 资源的访问权限时,必须创建一个按主题、群组或自定义属性引用工作负载身份的 IAM 绑定。工作负载身份的主题、群组和自定义属性派生自工作负载 ID 令牌中的声明。
如果客户创建了引用可变声明的 IAM 绑定,则当声明的值变化时,他们的工作负载可能会意外失去访问权限。例如,客户可能会创建引用其工作负载名称的 IAM 绑定。如果随后重命名工作负载,则 IAM 绑定可能不再适用。
更糟糕的情况是,作恶方可能会故意重命名工作负载或修改工作负载的环境,以仿冒其他工作负载的身份,从而获得未经授权的资源访问权限。
为帮助客户防范此类仿冒问题,请确保 ID 令牌包含不可变且不可重复使用的标识符。
在 ID 令牌中包含上下文信息
客户可能希望限制工作负载,使工作负载仅在满足某些额外条件时才能获得 Google 凭据,而不是授予 Google Cloud 资源的无条件访问权限。
为了让客户能够配置此类限制,请在 ID 令牌中添加包含上下文信息的额外声明。上下文信息的示例包括:
- 拥有或启动工作负载的用户的信息
- 工作负载启动的原因和方式
- 工作负载当前正在处理的请求
将 ID 令牌的生命周期限制为 60 分钟
ID 令牌具有由 exp
声明决定的有限生命周期。当工作负载使用 ID 令牌执行令牌交换时,工作负载身份联合会验证该 ID 令牌的 exp
声明,并颁发一个 STS 令牌,这个 STS 令牌的有效时长与输入令牌相同,但不超过 1 小时。
使用有效期超过一小时的 ID 令牌不会影响工作负载身份联合,但如果 ID 令牌意外泄露,风险可能会增加。使用显著短于 1 小时的生命周期有助于降低此类风险,但可能会导致频繁的令牌交换和性能下降。
后续步骤
- 详细了解工作负载身份联合。
- 了解使用工作负载身份联合的最佳实践。