颁发用于证明第三方身份的证书
本教程演示了如何使用身份反射和工作负载身份池颁发可证明第三方身份的证书。
您可以使用身份反射来创建与证书请求者的已验证身份匹配的证书。使用身份反射,您可以将非特权证书请求者限制为仅请求主题备用名称 (SAN) 与其凭据中的身份相对应的证书。
目标
本教程介绍了如何将 CA Service 与工作负载身份池结合使用,以联合第三方身份并获取可证明此身份的证书。
准备工作
在开始之前,请确保您了解以下概念:
- 工作负载身份池:借助工作负载身份池,您可以管理第三方身份提供方。如需了解详情,请参阅管理工作负载身份池和提供方。
- 工作负载身份联合:工作负载身份联合利用工作负载身份池向第三方身份授予对 Google Cloud 服务的访问权限。如需了解详情,请参阅工作负载身份联合。
- Security Token Service (STS):通过 Security Token Service,您可以使用第三方凭据交换第一方 (Google Cloud) 令牌。如需了解详情,请参阅安全令牌服务。
- 身份反射:身份反射功能可让证书请求者经过验证的身份继续进入所请求的证书。如需了解详情,请参阅身份反射。
确保您具有以下 IAM 角色:
- 如需管理证书授权机构 (CA) 和 CA 池以及请求证书,您必须拥有 CA Service Operation Manager (
privateca.caManager
) 角色。如需详细了解 CA Service 的 IAM 角色,请参阅使用 IAM 进行访问权限控制。 - 如需管理工作负载身份池和提供方,您必须拥有 Workload Identity Pool Admin (
iam.workloadIdentityPoolAdmin
) 角色。 - 如需创建服务帐号,您必须拥有 Service Account Admin (
iam.serviceAccountAdmin
) 角色。
如需了解如何授予 IAM 角色,请参阅管理对项目、文件夹和组织的访问权限。您可以将所需的 IAM 角色授予 Google 帐号、服务帐号、Google 群组、Google Workspace 帐号或 Cloud Identity 网域。
设置工作负载身份池和提供方
本教程介绍了如何将 Google OpenID Connect (OIDC) 提供方与服务帐号结合使用,以充当第三方身份。Google 帐号 OIDC 提供方充当第三方身份提供方 (IDP),Google Cloud 服务帐号是此 IDP 声明的第三方身份示例。
工作负载身份池支持各种身份提供方,包括 Microsoft Azure/本地 Active Directory、AWS 和基于 SAML 的身份提供方。
如需设置工作负载身份池和提供方,请执行以下操作: 1. 如需表示一组可信的联合身份,请创建工作负载身份池:
```
gcloud iam workload-identity-pools create IDENTITY_POOL_ID --location global --display-name "tutorial-wip"
```
Replace the following:
- <var>IDENTITY_POOL_ID</var>: The unique identifier of the new workload
identity pool.
为第三方身份提供方创建工作负载身份池提供方:
gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID --location global --workload-identity-pool IDENTITY_POOL_ID --display-name "tutorial-oidc" --attribute-mapping "google.subject=assertion.sub" --issuer-uri="https://accounts.google.com"
替换以下内容:
- PROVIDER_ID:您要在工作负载身份池中创建的身份提供方的唯一标识符。
您可以根据自己的用例自定义以下标志:
attribute-mapping
:此标志设置第三方声明与 Google 主账号声明google.subject
之间的映射。google.subject
是必需映射,您可以使用 CEL 表达式设置为任何声明或声明组合。如需了解详情,请参阅定义属性映射和条件。issuer-uri
:对于 OIDC 提供方,此标志是一个可公开访问的端点,Google 会与其联系以验证第三方令牌。如需了解详情,请参阅准备外部身份提供方。
如需详细了解如何设置工作负载身份提供方,请参阅配置工作负载身份联合。
创建 CA 池和颁发 CA
本部分介绍如何创建 CA 池并向其添加根 CA。您可以使用此 CA 池颁发身份反映证书。如果要使用现有 CA 池和 CA,则可以跳过本部分。
您也可以选择创建从属 CA,而不是根 CA。创建根 CA 有助于缩短该过程。
在 DevOps 层级中创建 CA 池:
gcloud privateca pools create CA_POOL_ID --location LOCATION --tier devops
替换以下内容:
- CA_POOL_ID - 颁发证书的 CA Service CA 池的 ID。
- LOCATION - CA 池的位置。
如需详细了解如何创建 CA 池,请参阅创建 CA 池。
创建根 CA:
gcloud privateca roots create CA_ID --pool CA_POOL_ID --location LOCATION --subject "CN=test,O=test-org"
替换以下内容:
- CA_ID - 颁发证书的证书授权机构的 ID。
- CA_POOL_ID - 颁发证书的 CA Service CA 池的 ID。
- LOCATION - CA 池的位置。
如需详细了解如何创建根 CA,请参阅创建根 CA。
允许从工作负载身份池联合的身份从 CA 池颁发证书。身份反射需要
CreateCertificate
请求者的 CA Service Workload Certificate Requester (roles/privateca.workloadCertificateRequester
) IAM 角色。您可以各种粒度表示工作负载身份池主帐号,从单个正文到各提供方在池中的所有身份。如需了解详情,请参阅可用的主账号或主账号集(使用 Google Cloud CLI 标签页),以便更好地满足您的使用场景。
gcloud privateca pools add-iam-policy-binding CA_POOL_ID --location LOCATION --role roles/privateca.workloadCertificateRequester --member "principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/*"
替换以下内容:
- PROJECT_NUMBER - 您在其中创建了工作负载身份池的项目的编号。
创建代表第三方身份的服务帐号
以下过程假定服务帐号代表第三方。本部分介绍如何使用 GenerateIdToken
IAM 端点以 OIDC 令牌的形式检索第三方身份。根据您的使用场景,您可能需要执行不同的步骤来获取您选择的第三方身份令牌。
gcloud iam service-accounts create SERVICE_ACCOUNT
替换以下内容:
- SERVICE_ACCOUNT - 代表第三方身份的服务帐号的 ID。
颁发证书以证明第三方身份
在开始之前,请确保您拥有 Service Account Token Creator (roles/iam.serviceAccountTokenCreator
) IAM 角色。您需要此 IAM 角色才能调用 GenerateIdToken
API。
如需获取可证明第三方身份的证书,请执行以下操作:
从您的第三方身份提供方获取第三方身份令牌。
curl
export ID_TOKEN=`curl -d '{"audience":"//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/providers/PROVIDER_ID"}' -H 'Content-Type: application/json' -H "Authorization: Bearer $(gcloud auth print-access-token)" https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com:generateIdToken | python3 -c "import sys;import json;print(json.load(sys.stdin)['token'])"`
替换以下内容:
- PROJECT_ID - 要在其中创建资源的项目的 Google Cloud 项目 ID。
客户端库
若要以编程方式访问第三方令牌,您可以从文件来源凭据或网址来源凭据中获取令牌。如需了解详情,请参阅使用客户端库、gcloud CLI 或 Terraform 进行身份验证。在本教程中,我们会遵循文件来源凭据工作流程。
将凭据加载到证书请求者读取的路径中:
curl -d '{"audience":"//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/providers/PROVIDER_ID"}' -H 'Content-Type: application/json' -H "Authorization: Bearer $(gcloud auth print-access-token)" https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com:generateIdToken | python3 -c "import sys;import json; print(json.load(sys.stdin)['token']) > /tmp/oidc_token.txt
替换以下内容:
- PROJECT_ID:您要在其中创建资源的项目的 ID。
使用 STS
token
端点将第三方令牌交换为联合 OAuth 令牌:curl
export STS_TOKEN=`curl -L -X POST 'https://sts.googleapis.com/v1/token' -H 'Content-Type: application/json' \ -d '{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/providers/PROVIDER_ID", "requested_token_type": "urn:ietf:params:oauth:token-type:access_token", "scope": "https://www.googleapis.com/auth/cloud-platform", "subject_token": "'$ID_TOKEN'", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt" }' | python3 -c "import sys;import json; print(json.load(sys.stdin)['access_token'])"`
客户端库
- 创建一个名为
oidc_token.txt
的凭据配置文件,请求代码证书可以读取该文件以执行令牌交换。
gcloud iam workload-identity-pools create-cred-config projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID --output-file=/tmp/cred_config.json --credential-source-file=/tmp/oidc_token.txt
- 读取
oidc_token.txt
文件以在客户端库中设置授权机制:
python
import json from google.auth import identity_pool with open('/tmp/cred_config.json', 'r') as f: json_config_info = json.loads(f.read()) credentials = identity_pool.Credentials.from_info(json_config_info) scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/cloud-platform'])
- 创建一个名为
使用
REFLECTED_SPIFFE
主题请求模式向 CA Service 发出请求:curl
可选:如果您没有 CSR,请通过执行以下命令来创建 CSR。
export TUTORIAL_CSR=$(openssl req -newkey rsa:2048 -nodes -subj / -keyout tutorial_do_not_use.key)
请求具有 CSR、生命周期和反映的主题请求模式的证书:
curl -H "Authorization: Bearer $(echo $STS_TOKEN)" https://privateca.googleapis.com/v1/projects/PROJECT_NUMBER/locations/LOCATION/caPools/CA_POOL_ID/certificates\?alt\=json -X POST -H "Content-Type: application/json" -H 'Accept: application/json' --data '{"lifetime": "100s", "pemCsr": "'$TUTORIAL_CSR'", "subjectMode": "REFLECTED_SPIFFE"}'
客户端库
如需将第一方令牌转发到 CA Service,您必须创建一个有凭据的客户端。然后,您可以使用此具有凭据的客户端发出证书请求:
启动存储了凭据的 CA Service 客户端:
python
caServiceClient = privateca_v1.CertificateAuthorityServiceClient(credentials=scoped_credentials)
请求证书。
Python
如需向 CA Service 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
验证证书。您的证书应具有一个包含单个 URI SAN 的主题。用于证明身份的 SAN 采用以下格式:
spiffe://IDENTITY_POOL_ID.PROJECT_NUMBER.global.workload.id.goog/subject/<oidc_subject_number>
您需要在其中:
- IDENTITY_POOL_ID:工作负载身份池的唯一标识符。
- PROJECT_NUMBER - 您在其中创建了工作负载身份池的项目的编号。
清理
为避免系统因您在本文档中创建的 CA 服务资源向您的 Google Cloud 帐号收取费用,请使用 Google Cloud CLI 执行以下操作:
删除您创建的 CA。
停用 CA:
gcloud privateca roots disable CA_ID --pool CA_POOL_ID --location LOCATION
您需要在其中:
- CA_ID:CA 的唯一标识符。
- CA_POOL_ID:CA 池的唯一标识符。
- LOCATION:CA 池的位置。
删除 CA:
gcloud privateca roots delete CA_ID --pool CA_POOL_ID --location LOCATION --ignore-active-certificates
您需要在其中:
- CA_ID:CA 的唯一标识符。
- CA_POOL_ID:CA 池的唯一标识符。
- LOCATION:CA 池的位置。
删除您创建的 CA 池。
gcloud privateca pools delete CA_POOL_ID --location LOCATION
您需要在其中:
- CA_POOL_ID:CA 池的唯一标识符。
- LOCATION:CA 池的位置。
如需详细了解
gcloud privateca pools delete
命令,请参阅 gcloud privatecaPool delete。删除您创建的工作负载身份池:
gcloud iam workload-identity-pools delete IDENTITY_POOL_ID --location global
您需要在其中:
- IDENTITY_POOL_ID:工作负载身份池的唯一标识符。
删除您创建的服务帐号:
gcloud iam service-accounts delete SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com
您需要在其中:
- SERVICE_ACCOUNT:工作负载身份池的唯一标识符。
- PROJECT_ID:拥有服务帐号的项目。
CA Service Workload Certificate Requester (privateca.workloadCertificateRequester
) IAM 角色将所颁发证书的主题限制为请求者的身份。确保只向使用身份反射功能的用户或工作负载授予 CA Service Workload Certificate Requester (privateca.workloadCertificateRequester
) IAM 角色。为了遵循最小权限原则,您可以避免授予 CA Service Certificate Requester (privateca.certificateRequester
) IAM 角色。
后续步骤
- 了解各种政策控制功能,它们可让您控制所请求证书的属性,使其不仅仅局限于反映的身份。
- 了解如何配置和管理各种政策控制措施。