弱点補強: VPC Service Controls × IAP Context-Aware Access — Service Perimeter不在(個人GCPプロジェクトへPII持ち出し自由)→bigquery.googleapis.com/storage.googleapis.comにPerimeter × クロスプロジェクト連携未整理→両プロジェクトを同一Perimeterに包含 × いきなりenforce計画→Dry-run段階移行 × VPN固定IPアリストのみ→IAP+Access Level(デバイスポリシー) × 個人付与のIAP権限→グループ付与+四半期棚卸し × IPのみのAccess Level→ip_subnetworks+regions+device_policy AND条件 × VPC_SC_DENIED無アラート→ログベースメトリクス+通知(MOps 会員360度ビュー PIIデータ持ち出し防止・管理コンソールゼロトラスト化 Bad→Good 7点)

2026-08-02 (Day 84) 日曜 弱点補強 ★★★★☆ GCP Access Context Manager / VPC Service Controls Identity-Aware Proxy / BeyondCorp Enterprise

概要

🧱

IAMとVPC-SCは直交する2つの防御層

IAMは「誰が・何に」アクセスできるかを制御するが、正規の権限で見えたデータを境界の外へ持ち出せるかは別問題。列・行レベルセキュリティ(07-29)で「見せる/見せない」を固めても、EXPORT DATA/bq cpでの持ち出しは塞がれない。

🧪

Dry-runは本番断ち切りを避ける必須ステップ

use_explicit_dry_run_spec = true で数週間実運用させ、想定外のブロック(=設計漏れの通信経路)を洗い出してからstatusへ昇格する。いきなりenforceにすると正当な業務フローごと止まるリスクがある。

🔐

IAPは「接続元」ではなく「接続元の状態」を評価する

従来のVPN+IPアリストは送信元IPしか見ない。Access Levelのdevice_policyはOSパッチ・暗号化状態・画面ロック・会社支給端末かどうかまで評価対象にできる。

👥

アクセス権限は個人ではなくグループに付与する

roles/iap.httpsResourceAccessorを個人アカウントへ直接付与すると異動・退職のたびに削除漏れが起きやすい。IdP同期グループへ付与し、四半期Access Reviewを運用に組み込むことで権限残存を構造的に防ぐ。

問題

MOps チームは 07-29 に会員360度ビューへ Data Catalog ポリシータグ・動的マスキング・行レベルセキュリティ(ROW ACCESS POLICY)を導入し、BigQuery内部の列・行単位のPIIガバナンスを固めた。しかし今回、社内セキュリティ監査で次の指摘を受けた。

「IAMロールで bigquery.dataViewer を持つ社員であれば、認証さえ通れば自分の個人GCPプロジェクトへ EXPORT DATAbq cp でPIIデータをそのままコピーできてしまう。列・行レベルのアクセス制御は『見せる/見せない』は制御できても、『正規の権限で見えたデータをどこに持ち出せるか』は一切制御できていない。」

さらに、社外(自宅・カフェ等)から BigQuery Console や社内Admin UI(Looker Studio埋め込みダッシュボード)へのアクセスは、VPNクライアント経由の固定IPアリストのみで許可されており、端末がOSアップデート済みか・ディスク暗号化されているか等のデバイス状態は一切検証されていない(VPNさえ繋がれば私物PCからでもアクセス可能)。この2つの構造的な欠陥について、7つの問題点を洗い出し、VPC Service Controls(Service Perimeter)と Identity-Aware Proxy(Context-Aware Access)を使って改善せよ。

制約・前提条件

  • GCP組織構成: mops-prod(BigQuery/GCS本番), mops-analytics(Looker Studio/dbt実行基盤)の2プロジェクトが日常的にデータをやり取りする(dbt Mesh cross-project ref、07-22 参照)
  • 保護対象サービス: bigquery.googleapis.com, storage.googleapis.com
  • 管理コンソール: 社内Admin UI(Cloud Run上でホスト、IAP未導入)、BigQuery Console
  • Access Context Manager が利用可能(組織ポリシー管理者権限あり)
  • Terraform 1.8+, google-beta provider(Access Context Manager系リソースはbetaを含む)
  • 現状: VPC Service Controls不在で境界外へ自由に持ち出し可能/クロスプロジェクト連携未整理/いきなりenforce計画/VPN固定IPアリストのみでデバイス状態未検証/IAP権限の個人付与+棚卸し未実施/Access LevelがIPのみ/VPC_SC_DENIEDにアラートなし
期待する回答形式: 問題点の列挙(番号付き)+ 改善後 Terraform構成(Access Context Manager / Service Perimeter / IAP)+ 適用・検証コマンド + 設計意図の説明

悪い構成 (Before)

この構成には 7つの構造的な問題 が隠れています。見つけてみてください。
現状 — VPC Service Controls不在・管理コンソールはVPN+固定IPのみ
# 問題①: VPC Service Controlsそのものが存在しない
# → mops-prod の bigquery.dataViewer を持つ全員が、
#   個人プロジェクトへ EXPORT DATA / bq cp で自由にPIIデータを持ち出せる
# 問題②: mops-prod/mops-analytics間のdbt Mesh連携経路も未整理のまま
# 問題③: 導入するとしてもいきなりenforceで有効化する計画(影響範囲の事前可視化なし)

resource "google_cloud_run_v2_service" "admin_console" {
  name     = "mops-admin-console"
  location = "asia-northeast1"
  ingress  = "INGRESS_TRAFFIC_ALL"    # 問題④: VPNさえ繋がれば私物PCからも到達可能
  template {
    containers {
      image = "asia-northeast1-docker.pkg.dev/mops-prod/admin/console:1.2.0"
    }
  }
}
# デバイスの暗号化状態・OSパッチ適用状況は一切検証されない

# 問題⑤: IAM権限を個人アカウントへ直接付与(棚卸し運用なし)
resource "google_cloud_run_v2_service_iam_member" "invoker" {
  for_each = toset([
    "user:taro.yamada@example.com",
    "user:hanako.sato@example.com",   # 実は半年前に異動済み → 権限残存
  ])
  name   = google_cloud_run_v2_service.admin_console.name
  role   = "roles/run.invoker"
  member = each.value
}
# 問題⑥: アクセス条件を作るとしてもIPアドレスのみで、地理的異常アクセスを検知できない
# 問題⑦: VPC_SC_DENIED監査ログにアラート設定がなく、予兆・誤設定に気づけない
問題点サマリー(7点)
1Service Perimeter不在で境界外へ自由に持ち出せる — IAM権限があれば個人プロジェクトへEXPORT可能
2mops-prod/mops-analytics連携経路が未整理 — 境界を作ると正当なdbt Mesh連携ごと遮断される懸念
3いきなりenforceで有効化する計画 — 影響範囲の事前可視化なしで本番障害リスク
4VPN固定IPアリストのみでデバイス状態未検証 — 私物PCでもVPN経由なら到達可能
5IAP/IAM権限が個人アカウントへ直接付与 — 異動・退職者の権限残存(棚卸し運用なし)
6Access LevelがIPのみ — 地理的異常アクセス(深夜の海外IP等)を検知できない
7VPC_SC_DENIED監査ログにアラートなし — 攻撃の予兆・設定ミスに気づけない

ヒント(段階的開示)

ヒント1 — 方向性
問題は2つの防御層の欠如に分類できる。(1) データの持ち出し(Exfiltration)を防ぐネットワーク境界の欠如 — IAMは「誰が」「何に」アクセスできるかしか制御できず、「アクセスできたデータをどこへ運べるか」は制御できない。VPC Service Controls は API 呼び出しレベルで境界(Perimeter)を張り、境界外への EXPORTCOPY 等をブロックする、IAMとは独立したもう一段の防御層。(2) 管理コンソールへの接続元の信頼性検証の欠如 — 従来のVPN+IPアリストは「どこから来たか」しか見ておらず、「その端末が信頼できる状態か」(パッチ適用済み・暗号化済み等)を見ていない。IAP の Context-Aware Access(Access Level)は、IP・地域・デバイスポリシーを組み合わせた条件をリクエスト単位で評価する。どちらも「一度信頼したら無条件に許可し続ける」のではなく、アクセスのたびに複数条件を再評価するゼロトラストの考え方が共通軸になる。
ヒント2 — アプローチ
  • 問題①: VPC Service Controls不在 → google_access_context_manager_service_perimeterbigquery.googleapis.com/storage.googleapis.com を対象に Perimeter を作成し、境界外への EXPORT/COPY をブロックする
  • 問題②: mops-prod/mops-analytics間の正当な連携経路が未整理 → 両プロジェクトを同一 Perimeter に含めるか、Perimeter Bridge(相互アクセス許可)を設定する
  • 問題③: いきなりenforceで有効化する計画 → use_explicit_dry_run_spec = true のDry-runモードで数週間ログを観察し、想定外のブロックがないことを確認してから status へ昇格する
  • 問題④: VPN固定IPアリストのみでデバイス状態未検証 → 管理コンソール(Cloud Run)の前段に IAP を有効化し、Access Level の device_policy(画面ロック・会社支給端末・暗号化状態)を条件に含める
  • 問題⑤: IAPアクセス権限の棚卸し未実施 → roles/iap.httpsResourceAccessor を個人付与ではなくグループ(IdPと同期)に付与し、四半期ごとの Access Review を運用に組み込む
  • 問題⑥: Access LevelがIPのみ → ip_subnetworks に加えて regions(許可国コード)・device_policyAND 条件で組み合わせる
  • 問題⑦: VPC_SC_DENIEDの監査ログにアラートなし → Cloud Logging の該当ログエントリをログベースメトリクス化し、Monitoring Alert Policy で即時通知する
ヒント3 — コードの骨格
# Access Level(デバイスポリシー + IP + 地域)
resource "google_access_context_manager_access_level" "corp_trusted" {
  parent = "accessPolicies/${var.access_policy_id}"
  name   = "accessPolicies/${var.access_policy_id}/accessLevels/corp_trusted"
  title  = "corp_trusted"
  basic {
    conditions {
      ip_subnetworks = ["203.0.113.0/24"]      # 修正⑥: 社内VPN出口IP
      regions         = ["JP"]                  # 修正⑥: 許可国コード
      device_policy {
        require_screen_lock = true              # 修正④
        require_corp_owned  = true              # 修正④
      }
    }
  }
}

# Service Perimeter(Dry-runで開始, 修正①③)
resource "google_access_context_manager_service_perimeter" "mops_perimeter" {
  parent         = "accessPolicies/${var.access_policy_id}"
  name           = "accessPolicies/${var.access_policy_id}/servicePerimeters/mops_data_perimeter"
  title          = "mops_data_perimeter"
  perimeter_type = "PERIMETER_TYPE_REGULAR"

  use_explicit_dry_run_spec = true              # 修正③: まずDry-runで影響範囲を可視化
  spec {
    resources           = ["projects/${var.mops_prod_project_number}", "projects/${var.mops_analytics_project_number}"]  # 修正②
    restricted_services  = ["bigquery.googleapis.com", "storage.googleapis.com"]
  }
}

問題点分析(7点)

#問題点分類改善方法
1Service Perimeter不在で境界外へ自由に持ち出し可能データ流出防止bigquery/storage APIを対象にPerimeter作成
2mops-prod/mops-analytics連携経路が未整理境界設計両プロジェクトを同一Perimeterに包含
3いきなりenforceで有効化する計画段階移行use_explicit_dry_run_specでDry-run先行
4VPN固定IPアリストのみでデバイス状態未検証ゼロトラストIAP+Access Level device_policy
5IAP/IAM権限が個人付与で棚卸しなし権限管理グループ付与+四半期Access Review
6Access LevelがIPのみ多要素条件ip_subnetworks+regions+device_policy AND
7VPC_SC_DENIED監査ログにアラートなし検知ログベースメトリクス+Monitoring Alert Policy

構成図 — Bad vs Good(SVG)

Bad(変更前)— 境界なし・VPN固定IPのみ mops-prod(BigQuery: 会員360度ビュー) 問題①: bigquery.dataViewer権限があれば境界の概念なし 問題②: mops-analyticsとの連携経路も未整理 EXPORT DATA / bq cp 個人GCPプロジェクト(社外/私物) 正規のIAM権限があればPIIデータをそのままコピー可能 問題③: 導入するとしてもenforceの事前影響可視化なし mops-admin-console(Cloud Run, ingress: ALL) 問題④: VPN + 固定IPアリストのみ、デバイス状態未検証 私物PCでもVPN経由なら到達可能 roles/run.invoker(個人アカウント直接付与) 問題⑤: hanako.satoは半年前に異動済み→権限残存 棚卸し運用が存在しない Access Level(あるとしてもIPのみ) 問題⑥: 地理的異常アクセス(深夜の海外IP等)を検知できない × 正規のIAM権限がそのまま持ち出し権限になっている × 端末の信頼状態を一切見ないアクセス制御 × 権限の棚卸しがなく異動・退職者の権限が残存 × 問題⑦: VPC_SC_DENIEDログのアラートがなく予兆に気づけない Good(変更後)— Service Perimeter + IAP Context-Aware Access mops_data_perimeter(Dry-run → status昇格) 修正①: bigquery/storage APIを境界内に閉じ込め 修正②: mops-prod + mops-analytics を同一境界に包含 修正③: use_explicit_dry_run_spec=trueで段階移行 EXPORT試行→VPC_SC_DENIED 個人GCPプロジェクト(境界外) 境界外へのEXPORT/COPYは拒否される(IAM権限があっても不可) mops-admin-console(ingress: INTERNAL_LOAD_BALANCER + IAP) 修正④: IAP経由のみ到達可能、直接公開を廃止 Access Level corp_trusted で条件評価 画面ロック/会社支給端末/暗号化状態を検証 roles/iap.httpsResourceAccessor(group:mops-team@) 修正⑤: IdP同期グループへ付与、四半期Access Review 異動・退職はグループ側の同期で自動反映 Access Level corp_trusted(AND条件) 修正⑥: ip_subnetworks + regions(JP) + device_policy 単一要素の突破だけでは通らない VPC_SC_DENIED ログベースメトリクス + Alert Policy 修正⑦: 違反ログを即座にSlack通知 Dry-run期間も本番enforce後も継続監視 ✓ 正規のIAM権限があっても境界外への持ち出しは拒否される ✓ 接続元IPだけでなく端末の信頼状態まで評価 ✓ グループ付与+棚卸しで権限残存を構造的に防止 ✓ Dry-run先行で本番断ち切りを回避しつつ段階移行 ✓ 違反ログの即時アラートで予兆・設定ミスに気づける 修正

模範解答

Before — Service Perimeterが存在しない
# VPC Service Controls関連リソースが一切定義されていない
# → mops-prod の bigquery.dataViewer 権限があれば、
#   個人プロジェクトへ EXPORT DATA / bq cp で自由にPIIデータを持ち出せる
# → mops-analytics側との連携経路も未整理のまま
# → 導入するとしてもいきなりenforceで有効化する計画
After — Dry-run先行のService Perimeter(両プロジェクト包含)
# 修正①②③: VPC Service Controls(Dry-run開始 → mops-prod/mops-analytics両プロジェクトを対象)
resource "google_access_context_manager_service_perimeter" "mops_perimeter" {
  parent         = "accessPolicies/${var.access_policy_id}"
  name           = "accessPolicies/${var.access_policy_id}/servicePerimeters/mops_data_perimeter"
  title          = "mops_data_perimeter"
  perimeter_type = "PERIMETER_TYPE_REGULAR"

  # 修正③: 本番影響ゼロで有効化。VPC_SC_DENIEDになるはずだったログだけを記録する
  use_explicit_dry_run_spec = true

  spec {
    resources = [
      "projects/${var.mops_prod_project_number}",
      "projects/${var.mops_analytics_project_number}",   # 修正②: dbt Mesh連携先を境界内に同居させる
    ]
    restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"]

    vpc_accessible_services {
      enable_restriction = true
      allowed_services   = ["bigquery.googleapis.com", "storage.googleapis.com"]
    }
  }
}

# 数週間のDry-run観察後、影響がないことを確認してstatusへ昇格(別PRで段階適用)
# resource "google_access_context_manager_service_perimeter" "mops_perimeter" {
#   ...
#   status { resources = [...], restricted_services = [...] }  # ここでenforce化
# }
Before — VPN固定IPのみ・個人アカウントへ直接付与
resource "google_cloud_run_v2_service" "admin_console" {
  name     = "mops-admin-console"
  location = "asia-northeast1"
  ingress  = "INGRESS_TRAFFIC_ALL"    # VPNさえ繋がれば私物PCからも到達可能
  template {
    containers {
      image = "asia-northeast1-docker.pkg.dev/mops-prod/admin/console:1.2.0"
    }
  }
}

resource "google_cloud_run_v2_service_iam_member" "invoker" {
  for_each = toset([
    "user:taro.yamada@example.com",
    "user:hanako.sato@example.com",   # 半年前に異動済み → 権限残存
  ])
  name   = google_cloud_run_v2_service.admin_console.name
  role   = "roles/run.invoker"
  member = each.value
}
After — IAP + Access Level(AND条件) + グループ付与
# 修正④⑥: Access Level(デバイスポリシー + IP + 地域の複合条件)
resource "google_access_context_manager_access_level" "corp_trusted" {
  parent = "accessPolicies/${var.access_policy_id}"
  name   = "accessPolicies/${var.access_policy_id}/accessLevels/corp_trusted"
  title  = "corp_trusted"
  basic {
    combining_function = "AND"
    conditions {
      ip_subnetworks = ["203.0.113.0/24"]   # 社内VPN出口IP
      regions        = ["JP"]                # 修正⑥: 日本国内以外からのアクセスを拒否
      device_policy {
        require_screen_lock        = true    # 修正④: 画面ロック必須
        require_corp_owned         = true    # 修正④: 会社支給端末のみ(私物PC排除)
        allowed_encryption_statuses = ["ENCRYPTED"]
      }
    }
  }
}

# 修正④: 管理コンソール(Cloud Run)の前段にIAPを有効化。直接公開を廃止しLB経由に限定
resource "google_cloud_run_v2_service" "admin_console" {
  name     = "mops-admin-console"
  location = "asia-northeast1"
  ingress  = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
  template {
    containers {
      image = "asia-northeast1-docker.pkg.dev/mops-prod/admin/console:1.2.0"
    }
  }
}

resource "google_iap_web_backend_service_iam_binding" "admin_console_access" {
  project             = var.mops_prod_project
  web_backend_service = google_compute_backend_service.admin_console_lb.name
  role                = "roles/iap.httpsResourceAccessor"
  members             = ["group:mops-team@example.com"]  # 修正⑤: 個人ではなくグループ付与
}
# 修正⑦: VPC_SC_DENIED 監査ログのアラート
resource "google_logging_metric" "vpc_sc_denied" {
  name    = "vpc_sc_denied_count"
  project = var.mops_prod_project
  filter  = <<-EOT
    protoPayload.metadata."@type"="type.googleapis.com/google.identity.accesscontextmanager.v1.AuditLog"
    protoPayload.metadata.violationReason="RESOURCE_NOT_IN_SAME_SERVICE_PERIMETER" OR
    protoPayload.metadata.violationReason="NO_MATCHING_ACCESS_LEVEL"
  EOT
}

resource "google_monitoring_alert_policy" "vpc_sc_denied_alert" {
  display_name = "VPC Service Controls violation detected"
  combiner      = "OR"
  conditions {
    display_name = "VPC_SC_DENIED count > 0"
    condition_threshold {
      filter          = "resource.type=\"audited_resource\" AND metric.type=\"logging.googleapis.com/user/${google_logging_metric.vpc_sc_denied.name}\""
      comparison      = "COMPARISON_GT"
      threshold_value = 0
      duration        = "0s"
      aggregations {
        alignment_period   = "300s"
        per_series_aligner = "ALIGN_COUNT"
      }
    }
  }
  notification_channels = [var.slack_notification_channel_id]
}
# 適用(Dry-runモードで開始)
terraform apply -target=google_access_context_manager_service_perimeter.mops_perimeter \
  -target=google_access_context_manager_access_level.corp_trusted

# Dry-runログの確認(実際にブロックされたはずのアクセスを可視化)
gcloud logging read \
  'protoPayload.metadata.dryRun=true AND protoPayload.metadata."@type"="type.googleapis.com/google.identity.accesscontextmanager.v1.AuditLog"' \
  --project=mops-prod --limit=50 --format=json

# 個人プロジェクトへのEXPORT DATAが境界内でブロックされることを確認(enforce化後)
bq query --use_legacy_sql=false \
  'EXPORT DATA OPTIONS(uri="gs://personal-project-bucket/exfil/*.csv", format="CSV") AS SELECT * FROM `mops-prod.gold.mart_member_metrics_public` LIMIT 10'
# → Error: Request is prohibited by organization's policy (VPC_SC_DENIED) が返ることを確認

# IAPアクセス権限の棚卸し(グループメンバー一覧の確認)
gcloud identity groups memberships list --group-email=mops-team@example.com
問題修正内容効果
① Service Perimeter不在bigquery/storage APIを対象にPerimeter作成正規のIAM権限があっても境界外へ持ち出し不可
② クロスプロジェクト連携未整理mops-prod/mops-analyticsを同一Perimeterに包含dbt Mesh連携を巻き添えで遮断しない
③ いきなりenforce計画use_explicit_dry_run_specで段階移行本番断ち切りを避け影響範囲を事前可視化
④ VPN固定IPのみIAP + Access Level device_policy端末の信頼状態まで評価するゼロトラスト化
⑤ 個人付与+棚卸しなしグループ付与+四半期Access Review異動・退職の権限残存を構造的に防止
⑥ Access LevelがIPのみip_subnetworks+regions+device_policy AND単一要素の突破だけでは通らない設計
⑦ 違反ログにアラートなしログベースメトリクス+Monitoring Alert Policy攻撃の予兆・設定ミスに即座に気づける

ポイント解説

1IAMとVPC Service Controlsは直交する2つの防御層 — IAMは「誰が・何に」アクセスできるかを制御し、VPC-SCは「境界を越えたデータの移動」を制御する。列・行レベルセキュリティ(07-29)が「見せる/見せない」の制御であるのに対し、VPC-SCは「正規に見えたデータをどこへ持ち出せるか」を制御する、独立したレイヤーであることを理解する。
2Service Perimeterはプロジェクト単位で境界を張るmops-prod/mops-analyticsのように正当なクロスプロジェクト連携(dbt Mesh)がある場合、境界の外に置くと連携ごと遮断される。両方を同一Perimeterに含めるか、Perimeter Bridgeで橋渡しする設計判断が必要。
3Dry-runモードは本番断ち切りを避けるための必須ステップuse_explicit_dry_run_spec = true で数週間実運用させ、想定外のブロック(=設計漏れの通信経路)を洗い出してからstatusへ昇格することで、いきなりenforceにして障害を起こすリスクを避けられる。
4IAPのContext-Aware Accessは「接続元」ではなく「接続元の状態」を評価する — 従来のVPN+IPアリストは送信元IPしか見ないが、Access Levelのdevice_policyはOSパッチ状況・暗号化状態・画面ロック設定・会社支給端末かどうかまで評価対象にできる。私物PCでVPNに繋がるだけでは通らない設計にする。
5アクセス権限は個人ではなくグループに付与し、棚卸しを運用に組み込むroles/iap.httpsResourceAccessorを個人アカウントへ直接付与すると、異動・退職のたびにTerraform側の削除漏れが起きやすい。IdP同期のグループに付与し、四半期ごとのAccess Reviewを回すことで、権限残存を構造的に防ぐ。
6Access Levelは複数条件のAND結合で「多要素」にする — IPのみの条件は「VPNさえ突破すればどこからでも」を許してしまう。IP・国コード・デバイスポリシーをcombining_function = "AND"で組み合わせることで、単一要素の突破だけでは通らない設計にする。
7VPC_SC_DENIEDログは「攻撃の予兆」も「設計ミス」も両方教えてくれる — 想定外の場所からの持ち出し試行だけでなく、正当な業務フローの設計漏れ(境界に入れ忘れたプロジェクト等)もこのログに現れる。ログベースメトリクス+アラートで即座に気づける体制にしておくことで、Dry-run期間だけでなく本番enforce後も継続的に運用できる。

実務への応用

会員360度ビューのようなPIIマートは、07-29でBigQuery内部のガバナンス(列・行レベル制御、マスキング)を固めても、「権限を持つ社員が正規のクエリ結果をどこへ運べるか」という境界防御が抜けていると、内部不正・アカウント乗っ取り・設定ミスのいずれでもデータ流出しうる。特にMOpsチームのように多くのメンバーがBigQuery Console・Looker Studio・分析用ノートブック環境に日常的にアクセスする組織では、「正規のIAM権限を持つアカウントからの持ち出し」が最も現実的な流出経路になりやすい。

また、管理コンソールのIAP化は、単なるセキュリティ強化ではなく「VPNクライアントの配布・維持コスト」を削減する副次効果もある。IAPはVPNなしでゼロトラストのアクセス制御を実現できるため、リモートワーク環境の多様化(私物端末の業務利用検討等)にも対応しやすい構成になる。

段階導入の現実的なステップ: (1) Access Levelを作成しIAPを管理コンソールに先行導入(影響範囲が小さく検証しやすい) → (2) Service PerimeterをDry-runで作成し、数週間ログを観察 → (3) Dry-runログに想定外のブロックがないことを確認したらstatusへ昇格 → (4) IAPアクセス権限をグループ化し、四半期Access Reviewを運用に組み込む → (5) VPC_SC_DENIEDアラートを常設し、enforce化後も継続監視する。

今日のまとめ

列・行レベルのアクセス制御(07-29)は「誰が何を見られるか」を制御するが、正規の権限で見えたデータを境界外に持ち出す経路は別レイヤーで塞ぐ必要がある。VPC Service Controls は Dry-run から段階的にenforce化することでこの持ち出し経路を構造的に塞ぎ、IAP の Context-Aware Access は「接続元IP」だけでなく「端末の信頼状態」まで評価することで、VPNベースの緩い境界防御をゼロトラストな条件付きアクセスへ置き換える。

次のステップ

  • 発展問題: mops-prodの一部チーム(データサイエンスチーム)だけがBigQuery MLモデルの学習のために境界外の外部Kaggle環境とデータをやり取りする必要がある場合、Perimeter全体を緩めずに、この用途だけを許可するgoogle_access_context_manager_service_perimetersの Egress Policy(egressFrom/egressTo)を設計せよ。
  • 参考: VPC Service Controls公式ドキュメント(Service Perimeter / Access Level / Egress-Ingress Policy)、Identity-Aware Proxy(Context-Aware Access)、BeyondCorp Enterprise、Access Context Manager API

自己評価(あとで記入)

自分の回答

気づき・メモ