Cloud Identity・サービスアカウント・Workload/Workforce Identity Federation・IAM Allow/Deny・Conditions・Access Context Manager・PAM・組織ポリシーを、公式ベースの技術詳細と本番運用のリスク・落とし穴まで踏み込んで解説します。
GCP の Identity は 「誰が・どこから」 で 4 系統に整理されます。試験では 4 系統を即時に使い分けられる必要があります。
人間ユーザーをどう調達するかの基盤レイヤ。試験では GCDS = 同期、SSO = 認証委譲 の役割分離を問う設問が頻出。
roles/resourcemanager.organizationAdmin + 必要最小限の組織管理ロールを持つ別アカウントを使うSetIamPolicy 等の Super Admin 操作は Pub/Sub → Slack/PagerDuty 通知マシン用 ID。試験で最頻出のテーマであり、「鍵を発行しない」 設計を判断できるかが核。
これ以外の SA 鍵による直接認証 は使わない方針が公式推奨。
NAME@PROJECT.iam.gserviceaccount.comPROJECT_NUMBER-compute@developer.gserviceaccount.comPROJECT_ID@appspot.gserviceaccount.comservice-PROJECT_NUMBER@SERVICE.iam.gserviceaccount.com(Cloud KMS / Cloud Build 等が暗黙的に使う)roles/editor が自動付与されてきたdisable または最小化gcloud resource-manager org-policies enable-enforce \
iam.automaticIamGrantsForDefaultServiceAccounts \
--organization=ORG_ID
gcloud resource-manager org-policies enable-enforce \
iam.disableServiceAccountKeyCreation \
--organization=ORG_ID
# 例外プロジェクトを許可(フォルダ単位での上書き)
gcloud resource-manager org-policies set-policy /tmp/exception.yaml \
--folder=EXCEPTION_FOLDER_ID
iam.serviceAccounts.actAs / serviceAccountKeys.create の付与を厳格管理google.iam.admin.v1.CreateServiceAccountKey を 必ずアラート対象google.iam.policy.UnusedPermissionRecommender) で未使用鍵を定期削除外部マシンが SA 鍵なし で GCP API を呼ぶ仕組み。OIDC / SAML 2.0 / AWS Signature の 3 形式に対応。
--description に運用情報を残す。https://token.actions.githubusercontent.com) を Provider として登録。必ず attribute-condition で repository などを絞る こと(無条件で許可しない)。roles/iam.workloadIdentityUser を「特定 principal セット」に限定して付与。
principalSet://iam.googleapis.com/.../subject/repo:OWNER/REPO:ref:refs/heads/maingoogle-github-actions/auth@v2 で Pool / Provider / SA を指定。出力で access_token が短期発行される。sts.googleapis.com の Audit Log(Admin Activity)を必ず Sink に流す。# 1. Pool 作成
gcloud iam workload-identity-pools create github-pool \
--location=global \
--display-name="GitHub Actions pool"
# 2. Provider (OIDC) 追加(attribute-condition で repo を絞る)
gcloud iam workload-identity-pools providers create-oidc github-provider \
--workload-identity-pool=github-pool --location=global \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.ref=assertion.ref" \
--attribute-condition="attribute.repository == 'my-org/my-repo'"
# 3. SA に workloadIdentityUser を main ブランチのみで許可
gcloud iam service-accounts add-iam-policy-binding \
deploy-sa@PROJECT.iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/NUM/locations/global/workloadIdentityPools/github-pool/attribute.repository/my-org/my-repo"
外部 IdP の 人間ユーザー を Cloud Identity アカウントを作らずに GCP に連携。Workload と混同しないこと。
principalSet://... の人間プリンシパルprincipalSet://... のワークロードクレームroles/iam.securityReviewer + IAM Condition の期間制限ユーザーが SA として短期的に行動 する仕組み。試験で serviceAccountUser vs serviceAccountTokenCreator の使い分けは頻出。
| ロール | 何ができるか | 典型シナリオ |
|---|---|---|
roles/iam.serviceAccountUser |
SA を リソースに割り当てる(GCE VM / Cloud Run / Cloud Functions / GKE Pod の設定時) | 運用者が VM 作成時に既定 SA 以外の SA を選ぶ |
roles/iam.serviceAccountTokenCreator |
SA の access_token / id_token / signedBlob / signedJwt を発行(=impersonate) | 開発者が一時的に本番 SA として gcloud / API 操作 |
roles/iam.serviceAccountKeyAdmin |
SA 鍵の作成・削除 | 原則として誰にも付与しないことが推奨 |
roles/iam.workloadIdentityUser |
Workload Identity Federation でこの SA を借用 | WIF Pool の principalSet をこの SA に紐付ける |
# Alice が prod-deploy@PROJECT.iam.gserviceaccount.com として gcloud を実行
gcloud compute instances list \
--impersonate-service-account=prod-deploy@PROJECT.iam.gserviceaccount.com
# 監査ログには両方の identity が記録される:
# authenticationInfo.principalEmail = alice@example.com
# authenticationInfo.serviceAccountDelegationInfo = prod-deploy@...
serviceAccountTokenCreator だけを付与delegationInfo)IAM ポリシーは 「Deny → Allow」 の順で評価され、Allow は 加算式(どこかで許可されていれば通る)。
iam.allowedPolicyMemberDomains を併用Allow より 強制力が高い ポリシー。広域禁止・特権昇格防止・規制対応に必須。公式 Deny 概要
principalSet://goog/public:all)denyRules:
- description: "Protect security-audit SA from privilege changes"
deniedPrincipals:
- "principalSet://goog/public:all"
exceptionPrincipals:
- "principalSet://iam.googleapis.com/.../break-glass-group"
deniedPermissions:
- "iam.googleapis.com/serviceAccounts.setIamPolicy"
- "iam.googleapis.com/roles.delete"
- "iam.googleapis.com/serviceAccounts.delete"
denialCondition:
expression: "resource.matchTag('123/audit-protected', 'true')"
title: "Only protected SAs"
buckets.delete を組織全員に DenysetIamPolicy を Denyiam.serviceAccounts.actAs を限定グループ以外には Denyiam.roles.create / update をエンジニアグループに Deny し、Platform チームのみ許可description に 適用理由・ロールバック手順を明記CEL(Common Expression Language)で条件付き付与を表現。resource.type / request.time / request.auth / resource.matchTag() が中核。公式 Conditions 概要
| 属性 | 例 | 用途 |
|---|---|---|
resource.name | resource.name.startsWith("projects/_/buckets/finance") | 特定リソース限定 |
resource.type | resource.type == "storage.googleapis.com/Bucket" | リソース種別フィルタ |
resource.matchTag() | resource.matchTag("123/env", "prod") | タグベース制御 |
request.time | request.time < timestamp("2026-12-31T23:59:59Z") | 期間限定付与 |
request.auth.claims | 'group_admin' in request.auth.claims.groups | 外部クレーム参照 |
request.auth.access_levels | "accessPolicies/POLICY/accessLevels/japan_only" in request.auth.access_levels | Access Context Manager との連携 |
# 業務時間内のみ(JST 09:00-18:00、月-金)
request.time.getHours("Asia/Tokyo") >= 9
&& request.time.getHours("Asia/Tokyo") <= 18
&& request.time.getDayOfWeek("Asia/Tokyo") >= 1
&& request.time.getDayOfWeek("Asia/Tokyo") <= 5
# 日本国内 + 企業端末のみ(Access Context Manager の Access Level を利用)
"accessPolicies/123/accessLevels/japan_corp_device" in request.auth.access_levels
# 期限付き付与(2026 年末まで)
request.time < timestamp("2026-12-31T23:59:59Z")
# prod タグの付いたリソース以外に対して
!resource.matchTag("123/env", "prod")
# 特定バケットの prefix のみ
resource.name.startsWith("projects/_/buckets/team-foo-")
「誰が・どこから・どんな端末で」を束ねた Access Level を定義し、IAM Conditions / VPC SC から参照。BeyondCorp Enterprise の中核。公式 ACM ドキュメント
属性ベースの条件式(CEL ライク)。
device.encryption_statusdevice.os_type / os_versiondevice.is_corp_owned_deviceorigin.ip / origin.region_codelevels(他レベルとの AND/OR)CEL 式の自由記述。
device.encryption_status == "ENCRYPTED" && device.is_corp_owned_device && origin.region_code == "JP"
combiningFunction: AND/OR で表現過去 90 日 間に使われていない権限を検出し、より絞った推奨ロールを提示。
「過剰権限の自動棚卸し」用途。
Active Assist の一部。Cloud Asset Inventory と連動。
「X というプリンシパルが、Y というリソースに、Z という権限でアクセス可能か」を 解説付き で判定。
deny の原因を継承階層まで遡って表示。
「誰が・どのリソースに・どの権限を持っているか」の 網羅検索。
Cloud Asset Inventory のクエリ機能で、組織横断の権限棚卸しに必須。
| 聞かれていること | 選ぶツール |
|---|---|
| 「未使用権限を削減したい」 | IAM Recommender |
| 「なぜ Bob は deny されたのか」 | Policy Troubleshooter |
「組織内で pubsub.topics.publish を持つ全プリンシパル」 | Policy Analyzer |
| 「外部メンバーへの付与の有無を可視化」 | Policy Analyzer + Recommender |
特権ロールを 常時保有させず、申請 → 承認 → 自動付与 → 期限自動剥奪する Just-In-Time アクセスの仕組み。公式 PAM 概要
事前定義された Constraint または Custom Constraint(CEL)を組織 / フォルダ / プロジェクトに適用する仕組み。IAM が「許可」、組織ポリシーは「禁止 / 制限」。公式 OPS 概要
| Constraint | 目的 | 注意点 |
|---|---|---|
gcp.resourceLocations | リージョン / マルチリージョンの許可リスト | 新リージョン追加時は in:asia-locations 等の値グループの差分に注意 |
iam.disableServiceAccountKeyCreation | SA 鍵作成禁止 | 既存鍵には影響しない。鍵作成監視と組み合わせる |
iam.allowedPolicyMemberDomains | 許可ドメイン以外への IAM 付与禁止 | allUsers / allAuthenticatedUsers も同時にブロックされる |
compute.vmExternalIpAccess | 外部 IP 割り当て制限 | 例外 VM はリスト or タグで明示。Cloud NAT 必須 |
compute.requireOsLogin | OS Login 強制 | 既存 SSH 鍵が無効化されるので段階展開 |
compute.requireShieldedVm | Shielded VM 強制 | 非対応 OS イメージで作成失敗するので互換性確認 |
iam.automaticIamGrantsForDefaultServiceAccounts | 既定 SA への自動 Editor 付与を無効化 | 新規プロジェクトのみ。既存プロジェクトの既定 SA は別途修正 |
gcp.restrictNonCmekServices | CMEK でないサービス利用を禁止 | サポートサービスのリスト指定が必要 |
name: "organizations/ORG_ID/customConstraints/custom.gcsRequiresComplianceLabel" resourceTypes: - storage.googleapis.com/Bucket methodTypes: - CREATE - UPDATE condition: "resource.labels.compliance != ''" actionType: ALLOW displayName: "GCS buckets must have compliance label" description: "Buckets must declare a `compliance` label (pii / pci / public / internal)."
inheritFromParent: false で上書きiam.disableServiceAccountKeyCreation / iam.allowedPolicyMemberDomains / compute.vmExternalIpAccess を Enforce