Cloud WorkstationsからGitHubへの安全なアクセスを実現する - Secure Web Proxyによるリポジトリレベル制御

Google Cloud WorkstationsからGitHubの特定リポジトリのみにアクセスを許可する、Secure Web Proxyを使った実装方法を解説します。

Cloud WorkstationsからGitHubへの安全なアクセスを実現する - Secure Web Proxyによるリポジトリレベル制御

はじめに

開発環境のセキュリティを確保しながら、開発者の生産性を維持することは常に課題です。特にクラウドベースの開発環境では、外部リポジトリへのアクセス制御が重要になります。

本記事では、Google Cloud WorkstationsからGitHubの特定リポジトリのみにアクセスを許可する、Secure Web Proxyを使った実装方法を解説します。

解決したい課題

Cloud Workstationsを使用する際、以下の課題に直面しました:

  1. セキュリティ要件: 開発環境から外部への無制限なアクセスは許可できない
  2. 開発効率: GitHubリポジトリへのアクセスは必須
  3. きめ細かい制御: 組織全体ではなく、必要なリポジトリのみアクセス許可したい

従来のアプローチでは、組織全体(github.com/myorg/*)へのアクセスを許可することが一般的でしたが、これでは従業員が個人的に作成したリポジトリへの意図しないデータ流出リスクがありました。

アーキテクチャ概要

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
┌─────────────────────┐
│  Cloud Workstation  │
│   (VPC内)          │
└──────────┬──────────┘
           │ Private IP
┌─────────────────────┐
│  Secure Web Proxy   │
│  - TLS Inspection   │
│  - URL Filtering    │
└──────────┬──────────┘
┌─────────────────────┐
│      GitHub         │
│  (特定リポジトリ)   │
└─────────────────────┘

実装詳細

1. Secure Web Proxyの基本設定

1
2
3
4
5
6
7
resource "google_network_security_gateway_security_policy" "main" {
  project               = var.project_id
  location              = var.region
  name                  = "${var.prefix}-workstation-policy"
  description           = "Security policy for Cloud Workstations"
  tls_inspection_policy = google_network_security_tls_inspection_policy.main.id
}

TLS inspectionを有効にすることで、HTTPS通信の中身を検査し、URLパスレベルでの制御が可能になります。

2. リポジトリ単位のアクセス制御

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
resource "google_network_security_gateway_security_policy_rule" "github_repo_access" {
  for_each = {
    for i, repo in var.allowed_github_repos
    : 2000 + i => repo  # 動的にpriorityを割り当て
  }
  
  name                    = "github-repo-${each.key}"
  description             = "Allow access to GitHub repository ${each.value}"
  priority                = each.key
  basic_profile           = "ALLOW"
  session_matcher         = "inIpRange(source.ip, '0.0.0.0/0')"
  application_matcher     = <<-_EOT_
    request.url().startsWith('github.com/${each.value}.git/')
  _EOT_
  tls_inspection_enabled  = true
  enabled                 = true
}

3. Priority管理戦略

ルールの評価順序を明確にするため、以下のpriority体系を採用:

Priority範囲 用途
1000-1999 一般的な許可URL パッケージリポジトリ、ドキュメント
2000-9999 GitHub個別リポジトリ myorg/frontend, myorg/backend
10000 デフォルト拒否 上記以外すべて拒否
1
2
3
# 2000番台の動的割り当て
# リポジトリが10個の場合: 2000, 2001, 2002, ..., 2009
# リポジトリが100個の場合: 2000, 2001, ..., 2099

セキュリティ考慮事項

1. session_matcherの設定

1
session_matcher = "inIpRange(source.ip, '0.0.0.0/0')"

一見すると全IPを許可しているように見えますが、Secure Web ProxyはVPC内に配置されているため、実質的にVPC内のトラフィックのみが対象となります。外部からの直接アクセスは構造的に不可能です。

2. より厳密な制御が必要な場合

1
2
3
4
5
6
7
8
# 特定のWorkstationサブネットのみに制限
session_matcher = "inIpRange(source.ip, '10.0.1.0/24')"

# HTTPメソッドも制限
application_matcher = <<-_EOT_
  request.url().startsWith('github.com/${each.value}.git/')
  && request.method.matches('^(GET|POST|HEAD)$')
_EOT_

3. 時間帯制御(オプション)

1
2
3
4
5
6
# 営業時間内のみアクセス許可
session_matcher = <<-EOT
  inIpRange(source.ip, '10.0.1.0/24')
  && request.time.getHours('Asia/Tokyo') >= 9
  && request.time.getHours('Asia/Tokyo') < 18
EOT

実装時の注意点

URLマッチングの課題

現在の実装では以下の制限があります:

1
2
3
4
5
6
# 現在の実装
request.url().startsWith('github.com/${each.value}.git/')

# 問題:以下のパターンがマッチしない
# - github.com/myorg/repo.git (末尾スラッシュなし)
# - github.com/myorg/repo/info/refs (Git smart HTTP)

改善案

1
2
3
4
# より柔軟なパターンマッチング
application_matcher = <<-_EOT_
  request.url().matches('^github\\.com/${replace(each.value, "/", "\\/")}(\\.git)?(/.*)?$')
_EOT_

動作確認

設定前

1
2
3
4
$ git clone https://github.com/myorg/restricted-repo.git
Cloning into 'restricted-repo'...
remote: Access denied
fatal: unable to access 'https://github.com/myorg/restricted-repo.git/': The requested URL returned error: 403

設定後

1
2
3
4
5
$ git clone https://github.com/myorg/allowed-repo.git
Cloning into 'allowed-repo'...
remote: Enumerating objects: 12345, done.
remote: Counting objects: 100% (12345/12345), done.
# 成功!

運用上のベストプラクティス

1. 段階的なロールアウト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
variable "allowed_github_repos" {
  default = [
    # Phase 1: 必須リポジトリのみ
    "myorg/core-api",
    
    # Phase 2: チーム固有リポジトリ追加
    "myorg/frontend-app",
    "myorg/mobile-app",
    
    # Phase 3: ツール・ライブラリ
    "myorg/shared-libraries"
  ]
}

2. ログ・監査

1
2
3
4
5
6
7
8
9
resource "google_network_security_gateway_security_policy_rule" "github_repo_access" {
  # ... 他の設定 ...
  
  # ログ設定を追加(将来の実装)
  log_config {
    enable      = true
    sample_rate = 1.0  # 全リクエストをログ
  }
}

3. 例外処理

緊急時のアクセスや特殊なユースケースに対応:

1
2
3
4
5
6
# 緊急時用の一時的なルール(priority 1500)
resource "google_network_security_gateway_security_policy_rule" "emergency_access" {
  count       = var.enable_emergency_access ? 1 : 0
  priority    = 1500
  # 特定のIPから全GitHubアクセスを許可
}

まとめ

Secure Web Proxyを使用することで、Cloud WorkstationsからGitHubへのアクセスを、リポジトリレベルで細かく制御できるようになりました。

メリット

  • ✅ セキュリティ: 必要最小限のアクセスのみ許可
  • ✅ 柔軟性: リポジトリ単位での制御が可能
  • ✅ 拡張性: 動的なルール生成により管理が容易
  • ✅ 監査性: アクセスログによる追跡が可能

今後の改善点

  • URLマッチングパターンの改善
  • HTTPメソッド制限の追加
  • より詳細なログ・監視の実装

この実装により、セキュリティと開発効率のバランスを保ちながら、クラウドネイティブな開発環境を実現できました。

参考リンク


この記事は、実際のプロダクション環境での実装経験に基づいています。セキュリティ要件は組織によって異なるため、実装時は自組織のポリシーに合わせて調整してください。

技術ネタ、趣味や備忘録などを書いているブログです
Hugo で構築されています。
テーマ StackJimmy によって設計されています。