凭据文件:识别、生成与吊销
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
先看 type:authorized_user、impersonated_service_account、external_account、service_account。
推荐做法#
- 常规本地开发用 ADC / impersonation;外部 workload 用 federation,尽量不创建 SA key。
- external_account 是获取/交换凭据的配置;其外部 token 来源必须有效。
- 密钥吊销在云端删除准确 key ID,并检查使用方与现有会话。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
SERVICE_ACCOUNT='REPLACE_SA_EMAIL'
gcloud iam service-accounts keys list \
--iam-account="$SERVICE_ACCOUNT" --project="$PROJECT_ID"容易踩的坑#
删除本地 JSON 或执行 gcloud auth revoke,不等于吊销云端 SA key。 必须在云端删除准确 key ID,并另行评估已签发短期凭据和使用方。
- 禁止创建 key 的 Organization Policy 不禁止已授权 impersonation,也不吊销现有 key。
配置说明与完整示例(按需展开)
先按 本地认证 选择认证方式,再来查文件格式。命令里的 READER 沿用 Bucket 实验;只查格式时无需执行密钥创建操作。
以下为删减过的格式示例,敏感字段使用占位值;真实文件由登录/配置工具生成,不能复制示例认证。
格式速查:authorized_user 是用户 ADC,impersonated_service_account 是 impersonated ADC,external_account 是 federated identity 配置,service_account 是长期 SA 密钥。
用户本地 ADC:authorized_user#
用户 ADC 保存 refresh token,用它换取用户短期 access token。
执行下列命令并在浏览器登录,gcloud 写入 默认 ADC 路径,无需手填字段:
gcloud auth application-default login{
"type": "authorized_user",
"client_id": "<OAUTH_CLIENT_ID>",
"client_secret": "<OAUTH_CLIENT_SECRET>",
"refresh_token": "<USER_REFRESH_TOKEN>",
"quota_project_id": "example-project"
}quota_project_id 是配额/计费归属项目,不代表限制只能访问该项目,也不授予访问权限。本地 ADC
Service Account impersonation 的本地 ADC:impersonated_service_account#
先完成 Bucket 实验 的 Token Creator 授权,再登录生成 impersonated ADC。它会覆盖默认 ADC;如设置了 GOOGLE_APPLICATION_CREDENTIALS,应用仍优先读取该变量指向的文件。
gcloud auth application-default login --impersonate-service-account="$READER"{
"type": "impersonated_service_account",
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/lab-reader@example-project.iam.gserviceaccount.com:generateAccessToken",
"source_credentials": {
"type": "authorized_user",
"client_id": "<OAUTH_CLIENT_ID>",
"client_secret": "<OAUTH_CLIENT_SECRET>",
"refresh_token": "<USER_REFRESH_TOKEN>"
},
"delegates": []
}source_credentials 用来证明原始调用者身份,service_account_impersonation_url 指明要申请哪个 SA 的短期凭据,delegates 为空表示没有中间委派的 SA。这种文件不含目标 SA 私钥,但仍包含敏感用户凭据,不能提交到 Git 或公开分享。impersonated credentials 字段
federated identity 配置:external_account#
下面以从文件读取外部 OIDC token 的 Workload Identity Federation 为例:credential_source 指定从哪里获取外部凭据,audience 指定目标 identity pool 提供方;没有 SA 私钥。
完整验证见 GitHub OIDC 文件实验,复用测试 Bucket,由 GitHub runner 取得真实 token。
先按 CI 实验配置 Pool、Provider、身份映射与授权。外部平台将 OIDC token 写入文件后,生成引用它的配置:
export PROJECT_NUMBER="$(gcloud projects describe "$PROJECT_ID" --format='value(projectNumber)')"
export POOL_ID='替换为已创建的Workload身份池ID'
export PROVIDER_ID='替换为该池中的Provider ID'
gcloud iam workload-identity-pools create-cred-config \
"projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID" \
--credential-source-file="/absolute/path/to/external-oidc-token.txt" \
--subject-token-type=urn:ietf:params:oauth:token-type:jwt \
--output-file=./workload-credentials.json
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/workload-credentials.json"命令只生成 JSON,不创建 Pool、授予权限或签发 token。external-oidc-token.txt 由外部 IdP / 平台获取并更新;若经 SA 访问,另加 --service-account="$READER",并授权 federated identity 使用该 SA。生成命令
{
"type": "external_account",
"audience": "//iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/<POOL_ID>/providers/<PROVIDER_ID>",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"token_url": "https://sts.googleapis.com/v1/token",
"credential_source": {
"file": "/absolute/path/to/external-oidc-token.txt"
}
}Workforce 的同类配置将 audience 换成 //iam.googleapis.com/locations/global/workforcePools/<POOL_ID>/providers/<PROVIDER_ID>,并通常包含 workforce_pool_user_project(配额项目编号)。外部凭据也可能来自 URL、可执行程序或 AWS 环境,因此 credential_source 结构会不同;部分流程还使用其他 type,此处不是所有格式的完整清单。Workforce 配置、Workload 配置
若使用已配置好的 Workforce identity pool 和文件来源的 OIDC token,则使用另一个生成命令;将下面的 identity pool ID、Provider ID、配额项目编号和 token 文件路径替换为实际值:
gcloud iam workforce-pools create-cred-config \
"locations/global/workforcePools/WORKFORCE_POOL_ID/providers/PROVIDER_ID" \
--credential-source-file="/absolute/path/to/workforce-oidc-token.txt" \
--subject-token-type=urn:ietf:params:oauth:token-type:jwt \
--workforce-pool-user-project="QUOTA_PROJECT_NUMBER" \
--output-file=./workforce-credentials.json
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/workforce-credentials.json"这同样只生成配置,外部用户 token 由企业 identity provider 的登录流程取得;它与浏览器交互登录使用的 login config 不同。Workforce 生成命令
Service Account 密钥:service_account#
使用 SA 私钥获取凭据;private_key 在真实文件中包含完整私钥。密钥格式
可选参考,IAM 实验无需创建长期 key。 优先使用用户 ADC、impersonation、绑定身份或 federation;仅在应用无法采用这些方式时考虑 key。
若 FAILED_PRECONDITION 指向 constraints/iam.disableServiceAccountKeyCreation,是 Organization Policy 禁止创建 key。2024-05-03 起创建的 Organization 默认强制此限制;本实验可直接跳过 key 创建。默认限制
该策略不限制已获授权的 impersonation,也不吊销现有 key。
具备 key 创建权限且 policy 允许时,可在 IAM & Admin → Service Accounts → 目标 SA → Keys → Add key → Create new key → JSON,或用下列命令新建。已有 key 的私钥无法再次下载。
# 可选:仅在明确需要长期密钥且策略允许时执行;常规本地实验跳过。
gcloud iam service-accounts keys create ./sa-key.json --iam-account="$READER"
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/sa-key.json"{
"type": "service_account",
"project_id": "example-project",
"private_key_id": "<KEY_ID>",
"private_key": "<PRIVATE_KEY_PEM>",
"client_email": "lab-reader@example-project.iam.gserviceaccount.com",
"client_id": "<SERVICE_ACCOUNT_NUMERIC_ID>",
"token_uri": "https://oauth2.googleapis.com/token"
}吊销需在云端删除 key。使用具备 iam.serviceAccountKeys.list/delete 的管理身份;若已切换到 reader,先切回管理账号并检查默认 impersonation。
# 只读取本地 JSON 的密钥 ID,不输出私钥;确认文件的 client_email 与 $READER 一致。
export KEY_ID="$(python3 -c 'import json; print(json.load(open("sa-key.json"))["private_key_id"])')"
gcloud iam service-accounts keys list --iam-account="$READER" --managed-by=user
# 核对列表中的 ID 后,永久删除这一把密钥;不会删除 Service Account 或其他密钥。
gcloud iam service-accounts keys delete "$KEY_ID" --iam-account="$READER"
gcloud iam service-accounts keys list --iam-account="$READER" --managed-by=user本地 JSON 已丢失时,从 keys list 或控制台 SA 的 Keys 页面确定目标密钥 ID,再手动设置 KEY_ID。删除后确认列表不再包含该 ID;仅删除本地 JSON、取消环境变量或执行 gcloud auth revoke 都不等于吊销云端密钥。已签发的短期凭据不会因删除密钥立即失效。删除密钥、delete 命令
云端删除成功后,若不再需要这份本地文件,再清理文件及指向它的环境变量:
rm ./sa-key.json
unset GOOGLE_APPLICATION_CREDENTIALS