コンテンツにスキップ

📚 GCP PCA 学習: 2026-05-03

セクション: 3.1 セキュリティと IAM の設定 前回からの繋がり: 2.3 でコンピュートシステムを構築したら、次はそれを「誰が・どの範囲で・何ができるか」を制御するアクセス管理が必須。ビジネス継続性と同じくらい「セキュリティ侵害の被害最小化」が試験・実務では問われる。


① 一言サマリー

IAM(Identity & Access Management)とは、一言でいうと「人・アプリケーション・リソースの三者関係を定義し、アクセスをコントロールする仕組み」です。

② たとえ話

家の来客管理 で考えます。

  • 認証(誰か確認) = 玄関のインターフォン・免許証確認。「本当にその人か」を証明
  • 認可(何ができるか決定) = 各部屋の鍵。「Aさんは居間と台所、Bさんは客間のみ」という決め方
  • 監査ログ = 訪問者ノート。「何時に誰が何をしたか」を記録して後で検証

GCP では: - Identity(認証) = Google Account / Workload Identity / Service Account - Role(認可) = Editor / Viewer / Custom Role(何ができるかの権限セット) - Resource = VM / Cloud Storage / BigQuery


③ 図解

graph LR
    A["👤 Identity"] -->|"持つ"| B["📋 Role
roles/viewer etc"] A -->|"を通じて"| C["🔐 Service Account"] C -->|"アクセス"| D["☁️ Resource
Compute Engine
Cloud Storage
BigQuery"] E["🔍 IAM Policy
Principal + Role + Resource
+ Condition"] -->|"制御"| D F["📝 Cloud Audit Log
who did what when"] -->|"記録"| G["🔎 監視・コンプライアンス"]

ポイント: - IAM Policy = (Principal、Role、Resource、Condition)の 4 要素の組み合わせ - Service Account = 「人」ではなく「アプリケーションとして何ができるか」を定義する特殊な Identity - Condition = 「午前 9 時~17 時のみ」「東京リージョンからのアクセスのみ」という時間・場所制約


④ 仕組みの深掘り

4.1 IAM の三層構造

Human User (alice@example.com)
    ↓ 認証(Google Account / Federated Identity)
Service Account (app-backend@project-id.iam.gserviceaccount.com)
    ↓ 認可(IAM Binding)
    Role: roles/storage.objectViewer
         roles/bigquery.dataEditor
    ↓ リソース割り当て
    Resource: gs://my-bucket/
             projects/my-dataset/tables/events

4.2 IAM Binding の実装フロー

GCP では、ユーザーやサービスアカウントがリソースにアクセスするとき:

  1. 認証段階:リクエストに付属するトークン(Google OAuth2 / Workload Identity)の署名を検証
  2. 認可評価(Pre-Evaluation)
  3. IAM Policy を参照:「このプリンシパルがこのロールを持つか?」
  4. Condition を評価:「時間帯・IP・リソースラベル条件を満たすか?」
  5. 許可/拒否:すべての Condition を満たしたら ALLOW、1 つでも外れたら DENY

4.3 Role(ロール)の階層

Basic Roles(非推奨・過度な許可)
    ├─ roles/viewer      (Read-Only、すべてのリソースが見える)
    ├─ roles/editor      (Read-Write、すべてのリソースを操作)
    └─ roles/owner       (Read-Write + IAM 変更、管理者権限)

Predefined Roles(推奨・粒度の細かいロール)
    ├─ roles/compute.instanceAdmin    (Compute Engine VM 完全管理)
    ├─ roles/compute.osLogin          (OS ログイン・sudo 権限)
    ├─ roles/storage.objectViewer     (Cloud Storage Read-Only)
    ├─ roles/bigquery.dataEditor      (BigQuery のテーブル編集)
    └─ roles/iam.serviceAccountUser   (Service Account を impersonate する)

Custom Roles(ユースケース固有・細かい制御)
    └─ roles/projects/PROJECT-ID/customRole-DataAnalyst
         (BigQuery SELECT + Export、Storage Read のみ)

4.4 Service Account の生命サイクル

Service Account = 「ユーザーではなく、アプリケーションが持つ Identity」

  • 用途:Cloud Run コンテナ、Compute Engine VM、GKE Pod、Cloud Functions
  • 認証方法:
  • Key(非推奨・期限管理の手間) = JSON キーファイル(GCP 外でも使用可、流出リスク高)
  • Workload Identity(推奨) = Kubernetes / GitHub Actions からの自動認証(キーなし)
  • Service Account Impersonation = 別の Service Account に一時的に切り替える

コスト・セキュリティ観点: - Key は 90 日ごとにローテーション推奨(手作業では忘れられ、期限切れキーが残存) - Workload Identity Federation を使うと「キー不要」になり、GitHub Actions / AWS からの認証も可能


⑤ 他サービスとの使い分け

IAM vs Secret Manager vs KMS

サービス 役割 使う場面 コスト
IAM 「誰が何にアクセスできるか」を定義 ユーザー・アプリの権限管理 無料
Secret Manager DB パスワード・API キーを暗号化・保存 機密情報の安全な配布(自動ローテーション可) $0.06/秒(月 $1.6k)
KMS データの暗号化キー自体を管理 Cloud Storage / BigQuery / Compute Engine のデータ保護 $0.03/操作(月 $2k 以上)

使い分けの判断軸

graph TD
    A["機密情報を安全に
保存・配布したい?"] A -->|"Yes: DB pwd
API Key
JWT Secret"| B["👉 Secret Manager"] A -->|"No: リソースへのアクセス
制御が目的"| C["👉 IAM"] D["暗号化キーの管理が
必須?"] D -->|"Yes: 業界規制
HIPAA / PCI DSS"| E["👉 KMS"] D -->|"No: GCP Managed
Encryption で十分"| F["👉 Cloud Storage
Default Encryption"]

⑥ 実務への応用

Use Case 1: マルチテナント SaaS(顧客ごとに異なる BigQuery テーブルへのアクセス)

要件: - 顧客 A のアプリが顧客 A の Dataset のみを読み書きできる - 顧客 B は顧客 A の Dataset を見えない - 管理者は全テーブルを監視

実装

Service Account:
    - app-customer-a@project.iam.gserviceaccount.com
    - app-customer-b@project.iam.gserviceaccount.com

IAM Binding:
    - app-customer-a → roles/bigquery.dataEditor
      + Resource: projects/PROJECT/datasets/customer_a_dataset

    - app-customer-b → roles/bigquery.dataEditor
      + Resource: projects/PROJECT/datasets/customer_b_dataset

Cloud Run:
    ├─ customer-a-backend
    │  └─ Service Account: app-customer-a (自動アタッチ)
    │     → BigQuery リクエスト
    │        → IAM Policy Check: app-customer-a が customer_a_dataset にアクセス可能 ✓
    │
    └─ customer-b-backend
       └─ Service Account: app-customer-b
          → BigQuery リクエスト
             → IAM Policy Check: app-customer-b が customer_b_dataset にアクセス可能 ✓

Use Case 2: オンコール・サポートチームの時間制限付きアクセス

要件: - サポートエンジニアが本番環境の Compute Engine ログを見る必要があるが「営業時間内のみ」 - 夜間は自動的にアクセス不可

実装

IAM Policy with Condition:

Principal: support-team@example.com
Role: roles/logging.viewer
Resource: projects/PROD-PROJECT
Condition:
    request.time.getHours("Asia/Tokyo") >= 9
    && request.time.getHours("Asia/Tokyo") < 18
    && request.time.getDayOfWeek("Asia/Tokyo") in [1, 2, 3, 4, 5]
    (月~金、9:00~18:00 のみ)

Use Case 3: 開発チームの段階的な権限昇格(Dev → Staging → Prod)

Developer Team Service Accounts:

dev-app@PROJECT
  ├─ Binding: roles/compute.instanceAdmin
  │   Resource: projects/dev-project (Dev 環境は自由に操作)
  ├─ Binding: roles/compute.osLogin
  │   Resource: projects/dev-project
  └─ Binding: roles/monitoring.metricWriter
      Resource: projects/dev-project

staging-app@PROJECT
  ├─ Binding: roles/compute.instanceViewer
  │   Resource: projects/staging-project (Staging は Read-Only)
  └─ Binding: roles/logging.viewer
      Resource: projects/staging-project

prod-app@PROJECT
  ├─ Binding: roles/monitoring.viewer (監視のみ)
  │   Resource: projects/prod-project
  └─ Note: 本番デプロイは CD パイプラインのみが実行
           (Developer は直接アクセス不可)

⑦ よくある誤解・落とし穴

誤解 1: 「Basic Role(Editor / Viewer)を使っていれば大丈夫」

間違い

user@example.com
  ├─ Binding: roles/editor
  │   Resource: projects/PROD-PROJECT  ← すべてのリソースを操作可能
  └─ リスク:誤操作で本番 DB を削除しても権限がある

正解

user@example.com
  ├─ Binding: roles/compute.instanceViewer
  │   Resource: projects/PROD-PROJECT  (見るだけ)
  └─ Binding: roles/logging.viewer
      Resource: projects/PROD-PROJECT  (ログ確認のみ)

PCA 試験での問われ方

本番環境の監視チームに最小限の権限を与えるべき。以下のうち正しいのは? A. roles/editor (全リソース操作)✗ B. roles/viewer (すべてを見えてしまう)✗ C. roles/monitoring.viewer + roles/logging.viewer ✓

誤解 2: 「Service Account Key をコードに埋め込んでいる」

間違い

# secret-key.json を GitHub に commit
with open('secret-key.json') as f:
    creds = json.load(f)

client = storage.Client(credentials=creds)

→ キーが流出すると、誰でもリソースにアクセス可能

正解

# Workload Identity Federation(キーなし)
from google.auth import default

credentials, project = default()
client = storage.Client(credentials=credentials)
# GCP は自動的に環境から credential を検出

誤解 3: 「VPC Service Controls があれば IAM の設定は甘くてもいい」

間違い

IAM Policy: roles/editor (誰でも)
VPC Service Controls: Perimeter でブロック

→ VPC 内の Workload は制限されるが、
  VPC 外からのアクセスは IAM だけが守り手
  → VPC バイパス / API アクセスには効かない

正解

IAM Policy: roles/bigquery.dataViewer (最小限)
  + Condition: IP は社内 Range のみ
VPC Service Controls: Perimeter で多層防御

→ 両方で守って、防御層を二重化

誤解 4: 「複数リージョンで同じ Service Account を使い回す」

⚠️ 問題

app-backend@PROJECT.iam.gserviceaccount.com
  ├─ 東京リージョン: Cloud Run
  ├─ シンガポール: GKE
  └─ すべてのリソースに同じ権限が付与される

→ 1 つのリージョンのキーが漏洩 → すべてのリージョンが被害

ベストプラクティス

app-backend-tokyo@PROJECT
  └─ roles/storage.objectViewer → gs://bucket-tokyo-*

app-backend-singapore@PROJECT
  └─ roles/storage.objectViewer → gs://bucket-singapore-*

→ リージョン・目的別に Service Account を分離
   漏洩時の被害範囲を限定


⑧ 理解度チェック

シナリオ:マルチテナント SaaS を運用しており、顧客 A と顧客 B が異なる BigQuery Dataset を使用しています。顧客 A のアプリケーションが顧客 B の Dataset にアクセスされてはいけません。また、オンコール管理者は緊急時のみすべてのデータを参照できる必要があります。

問い: 1. 各顧客のアプリケーションのために、どのような IAM 構成を設計しますか?(Service Account、Role、Condition を含めて) 2. オンコール管理者の権限はどのように制限しますか?(時間・IP・リソースラベル) 3. 監査ログを使ってこの構成が正しく動作していることを検証する方法を述べてください。

期待される答え: - 顧客ごとに分離した Service Account(app-customer-a、app-customer-b) - 各 Service Account に roles/bigquery.dataEditor を、該当 Dataset のみに付与 - 管理者に roles/bigquery.admin を付与するが、Condition で「営業時間外は無効」または「Justification(事由)が記録される」構成 - Cloud Logging で protoPayload.methodName = "jobservice.insert" のフィルタ + 月次レビュー


⑨ 深掘り補足(PCA 試験範囲外・実務応用)

9.1 IAM Insights(権限分析・オーバープロビジョニング検出)

🆕 GA サービス(2025 年後半 GA)

IAM Insights を使うと、付与されている権限の中で「実際に使われていない権限」を自動検出。

Before(過度な権限):
    user@example.com
      └─ roles/editor (100+ 権限を持つ)
         実際に使用: SELECT / INSERT のみ
         → 99% の権限は unused

After(IAM Insights での最適化):
    user@example.com
      └─ Custom Role: "DataAnalystLimited"
         ├─ bigquery.datasets.get
         ├─ bigquery.tables.get
         ├─ bigquery.tables.getData
         └─ bigquery.tables.updateData
         使用: 100%

使用例

gcloud iam insights list-used-permissions --principal=user@example.com
# 実際に使われている権限のリストを出力

9.2 Resource-based Policy vs Identity-based Policy

GCP は Identity-based Policy(IAM)が主流ですが、Cloud Storage と BigQuery は Resource-based Policy もサポート。

Identity-based(GCP 主流):
    alice@example.com → IAM Policy → リソース A, B, C にアクセス可能

Resource-based Policy(Cloud Storage など):
    gs://my-bucket/
      └─ Bucket Policy: "このバケットに alice@example.com が読み取り可能"

どちらを使う?: - 単一プロジェクト内 → IAM で統一(管理が単純) - 複数プロジェクト・複数組織 → Resource-based Policy + Organization Policy で多層化

9.3 Service Account Impersonation(一時的な権限昇格)

Service Account A が Service Account B に「なりすます」仕組み。

Scenario: CI/CD パイプラインが本番デプロイ時だけ高い権限が必要

Before(常時高い権限):
    ci-pipeline@PROJECT
      └─ roles/compute.admin (常に本番リソース操作可能)

After(Impersonation で分離):
    ci-pipeline@PROJECT
      ├─ roles/iam.serviceAccountUser (on deploy-sa のみ)
      └─ 普段: roles/logging.viewer(ビルドログ確認)

    deploy-sa@PROJECT
      └─ roles/compute.admin
         └─ 使用: 本番デプロイ時のみ、ci-pipeline がここに impersonate

gcloud での実装

# ci-pipeline が deploy-sa になりすます(一時的)
gcloud config set auth/impersonate_service_account deploy-sa@PROJECT.iam.gserviceaccount.com

# 以降の gcloud コマンドはすべて deploy-sa の権限で実行
gcloud compute instances list  # 本番 VM が見える


次回: 3.2 法令遵守の設計(GDPR / HIPAA / PCI DSS への対応、監査アーキテクチャ)