与任何主账号一样,服务账号可以向 Google 进行身份验证,获取 OAuth 2.0 访问令牌并调用 Google API。但是,此过程对于服务账号和用户的运作方式有所不同。
服务账号通过以下方式之一来进行身份验证:
短期服务账号凭据
以服务账号身份进行身份验证的最安全方法是以 OAuth 2.0 访问令牌的形式获取服务账号的短期有效凭据。默认情况下,这些令牌会在 1 小时后失效。
如果您需要为信任的服务账号授予对资源的有限访问权限,则短期有效服务账号凭据会很有用。与服务账号密钥等长期有效凭据相比,短期有效凭据还可以降低风险。
在许多情况下,这些凭据是自动获取的,您无需自行创建或管理这些凭据。下面是一些示例:
- 如果您运行 Google Cloud CLI 命令并添加
--impersonate-service-account
标志,则 gcloud CLI 会为服务账号创建短期有效凭据并使用这些凭据运行命令。 如果您将服务账号关联到 Compute Engine 虚拟机 (VM) 实例,则该实例上的工作负载可以使用 Cloud 客户端库访问 Google Cloud 服务。Cloud 客户端库使用应用默认凭据 (ADC) 来获取服务账号的短期有效凭据。
如需详细了解此过程,请参阅使用服务账号凭据对应用进行身份验证。
如果您配置了工作负载身份联合,则 Cloud 客户端库可以使用您的身份提供方提供的凭据生成短期有效的服务账号凭据。
您还可以使用 Service Account Credentials API 手动创建短期有效的凭据。例如,您可以创建一个为用户提供短期有效服务账号凭据的服务,以允许用户临时访问 Google Cloud 资源。
Service Account Credentials API 可以创建以下类型的凭据:
- OAuth 2.0 访问令牌
- OpenID Connect (OIDC) ID 令牌
- 自签名 JSON 网络令牌 (JWT)
- 自签名二进制 blob
如需了解详情,请参阅创建短期有效的服务账号凭据。
解读审核日志
Cloud Audit Logs 可帮助您回答针对您的 Google Cloud 资源“哪些用户何时在何处执行过哪些操作?”问题。
当您使用短期有效凭据来模拟服务账号时,大多数 Google Cloud 服务都会创建包含以下身份的日志条目:
- 短期有效凭据所要模拟的服务账号
- 创建短期有效凭据的身份
您可以使用这些日志条目来识别创建短期有效凭据的主账号以及该主账号模拟的服务账号。
如需查看显示服务账号模拟的审核日志条目示例,请参阅模拟服务账号来访问 Google Cloud。
自模拟
自模拟是指使用服务账号自己的凭据为服务账号生成新凭据。
Service Account Credentials API 禁止以下类型的自模拟:
使用服务账号的短期有效凭据为服务账号生成新访问令牌。
自签名 JSON Web 令牌 (JWT) 是此规则的例外情况:您可以使用服务账号的自签名 JWT 为服务账号生成新访问令牌。
使用服务账号的短期有效凭据对可用于调用以下 API 的二进制对象 (blob) 或 JWT 签名:
Google Cloud 禁止这种自模拟行为,因为它会使恶意操作者无限期地刷新被盗的令牌。
如果您尝试以某种禁止的方式使用自模拟,则可能会遇到以下错误:
FAILED_PRECONDITION: You can't create a token for the same service account that you used to authenticate the request.
如果遇到此错误,请尝试使用不同的凭据来为服务账号生成新的短期有效凭据,例如最终用户凭据或其他服务账号的凭据。
服务账号密钥
每个服务账号都与一个公钥/私钥 RSA 密钥对相关联。Service Account Credentials API 使用此内部密钥对创建短期有效的服务账号凭据以及为 blob 和 JSON Web 令牌 (JWT) 签名。此密钥对称为“Google 管理的密钥对”。
此外,您还可以创建多个公钥/私钥 RSA 密钥对(称为“用户管理的密钥对”),并使用私钥向 Google API 进行身份验证。此私钥称为“服务账号密钥”。
Google 管理的密钥对
Service Account Credentials API 以及 Google Cloud 服务(例如 App Engine 和 Compute Engine)使用由 Google 管理的密钥对来生成服务账号的短期凭据。
根据安全最佳实践,主动用于签名的 Google 管理的密钥会定期轮替。轮替过程具有概率性;新密钥的使用率随密钥的生命周期先逐渐上升,再逐渐下降。
由 Google 管理的密钥对中的私钥始终由第三方托管,您永远无法直接访问。
Google 管理的密钥对中的公钥可公开访问,因此任何人都可以验证使用私钥创建的签名。您可以通过多种不同格式访问公钥:
- X.509 certificate:
https://www.googleapis.com/service_accounts/v1/metadata/x509/SERVICE_ACCOUNT_EMAIL
- JSON Web 密钥 (JWK):
https://www.googleapis.com/service_accounts/v1/jwk/SERVICE_ACCOUNT_EMAIL
- 原始格式:
https://www.googleapis.com/service_accounts/v1/metadata/raw/SERVICE_ACCOUNT_EMAIL
如果您下载并缓存公钥,我们建议您将其缓存最多 24 小时,以确保您始终拥有当前密钥。无论您何时检索公钥,它都会在检索后至少 24 小时内有效。
用户管理的密钥对
您可为服务账号创建用户管理的密钥对,然后使用每个密钥对中的私钥向 Google API 进行身份验证。此私钥称为“服务账号密钥”。
Cloud 客户端库可以使用服务账号密钥自动获取 OAuth 2.0 访问令牌。您还可以使用服务账号密钥为 JWT 手动签名,然后使用签名的 JWT 请求访问令牌。如需了解详情,请参阅为“服务器到服务器”应用使用 OAuth 2.0。
每个服务账号最多可以有 10 个服务账号密钥。Google 只存储用户管理的密钥对的公开部分。
有几种不同的方法可用于为服务账号创建用户管理的密钥对:
- 使用 IAM API 自动创建用户管理的密钥对。Google 会生成公钥/私钥对;仅存储公钥;将私钥返回给您。
- 自行创建用户管理的密钥对,然后仅上传公钥。Google 永远看不到私钥。
用户管理的密钥是非常强大的凭据。 如需限制使用用户管理的密钥,您可以在组织、项目或文件夹中强制实施以下组织政策限制条件:
constraints/iam.disableServiceAccountKeyCreation
:禁止主账号创建用户管理的服务账号密钥。constraints/iam.disableServiceAccountKeyUpload
:禁止主账号上传服务账号的公钥。
如果您因使用工作负载身份联合而强制实施这些限制条件,请考虑将组织政策限制条件用于工作负载身份联合来指定允许哪些身份提供方。
用户管理的密钥的过期时间
默认情况下,当您创建用户管理的服务账号密钥时,该密钥永不过期。您可以通过为项目、文件夹或组织中所有新创建的密钥设置过期时间来更改此默认设置。 过期时间指定新创建的密钥有效的小时数。
如果您需要对要求提供服务账号密钥的系统进行临时访问,请使用过期时间。例如,在以下情况下请使用过期时间:
- 在非生产环境中为只能通过服务账号密钥进行身份验证的应用开发代码
- 使用只能通过服务账号密钥进行身份验证的第三方工具
在以下场景中,避免使用过期时间:
- 生产工作负载。在生产环境中,过期的服务账号密钥可能会导致意外的服务中断。请改为使用不会过期的密钥,并通过密钥轮替管理其生命周期。
- 需要永久访问权限的非生产工作负载,例如持续集成 (CI) 流水线。
- 会在指定时间后阻止使用密钥的密钥轮替系统。如需了解建议的密钥轮替策略,请参阅服务账号密钥轮替。
为了防止服务中断,我们建议您不要设置过期时间,除非 constraints/iam.disableServiceAccountKeyCreation
组织政策限制条件长时间存在。设置过期时间时,您还必须停止强制实施 constraints/iam.disableServiceAccountKeyCreation
限制条件。如需详细了解此限制条件,请参阅限制服务账号密钥的生命周期。
如需设置过期时间,请执行以下操作:
- 确定要在其中设置服务账号密钥的到期时间的项目、文件夹或组织。
- 添加组织政策,以强制实施
constraints/iam.serviceAccountKeyExpiryHours
限制条件。对项目、文件夹或组织强制实施此限制条款后,过期时间将应用于该父级资源中所有新创建的服务账号密钥。现有密钥不受影响。
过期时间以小时为单位。最佳做法是使用较短的过期时间,例如 8 小时、24 小时(1 天)或 168 小时(7 天)。较短的过期时间有助于确保您的团队拥有经过测试的密钥更新流程。从可满足您需求的最短过期时间开始,并仅在必要时延长该过期时间。