Cisco CloudLock CASB のログを収集する

パーサーのバージョン: 3.0

以下でサポートされています。

このドキュメントでは、Google Cloud Storage を使用して Cisco CloudLock CASB ログを Google Security Operations に取り込む方法について説明します。Cloud Run functions の関数が、スケジュールに沿って Cisco CloudLock API をポーリングし、インシデント、アクティビティ、エンティティのデータを GCS バケットに書き込みます。Google SecOps は、GCS V2 フィードを介してこのデータを取り込みます。

Cisco CloudLock は、クラウド アプリケーションの可視性と制御を提供する、クラウドネイティブのクラウド アクセス セキュリティ ブローカー(CASB)です。組織は、シャドー IT の検出、データ損失防止ポリシーの適用、脅威の検出、SaaS アプリケーション全体でのコンプライアンスの維持を行うことができます。

始める前に

次の前提条件を満たしていることを確認します。

  • Google SecOps インスタンス
  • Cloud Storage API が有効になっている GCP プロジェクト
  • GCS バケットを作成、管理する権限
  • GCS バケットの IAM ポリシーを管理する権限
  • Cloud Run サービス、Pub/Sub トピック、Cloud Scheduler ジョブを作成する権限
  • Cisco CloudLock 管理コンソールへの特権アクセス
  • Cisco CloudLock API のベース URL(Cisco CloudLock サポートから提供)

Cisco CloudLock API 認証情報を取得する

まず、Cisco CloudLock サポートに連絡して CloudLock API URL を取得します。API ベース URL はテナントに固有のものであり、一般公開されていません。CloudLock アプリケーションの [Settings] ページにある [Authentication & API] タブに移動して、アクセス トークンを生成します。

  1. Cisco CloudLock 管理コンソールにログインします。
  2. [設定] > [認証と API] に移動します。
  3. [API] で [Generate] をクリックして、アクセス トークンを作成します。
  4. 次の詳細情報をコピーして安全な場所に保存します。

    • API アクセス トークン: [Generate] をクリックした後に表示される署名なしトークン。
    • API ベース URL: Cisco CloudLock サポートから提供されます。形式は https://{YourCloudlockAPIServer} です。

API アクセスを確認する

  • 統合に進む前に、認証情報をテストします。

    CLOUDLOCK_API_TOKEN="your-api-token"
    CLOUDLOCK_API_BASE="https://your-cloudlock-api-server"
    
    curl -v -H "Authorization: Bearer ${CLOUDLOCK_API_TOKEN}" \
      "${CLOUDLOCK_API_BASE}/api/v2/incidents?limit=1"
    

成功すると、items 配列を含む JSON オブジェクトとともに HTTP 200 が返されます。HTTP 401 が返された場合は、API トークンを確認します。HTTP 403 が返された場合は、アカウントに必要な権限があることを確認します。

Google Cloud Storage バケットを作成する

  1. Google Cloud コンソールに移動します。
  2. プロジェクトを選択するか、新しいプロジェクトを作成します。
  3. ナビゲーション メニューで、[Cloud Storage] > [バケット] に移動します。
  4. [バケットを作成] をクリックします。
  5. 次の構成情報を提供してください。

    設定 値
    バケットに名前を付ける グローバルに一意の名前(cisco-cloudlock-logs など)を入力します。
    ロケーション タイプ ニーズに応じて選択します(リージョン、デュアルリージョン、マルチリージョン)。
    ロケーション ロケーションを選択します(例: us-central1)。
    ストレージ クラス Standard(頻繁にアクセスされるログに推奨)
    アクセス制御 均一(推奨)
    保護ツール 省略可: オブジェクトのバージョニングまたは保持ポリシーを有効にする
  6. [作成] をクリックします。

Cloud Run functions のサービス アカウントを作成する

Cloud Run functions の関数には、GCS バケットへの書き込み権限と Pub/Sub による呼び出し権限を持つサービス アカウントが必要です。

サービス アカウントの作成

  1. GCP コンソールで、[IAM と管理] > [サービス アカウント] に移動します。
  2. [サービス アカウントを作成] をクリックします。
  3. 次の構成情報を指定します。
    • サービス アカウント名: 「cloudlock-data-export-sa」と入力します。
    • サービス アカウントの説明: 「Service account for Cloud Run function to collect Cisco CloudLock logs」と入力します。
  4. [作成して続行] をクリックします。
  5. [このサービス アカウントにプロジェクトへのアクセスを許可する] セクションで、次の操作を行います。
    1. [ロールを選択] をクリックします。
    2. [Storage オブジェクト管理者] を検索して選択します。
    3. [+ 別のロールを追加] をクリックします。
    4. [Cloud Run 起動元] を検索して選択します。
    5. [+ 別のロールを追加] をクリックします。
    6. [Cloud Functions 起動元] を検索して選択します。
  6. [続行] をクリックします。
  7. [完了] をクリックします。

これらのロールは、次の操作に必要です。

  • Storage オブジェクト管理者: GCS バケットにログを書き込み、状態ファイルを管理します。
  • Cloud Run 起動元: Pub/Sub が関数を呼び出せるようにします。
  • Cloud Functions 起動元: 関数の呼び出しを許可します。

GCS バケットに対する IAM 権限を付与する

GCS バケットに対する書き込み権限をサービス アカウントに付与します。

  1. [Cloud Storage] > [バケット] に移動します。
  2. バケット名をクリックします。
  3. [権限] タブに移動します。
  4. [アクセス権を付与] をクリックします。
  5. 次の構成情報を指定します。
    • プリンシパルを追加: サービス アカウントのメールアドレス(例: cloudlock-data-export-sa@PROJECT_ID.iam.gserviceaccount.com)を入力します。
    • ロールを割り当てる: [Storage オブジェクト管理者] を選択します。
  6. [保存] をクリックします。

Pub/Sub トピックの作成

Cloud Scheduler がパブリッシュし、Cloud Run functions の関数がサブスクライブする Pub/Sub トピックを作成します。

  1. GCP コンソールで、[Pub/Sub] > [トピック] に移動します。
  2. [トピックを作成] をクリックします。
  3. 次の構成情報を指定します。
    • トピック ID: 「cloudlock-data-export-trigger」と入力します。
    • その他の設定はデフォルトのままにします。
  4. [作成] をクリックします。

ログを収集する Cloud Run 関数を作成する

Cloud Run 関数は、Cloud Scheduler からの Pub/Sub メッセージによってトリガーされ、Cisco CloudLock API からログを取得して GCS に書き込みます。

  1. GCP Console で Cloud Run に移動します。
  2. [サービスを作成] をクリックします。
  3. [関数](インライン編集を使用して関数を作成する)を選択します。
  4. [構成] セクションで、次の構成の詳細を指定します。

    設定 値
    サービス名 cloudlock-data-export
    リージョン GCS バケットに一致するリージョンを選択します(例: us-central1)。
    ランタイム [Python 3.12] 以降を選択します。
  5. [トリガー(省略可)] セクションで、次の操作を行います。

    1. [+ トリガーを追加] をクリックします。
    2. [Cloud Pub/Sub] を選択します。
    3. [Cloud Pub/Sub トピックを選択してください] で、トピック(cloudlock-data-export-trigger)を選択します。
    4. [保存] をクリックします。
  6. [認証] セクションで、次の操作を行います。

    1. [認証が必要] を選択します。
    2. Identity and Access Management(IAM)を確認します。
  7. 下にスクロールして、[コンテナ、ネットワーキング、セキュリティ] を開きます。

  8. [セキュリティ] タブに移動します。

    • サービス アカウント: サービス アカウント(cloudlock-data-export-sa)を選択します。
  9. [コンテナ] タブに移動します。

    1. [変数とシークレット] をクリックします。
    2. 環境変数ごとに [+ 変数を追加] をクリックします。
    変数名 値の例 説明
    GCS_BUCKET cisco-cloudlock-logs GCS バケット名
    GCS_PREFIX cloudlock/ ログファイルの接頭辞
    STATE_KEY cloudlock/state.json 状態ファイルのパス
    CLOUDLOCK_API_TOKEN your-api-token API 署名なしトークン
    CLOUDLOCK_API_BASE https://your-cloudlock-api-server CloudLock サポートの API ベース URL
  10. [変数とシークレット] タブで、[リクエスト] まで下にスクロールします。

    • リクエスト タイムアウト: 600 秒(10 分)を入力します。
  11. [コンテナ] の [設定] タブに移動します。

    • [リソース] セクションで、次の操作を行います。
      • メモリ: 512 MiB 以上を選択します。
      • CPU: [1] を選択します。
    • [完了] をクリックします。
  12. [実行環境] まで下にスクロールします。

    • [デフォルト](推奨)を選択します。
  13. [リビジョン スケーリング] セクションで、次の操作を行います。

    • [インスタンスの最小数] に「0」と入力します。
    • [インスタンスの最大数]: 「100」と入力します(または、予想される負荷に基づいて調整します)。
  14. [作成] をクリックします。

  15. サービスが作成されるまで待ちます(1 ~ 2 分)。

  16. サービスが作成されると、インライン コードエディタが自動的に開きます。

関数コードを追加する

  1. [エントリ ポイント] フィールドに「main」と入力します。
  2. インライン コードエディタで、次の 2 つのファイルを作成します。

    • main.py:

      import functions_framework
      from google.cloud import storage
      import json
      import os
      import urllib3
      from datetime import datetime, timezone, timedelta
      import time
      
      # Initialize HTTP client with timeouts
      http = urllib3.PoolManager(
          timeout=urllib3.Timeout(connect=5.0, read=30.0),
          retries=False,
      )
      
      # Initialize Storage client
      storage_client = storage.Client()
      
      @functions_framework.cloud_event
      def main(cloud_event):
          """
          Cloud Run function triggered by Pub/Sub to fetch logs from Cisco CloudLock API and write to GCS.
      
          Args:
              cloud_event: CloudEvent object containing Pub/Sub message
          """
      
          # Get environment variables
          bucket_name = os.environ.get('GCS_BUCKET')
          prefix = os.environ.get('GCS_PREFIX', 'cloudlock/')
          state_key = os.environ.get('STATE_KEY', 'cloudlock/state.json')
          api_token = os.environ.get('CLOUDLOCK_API_TOKEN')
          api_base = os.environ.get('CLOUDLOCK_API_BASE')
      
          if not all([bucket_name, api_token, api_base]):
              print('Error: Missing required environment variables')
              return
      
          try:
              # Get GCS bucket
              bucket = storage_client.bucket(bucket_name)
      
              # Load state (last processed offset for each endpoint)
              state = load_state(bucket, state_key)
      
              print(f'Processing logs with state: {state}')
      
              # Create Authorization header
              headers = {
                  'Authorization': f'Bearer {api_token}',
                  'Content-Type': 'application/json'
              }
      
              # Fetch incidents data (using offset-based pagination)
              incidents_offset = state.get('incidents_offset', 0)
              incidents, new_incidents_offset = fetch_cloudlock_incidents(
                  http, api_base, headers, incidents_offset
              )
      
              if incidents:
                  upload_to_gcs_ndjson(bucket, prefix, 'incidents', incidents)
                  print(f'Uploaded {len(incidents)} incidents to GCS')
                  state['incidents_offset'] = new_incidents_offset
      
              # Fetch activities data (using time-based filtering with offset pagination)
              activities_last_time = state.get('activities_last_time')
              if not activities_last_time:
                  activities_last_time = (datetime.now(timezone.utc) - timedelta(hours=24)).isoformat()
      
              activities_offset = state.get('activities_offset', 0)
              activities, new_activities_offset, newest_activity_time = fetch_cloudlock_activities(
                  http, api_base, headers, activities_last_time, activities_offset
              )
      
              if activities:
                  upload_to_gcs_ndjson(bucket, prefix, 'activities', activities)
                  print(f'Uploaded {len(activities)} activities to GCS')
                  state['activities_offset'] = new_activities_offset
                  if newest_activity_time:
                      state['activities_last_time'] = newest_activity_time
      
              # Fetch entities data (using offset-based pagination)
              entities_offset = state.get('entities_offset', 0)
              entities, new_entities_offset = fetch_cloudlock_entities(
                  http, api_base, headers, entities_offset
              )
      
              if entities:
                  upload_to_gcs_ndjson(bucket, prefix, 'entities', entities)
                  print(f'Uploaded {len(entities)} entities to GCS')
                  state['entities_offset'] = new_entities_offset
      
              # Update consolidated state
              state['updated_at'] = datetime.now(timezone.utc).isoformat()
              save_state(bucket, state_key, state)
      
              print('CloudLock data export completed successfully')
      
          except Exception as e:
              print(f'Error processing logs: {str(e)}')
              raise
      
      def make_api_request(http, url, headers, retries=3):
          """Make API request with exponential backoff retry logic."""
          backoff = 1.0
          for attempt in range(retries):
              try:
                  response = http.request('GET', url, headers=headers)
      
                  if response.status == 200:
                      return response
                  elif response.status == 429:
                      # Rate limit - CloudLock enforces per-endpoint rate limits
                      retry_after = int(response.headers.get('Retry-After', str(int(backoff))))
                      print(f'Rate limited (429), waiting {retry_after} seconds')
                      time.sleep(retry_after)
                      backoff = min(backoff * 2, 60.0)
                  else:
                      print(f'API request failed with status {response.status}: {response.data.decode("utf-8")}')
                      if response.status in (401, 403):
                          return None
              except Exception as e:
                  print(f'Request attempt {attempt + 1} failed: {str(e)}')
                  if attempt < retries - 1:
                      wait_time = 2 ** attempt
                      time.sleep(wait_time)
                  else:
                      raise
      
          return None
      
      def fetch_cloudlock_incidents(http, api_base, headers, start_offset=0):
          """
          Fetch incidents data from Cisco CloudLock API using offset-based pagination.
      
          Endpoint: GET /api/v2/incidents
          Pagination: limit and offset query parameters.
          Response: JSON with 'items' array, 'total' count, and 'results' count.
          """
          url = f"{api_base}/api/v2/incidents"
      
          limit = 1000
          offset = start_offset
          all_data = []
      
          try:
              while True:
                  # Build URL with parameters
                  full_url = f"{url}?limit={limit}&offset={offset}"
      
                  print(f"Fetching incidents with offset: {offset}")
      
                  response = make_api_request(http, full_url, headers)
                  if not response:
                      break
      
                  data = json.loads(response.data.decode('utf-8'))
      
                  # CloudLock API returns items in 'items' array
                  batch_data = data.get('items', [])
      
                  if not batch_data:
                      print("No more incidents to fetch")
                      break
      
                  all_data.extend(batch_data)
      
                  # Check if we've reached the end
                  total = data.get('total', 0)
                  results = data.get('results', len(batch_data))
      
                  print(f"Fetched {results} incidents (total available: {total})")
      
                  if results < limit or offset + results >= total:
                      print("Reached end of incidents")
                      break
      
                  offset += limit
      
              print(f"Fetched {len(all_data)} total incidents")
              return all_data, offset
      
          except Exception as e:
              print(f"Error fetching incidents: {str(e)}")
              return [], start_offset
      
      def fetch_cloudlock_activities(http, api_base, headers, from_time, start_offset=0):
          """
          Fetch activities data from Cisco CloudLock API using time-based filtering and offset pagination.
      
          Endpoint: GET /api/v2/activities
          Pagination: limit and offset query parameters.
          Note: Client-side time filtering is applied since the API may not support time range parameters.
          """
          url = f"{api_base}/api/v2/activities"
      
          limit = 1000
          offset = start_offset
          all_data = []
          newest_time = None
      
          try:
              while True:
                  # Build URL with pagination
                  full_url = f"{url}?limit={limit}&offset={offset}"
      
                  print(f"Fetching activities with offset: {offset}")
      
                  response = make_api_request(http, full_url, headers)
                  if not response:
                      break
      
                  data = json.loads(response.data.decode('utf-8'))
                  batch_data = data.get('items', [])
      
                  if not batch_data:
                      print("No more activities to fetch")
                      break
      
                  # Filter activities by time (client-side filtering)
                  filtered_batch = []
                  for item in batch_data:
                      item_time = item.get('timestamp') or item.get('created_at')
                      if item_time and item_time >= from_time:
                          filtered_batch.append(item)
                          if not newest_time or item_time > newest_time:
                              newest_time = item_time
      
                  all_data.extend(filtered_batch)
      
                  results = data.get('results', len(batch_data))
                  total = data.get('total', 0)
      
                  print(f"Fetched {results} activities, {len(filtered_batch)} after time filter (total available: {total})")
      
                  if results < limit or offset + results >= total:
                      print("Reached end of activities")
                      break
      
                  offset += limit
      
              print(f"Fetched {len(all_data)} total activities")
              return all_data, offset, newest_time
      
          except Exception as e:
              print(f"Error fetching activities: {str(e)}")
              return [], start_offset, None
      
      def fetch_cloudlock_entities(http, api_base, headers, start_offset=0):
          """
          Fetch entities data from Cisco CloudLock API using offset-based pagination.
      
          Endpoint: GET /api/v2/entities
          Note: This endpoint requires the Entity Cache feature. If not enabled,
          use the incident entities endpoint (/api/v2/incidents/{id}/entities) as an alternative.
          """
          url = f"{api_base}/api/v2/entities"
      
          limit = 1000
          offset = start_offset
          all_data = []
      
          try:
              while True:
                  full_url = f"{url}?limit={limit}&offset={offset}"
      
                  print(f"Fetching entities with offset: {offset}")
      
                  response = make_api_request(http, full_url, headers)
                  if not response:
                      break
      
                  data = json.loads(response.data.decode('utf-8'))
                  batch_data = data.get('items', [])
      
                  if not batch_data:
                      print("No more entities to fetch")
                      break
      
                  all_data.extend(batch_data)
      
                  results = data.get('results', len(batch_data))
                  total = data.get('total', 0)
      
                  print(f"Fetched {results} entities (total available: {total})")
      
                  if results < limit or offset + results >= total:
                      print("Reached end of entities")
                      break
      
                  offset += limit
      
              print(f"Fetched {len(all_data)} total entities")
              return all_data, offset
      
          except Exception as e:
              print(f"Error fetching entities: {str(e)}")
              return [], start_offset
      
      def upload_to_gcs_ndjson(bucket, prefix, data_type, data):
          """Upload data to GCS bucket in NDJSON format (one JSON object per line)."""
          timestamp = datetime.now(timezone.utc).strftime('%Y/%m/%d/%H')
          filename = f"{prefix}{data_type}/{timestamp}/cloudlock_{data_type}_{int(datetime.now(timezone.utc).timestamp())}.jsonl"
      
          try:
              # Convert to NDJSON format
              ndjson_content = '\n'.join([json.dumps(item, separators=(',', ':')) for item in data])
      
              blob = bucket.blob(filename)
              blob.upload_from_string(
                  ndjson_content,
                  content_type='application/x-ndjson'
              )
      
              print(f"Successfully uploaded {filename} to GCS")
      
          except Exception as e:
              print(f"Error uploading to GCS: {str(e)}")
              raise
      
      def load_state(bucket, key):
          """Load state from GCS with separate tracking for each endpoint."""
          try:
              blob = bucket.blob(key)
              if blob.exists():
                  state_data = blob.download_as_text()
                  return json.loads(state_data)
          except Exception as e:
              print(f'Warning: Could not load state: {str(e)}')
      
          print("No previous state found, starting fresh")
          return {}
      
      def save_state(bucket, key, state):
          """Save consolidated state to GCS."""
          try:
              blob = bucket.blob(key)
              blob.upload_from_string(
                  json.dumps(state, indent=2),
                  content_type='application/json'
              )
              print("Updated state successfully")
          except Exception as e:
              print(f"Error updating state: {str(e)}")
              raise
      
    • requirements.txt:

      functions-framework==3.*
      google-cloud-storage==2.*
      urllib3>=2.0.0
      
  3. [デプロイ] をクリックして関数を保存し、デプロイします。

  4. デプロイが完了するまで待ちます(2 ~ 3 分)。

Cloud Scheduler ジョブの作成

Cloud Scheduler は、定期的に Pub/Sub トピックにメッセージをパブリッシュし、Cloud Run 関数をトリガーします。

  1. GCP Console で、[Cloud Scheduler] に移動します。
  2. [ジョブを作成] をクリックします。
  3. 次の構成情報を提供してください。

    設定 値
    名前 cloudlock-data-export-hourly
    リージョン Cloud Run functions の関数と同じリージョンを選択します。
    周波数 0 * * * *(1 時間ごと、毎正時)
    タイムゾーン タイムゾーンを選択(UTC を推奨)
    ターゲット タイプ Pub/Sub
    トピック トピック(cloudlock-data-export-trigger)を選択します。
    メッセージ本文 {}(空の JSON オブジェクト)
  4. [作成] をクリックします。

スケジュール頻度のオプション

ログの量とレイテンシの要件に基づいて頻度を選択します。

頻度 CRON 式 ユースケース
5 分おき */5 * * * * 大容量、低レイテンシ
15 分ごと */15 * * * * 検索量が普通
1 時間ごと 0 * * * * 標準(推奨)
6 時間ごと 0 */6 * * * 少量のバッチ処理
毎日 0 0 * * * 過去のデータの収集

統合をテストする

  1. Cloud Scheduler コンソールで、ジョブを見つけます。
  2. [強制実行] をクリックして、ジョブを手動でトリガーします。
  3. 数秒待ちます。
  4. [Cloud Run] > [サービス] に移動します。
  5. 関数名(cloudlock-data-export)をクリックします。
  6. [ログ] タブをクリックします。
  7. 関数が正常に実行されたことを確認します。以下のものを探します。

    Processing logs with state: {}
    Fetching incidents with offset: 0
    Fetched X incidents (total available: Y)
    Uploaded X incidents to GCS
    CloudLock data export completed successfully
    
  8. [Cloud Storage] > [バケット] に移動します。

  9. バケット名(cisco-cloudlock-logs)をクリックします。

  10. cloudlock/ 接頭辞フォルダに移動します。

  11. incidents/、activities/、entities/ のサブフォルダに新しい .jsonl ファイルが作成されたことを確認します。

ログにエラーが表示される場合:

  • HTTP 401: 環境変数の API トークンを確認します。
  • HTTP 403: CloudLock アカウントに必要な権限があることを確認します。
  • HTTP 429: レート制限 - 関数はバックオフを使用して自動的に再試行します。
  • 環境変数が設定されていない: 必要な変数がすべて設定されていることを確認します。
  • Empty entities: Entities エンドポイントには Entity Cache 機能が必要です。この機能を有効にするには、CloudLock サポートにお問い合わせください。

Cisco CloudLock のログを取り込むように Google SecOps でフィードを構成する

  1. [設定] > [データ管理] > [フィード] に移動します。SIEM のみのプラットフォームを使用している場合は、[設定] > [フィード] に移動します。
  2. [Add New Feed] をクリックします。
  3. [単一フィードを設定] をクリックします。
  4. [フィード名] フィールドに、フィードの名前を入力します(例: Cisco CloudLock logs)。
  5. [Source type] として [Google Cloud Storage V2] を選択します。
  6. [Log type] として [Cisco CloudLock] を選択します。
  7. [サービス アカウントを取得する] をクリックします。一意のサービス アカウントのメールアドレスが表示されます。例:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. このメールアドレスをコピーして、次のステップで使用します。

  9. [次へ] をクリックします。

  10. 次の入力パラメータの値を指定します。

    • ストレージ バケットの URL: 接頭辞パスを含む GCS バケット URI を入力します。

      gs://cisco-cloudlock-logs/cloudlock/
      
      • 次のように置き換えます。
        • cisco-cloudlock-logs: GCS バケット名。
        • cloudlock/: ログが保存されるオプションの接頭辞 / フォルダパス(ルートの場合は空のままにします)。
    • Source deletion option: 必要に応じて削除オプションを選択します。

      • なし: 転送後にファイルを削除しません(テストに推奨)。
      • 転送されたファイルを削除する: 転送が完了した後にファイルを削除します。
      • 転送されたファイルと空のディレクトリを削除する: 転送が成功した後にファイルと空のディレクトリを削除します。
    • ファイルの最長存続期間: 過去数日間に変更されたファイルを含めます(デフォルトは 180 日)。

    • Asset namespace: アセットの名前空間。

    • Ingestion labels: このフィードのイベントに適用されるラベル。

  11. [次へ] をクリックします。

  12. [Finalize] 画面で新しいフィードの設定を確認し、[送信] をクリックします。

Google SecOps サービス アカウントに IAM 権限を付与する

Google SecOps サービス アカウントには、GCS バケットに対する Storage オブジェクト閲覧者のロールが必要です。

  1. [Cloud Storage] > [バケット] に移動します。
  2. バケット名をクリックします。
  3. [権限] タブに移動します。
  4. [アクセス権を付与] をクリックします。
  5. 次の構成情報を指定します。
    • プリンシパルを追加: Google SecOps サービス アカウントのメールアドレスを貼り付けます。
    • ロールを割り当てる: [Storage オブジェクト閲覧者] を選択します。
  6. [保存] をクリックします。

UDM マッピング テーブル

ログフィールド UDM マッピング ロジック
created_at about.resource.attribute.creation_time 未加工ログの created_at の値はタイムスタンプとして解析され、about.resource.attribute.creation_time フィールドにマッピングされます。
created_at about.resource.attribute.labels.key created_at の値がラベルキーに割り当てられます。
created_at about.resource.attribute.labels.value created_at の値がラベル値に割り当てられます。
entity.id target.asset.product_object_id 未加工ログの entity.id の値が target.asset.product_object_id フィールドにマッピングされます。
entity.ip target.ip 未加工ログの entity.ip の値が target.ip フィールドに統合されます。
entity.mime_type target.file.mime_type entity.origin_type が「document」の場合、未加工ログの entity.mime_type の値は target.file.mime_type フィールドにマッピングされます。
entity.name target.application entity.origin_type が「app」の場合、未加工ログの entity.name の値は target.application フィールドにマッピングされます。
entity.name target.file.full_path entity.origin_type が「document」の場合、未加工ログの entity.name の値は target.file.full_path フィールドにマッピングされます。
entity.origin_id target.resource.product_object_id 未加工ログの entity.origin_id の値が target.resource.product_object_id フィールドにマッピングされます。
entity.origin_type target.resource.resource_subtype 未加工ログの entity.origin_type の値が target.resource.resource_subtype フィールドにマッピングされます。
entity.owner_email target.user.email_addresses 未加工ログの entity.owner_email の値がメールの正規表現と一致する場合、target.user.email_addresses フィールドにマージされます。
entity.owner_email target.user.user_display_name 未加工ログの entity.owner_email の値がメールの正規表現と一致しない場合、target.user.user_display_name フィールドにマッピングされます。
entity.owner_name target.user.user_display_name entity.owner_email がメールの正規表現と一致する場合、未加工ログの entity.owner_name の値は target.user.user_display_name フィールドにマッピングされます。
entity.vendor.name target.platform_version 未加工ログの entity.vendor.name の値が target.platform_version フィールドにマッピングされます。
id metadata.product_log_id 未加工ログの id の値が metadata.product_log_id フィールドにマッピングされます。
incident_status metadata.product_event_type 未加工ログの incident_status の値が metadata.product_event_type フィールドにマッピングされます。
policy.id security_result.rule_id 未加工ログの policy.id の値が security_result.rule_id フィールドにマッピングされます。
policy.name security_result.rule_name 未加工ログの policy.name の値が security_result.rule_name フィールドにマッピングされます。
重要度 security_result.severity_details 未加工ログの severity の値が security_result.severity_details フィールドにマッピングされます。
updated_at about.resource.attribute.labels.key updated_at の値がラベルキーに割り当てられます。
updated_at about.resource.attribute.labels.value updated_at の値がラベル値に割り当てられます。
updated_at about.resource.attribute.last_update_time 未加工ログの updated_at の値はタイムスタンプとして解析され、about.resource.attribute.last_update_time フィールドにマッピングされます。
なし metadata.event_timestamp updated_at フィールドから取得されます。値はタイムスタンプとして解析され、マッピングされます。
なし metadata.event_type 「GENERIC_EVENT」に設定されます。
なし metadata.product_name 「CISCO_CLOUDLOCK_CASB」に設定されます。
なし metadata.product_version 「Cisco」に設定されます。
なし metadata.vendor_name 「CloudLock」に設定します。
なし security_result.alert_state severity が「ALERT」で、incident_status が「RESOLVED」または「DISMISSED」でない場合は、「ALERTING」に設定します。severity が「ALERT」で、incident_status が「RESOLVED」または「DISMISSED」の場合は、「NOT_ALERTING」に設定します。
なし security_result.detection_fields.key matches 配列(具体的には各一致オブジェクトのキー)から派生します。severity が「ALERT」で、incident_status が「NEW」の場合も「true」に設定されます。
なし security_result.detection_fields.value matches 配列(具体的には各一致オブジェクトの値)から派生します。severity が「ALERT」で、incident_status が「NEW」の場合も「true」に設定されます。
なし security_result.severity severity が「INFO」の場合は「INFORMATIONAL」に設定します。severity が「CRITICAL」の場合は「CRITICAL」に設定されます。severity フィールドから取得されます。
なし security_result.summary 「match count: 」に match_count の値を連結した値に設定します。
なし target.resource.resource_type entity.origin_type が「document」の場合は「STORAGE_OBJECT」に設定します。
なし target.url entity.origin_type が「document」の場合、entity.direct_url から派生します。

さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。