Delinea シングル サインオン(SSO)ログを収集する

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

このドキュメントでは、Google Cloud Storage を使用して Delinea(旧 Centrify)シングル サインオン(SSO)ログを Google Security Operations に取り込む方法について説明します。パーサーはログを抽出し、JSON 形式と syslog 形式の両方を処理します。Key-Value ペア、タイムスタンプ、その他の関連フィールドを解析して UDM モデルにマッピングします。ログインの失敗、ユーザー エージェント、重大度レベル、認証メカニズム、さまざまなイベントタイプを処理するための特定のロジックを備えています。障害イベントのターゲット メールアドレスでは、NormalizedUser よりも FailUserName が優先されます。

始める前に

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

  • Google SecOps インスタンス
  • Cloud Storage API が有効になっている GCP プロジェクト
  • GCS バケットを作成および管理する権限
  • GCS バケットの IAM ポリシーを管理する権限
  • Cloud Run 関数、Pub/Sub トピック、Cloud Scheduler ジョブを作成する権限
  • Delinea(Centrify)SSO テナントへの特権アクセス

Delinea(Centrify)SSO 認証情報を収集する

OAuth2 クライアント アプリケーションを作成する

  1. Delinea 管理ポータルにログインします。
  2. [アプリ] > [ウェブアプリを追加] に移動します。
  3. [カスタム] タブをクリックします。
  4. [OAuth2 Client] を検索して、[追加] をクリックします。
  5. [ウェブアプリを追加] ダイアログで [はい] をクリックします。
  6. [ウェブアプリを追加] ダイアログで [閉じる] をクリックします。
  7. [アプリケーション構成] ページで、次の項目を構成します。
    • [Settings] タブ:
      • アプリケーション ID: 一意の識別子(secops-oauth-client など)を入力します。
      • アプリケーション名: わかりやすい名前を入力します(例: SecOps Data Export)。
      • アプリケーションの説明: 説明を入力します(例: OAuth client for exporting audit events to SecOps)。
    • General Usage セクション:
      • クライアント ID のタイプ: [機密] を選択します。
      • 発行されたクライアント ID: この値をコピーして保存します。
      • 発行されたクライアント シークレット: この値をコピーして保存します。
    • [トークン] タブ:
      • Auth Methods: [Client Creds] を選択します。
      • トークンタイプ: [JwtRS256] を選択します。
    • [スコープ] タブ:
      • 説明 Query API Access を含むスコープ redrock/query を追加します。
  8. [保存] をクリックして、OAuth クライアントを作成します。
  9. 次の詳細をコピーして安全な場所に保存します。
    • テナント URL: Centrify テナントの URL(例: https://yourtenant.my.centrify.com)。
    • クライアント ID: ステップ 7 で取得したクライアント ID。
    • クライアント シークレット: 手順 7 で取得した値。
    • OAuth アプリケーション ID: アプリケーション構成から取得します。

権限を確認する

OAuth クライアントに必要な権限があることを確認するには:

  1. Delinea 管理ポータルにログインします。
  2. [設定](⚙️)> [リソース> ロール] に移動します。
  3. OAuth クライアントに割り当てられたロールに [レポート: 監査イベント: 表示] 権限が含まれていることを確認します。
  4. 権限がない場合は、Delinea 管理者に連絡して必要な権限を付与してもらいます。

テスト API アクセス

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

    # Replace with your actual credentials
    TENANT_URL="https://yourtenant.my.centrify.com"
    CLIENT_ID="your-client-id"
    CLIENT_SECRET="your-client-secret"
    OAUTH_APP_ID="your-oauth-application-id"
    
    # Get OAuth token
    TOKEN=$(curl -s -X POST "${TENANT_URL}/oauth2/token/${OAUTH_APP_ID}" \
      -H "Authorization: Basic $(echo -n "${CLIENT_ID}:${CLIENT_SECRET}" | base64)" \
      -H "X-CENTRIFY-NATIVE-CLIENT: True" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials&scope=redrock/query" | jq -r '.access_token')
    
    # Test query API access
    curl -v -X POST "${TENANT_URL}/Redrock/query" \
      -H "Authorization: Bearer ${TOKEN}" \
      -H "X-CENTRIFY-NATIVE-CLIENT: True" \
      -H "Content-Type: application/json" \
      -d '{"Script":"Select * from Event where WhenOccurred > datefunc('"'"'now'"'"', '"'"'-1'"'"') ORDER BY WhenOccurred ASC","args":{"PageNumber":1,"PageSize":10,"Limit":10,"Caching":-1}}'
    

成功すると、監査イベントを含む JSON レスポンスが表示されます。401 エラーまたは 403 エラーが表示された場合は、認証情報と権限を確認してください。

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

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

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

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

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

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

  1. GCP Console で、[IAM と管理>サービス アカウント] に移動します。
  2. [サービス アカウントを作成] をクリックします。
  3. 次の構成の詳細を指定します。
    • サービス アカウント名: 「delinea-sso-collector-sa」と入力します。
    • サービス アカウントの説明: 「Service account for Cloud Run function to collect Delinea SSO logs」と入力します。
  4. [作成して続行] をクリックします。
  5. [このサービス アカウントにプロジェクトへのアクセスを許可する] セクションで、次のロールを追加します。
    1. [ロールを選択] をクリックします。
    2. [ストレージ オブジェクト管理者] を検索して選択します。
    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. バケット名(delinea-centrify-logs-bucket など)をクリックします。
  3. [権限] タブに移動します。
  4. [アクセス権を付与] をクリックします。
  5. 次の構成の詳細を指定します。
    • プリンシパルを追加: サービス アカウントのメールアドレス(例: delinea-sso-collector-sa@PROJECT_ID.iam.gserviceaccount.com)を入力します。
    • ロールを割り当てる: [Storage オブジェクト管理者] を選択します。
  6. [保存] をクリックします。

Pub/Sub トピックの作成

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

  1. GCP Console で、[Pub/Sub> トピック] に移動します。
  2. [トピックを作成] をクリックします。
  3. 次の構成の詳細を指定します。
    • トピック ID: 「delinea-sso-logs-trigger」と入力します。
    • その他の設定はデフォルトのままにします。
  4. [作成] をクリックします。

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

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

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

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

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

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

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

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

    1. [変数とシークレット] をクリックします。
    2. 環境変数ごとに [+ 変数を追加] をクリックします。
    変数名 値の例 説明
    GCS_BUCKET delinea-centrify-logs-bucket GCS バケット名
    GCS_PREFIX centrify-sso-logs ログファイルの接頭辞
    STATE_KEY centrify-sso-logs/state.json 状態ファイルのパス
    TENANT_URL https://yourtenant.my.centrify.com Delinea テナント URL
    CLIENT_ID your-client-id OAuth クライアント ID
    CLIENT_SECRET your-client-secret OAuth クライアント シークレット
    OAUTH_APP_ID your-oauth-application-id OAuth アプリケーション ID
    PAGE_SIZE 1000 1 ページあたりのレコード数
    MAX_PAGES 10 取得する最大ページ数
  10. [変数とシークレット] セクションで、[リクエスト] まで下にスクロールします。

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

    • [リソース] セクションで次の操作を行います。
      • メモリ: 512 MiB 以上を選択します。
      • CPU: [1] を選択します。
  12. [リビジョン スケーリング] セクションで、次の操作を行います。

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

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

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

関数コードを追加する

  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
    import base64
    
    # 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 Delinea Centrify SSO audit events 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', 'centrify-sso-logs')
        state_key = os.environ.get('STATE_KEY', 'centrify-sso-logs/state.json')
    
        # Centrify API credentials
        tenant_url = os.environ.get('TENANT_URL')
        client_id = os.environ.get('CLIENT_ID')
        client_secret = os.environ.get('CLIENT_SECRET')
        oauth_app_id = os.environ.get('OAUTH_APP_ID')
    
        # Optional parameters
        page_size = int(os.environ.get('PAGE_SIZE', '1000'))
        max_pages = int(os.environ.get('MAX_PAGES', '10'))
    
        if not all([bucket_name, tenant_url, client_id, client_secret, oauth_app_id]):
            print('Error: Missing required environment variables')
            return
    
        try:
            # Get GCS bucket
            bucket = storage_client.bucket(bucket_name)
    
            # Load state (last processed timestamp)
            state = load_state(bucket, state_key)
            last_timestamp = state.get('last_timestamp')
    
            print(f'Processing logs since {last_timestamp if last_timestamp else "24 hours ago"}')
    
            # Get OAuth access token
            access_token = get_oauth_token(tenant_url, client_id, client_secret, oauth_app_id)
    
            # Fetch audit events
            events = fetch_audit_events(tenant_url, access_token, last_timestamp, page_size, max_pages)
    
            if events:
                # Write events to GCS
                current_timestamp = datetime.now(timezone.utc)
                blob_name = f"{prefix}/centrify-sso-events-{current_timestamp.strftime('%Y%m%d_%H%M%S')}.json"
                blob = bucket.blob(blob_name)
    
                # Convert to JSONL format (one JSON object per line)
                jsonl_content = '\n'.join([json.dumps(event, default=str) for event in events])
                blob.upload_from_string(jsonl_content, content_type='application/x-ndjson')
    
                print(f'Wrote {len(events)} events to {blob_name}')
    
                # Update state with latest timestamp
                latest_timestamp = get_latest_event_timestamp(events)
                save_state(bucket, state_key, {'last_timestamp': latest_timestamp, 'updated_at': current_timestamp.isoformat() + 'Z'})
    
                print(f'Successfully processed {len(events)} events')
            else:
                print('No new events found')
    
        except Exception as e:
            print(f'Error processing Centrify SSO logs: {str(e)}')
            raise
    
    def get_oauth_token(tenant_url, client_id, client_secret, oauth_app_id):
        """Get OAuth access token using client credentials flow."""
        credentials = f"{client_id}:{client_secret}"
        basic_auth = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
    
        token_url = f"{tenant_url}/oauth2/token/{oauth_app_id}"
        headers = {
            'Authorization': f'Basic {basic_auth}',
            'X-CENTRIFY-NATIVE-CLIENT': 'True',
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    
        data = {
            'grant_type': 'client_credentials',
            'scope': 'redrock/query'
        }
    
        response = http.request('POST', token_url, headers=headers, fields=data)
    
        if response.status != 200:
            raise Exception(f"OAuth token request failed: {response.status} {response.data.decode('utf-8')}")
    
        token_data = json.loads(response.data.decode('utf-8'))
        return token_data['access_token']
    
    def fetch_audit_events(tenant_url, access_token, last_timestamp, page_size, max_pages):
        """Fetch audit events from Centrify using the Redrock/query API with proper pagination."""
        query_url = f"{tenant_url}/Redrock/query"
        headers = {
            'Authorization': f'Bearer {access_token}',
            'X-CENTRIFY-NATIVE-CLIENT': 'True',
            'Content-Type': 'application/json'
        }
    
        # Build SQL query with timestamp filter
        if last_timestamp:
            sql_query = f"Select * from Event where WhenOccurred > '{last_timestamp}' ORDER BY WhenOccurred ASC"
        else:
            # First run - get events from last 24 hours
            sql_query = "Select * from Event where WhenOccurred > datefunc('now', '-1') ORDER BY WhenOccurred ASC"
    
        all_events = []
        page_num = 1
        backoff = 1.0
    
        while page_num <= max_pages:
            payload = {
                "Script": sql_query,
                "args": {
                    "PageNumber": page_num,
                    "PageSize": page_size,
                    "Limit": page_size * max_pages,
                    "Caching": -1
                }
            }
    
            try:
                response = http.request('POST', query_url, headers=headers, body=json.dumps(payload))
    
                # Handle rate limiting with exponential backoff
                if response.status == 429:
                    retry_after = int(response.headers.get('Retry-After', str(int(backoff))))
                    print(f"Rate limited (429). Retrying after {retry_after}s...")
                    time.sleep(retry_after)
                    backoff = min(backoff * 2, 30.0)
                    continue
    
                backoff = 1.0
    
                if response.status != 200:
                    raise Exception(f"API query failed: {response.status} {response.data.decode('utf-8')}")
    
                response_data = json.loads(response.data.decode('utf-8'))
    
                if not response_data.get('success', False):
                    raise Exception(f"API query failed: {response_data.get('Message', 'Unknown error')}")
    
                # Parse the response
                result = response_data.get('Result', {})
                columns = {col['Name']: i for i, col in enumerate(result.get('Columns', []))}
                raw_results = result.get('Results', [])
    
                if not raw_results:
                    print(f"No more results on page {page_num}")
                    break
    
                print(f"Page {page_num}: Retrieved {len(raw_results)} events")
    
                for raw_event in raw_results:
                    event = {}
                    row_data = raw_event.get('Row', {})
    
                    # Map column names to values
                    for col_name, col_index in columns.items():
                        if col_name in row_data and row_data[col_name] is not None:
                            event[col_name] = row_data[col_name]
    
                    # Add metadata
                    event['_source'] = 'centrify_sso'
                    event['_collected_at'] = datetime.now(timezone.utc).isoformat() + 'Z'
    
                    all_events.append(event)
    
                # Check if we've reached the end
                if len(raw_results) < page_size:
                    print(f"Reached last page (page {page_num} returned {len(raw_results)} < {page_size})")
                    break
    
                page_num += 1
    
            except Exception as e:
                print(f"Error fetching page {page_num}: {e}")
                raise
    
        print(f"Retrieved {len(all_events)} total events from {page_num} pages")
        return all_events
    
    def get_latest_event_timestamp(events):
        """Get the latest timestamp from the events for state tracking."""
        if not events:
            return datetime.now(timezone.utc).isoformat() + 'Z'
    
        latest = None
        for event in events:
            when_occurred = event.get('WhenOccurred')
            if when_occurred:
                if latest is None or when_occurred > latest:
                    latest = when_occurred
    
        return latest or datetime.now(timezone.utc).isoformat() + 'Z'
    
    def load_state(bucket, key):
        """Load state from GCS."""
        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)}')
        return {}
    
    def save_state(bucket, key, state):
        """Save state to GCS."""
        try:
            blob = bucket.blob(key)
            blob.upload_from_string(
                json.dumps(state),
                content_type='application/json'
            )
        except Exception as e:
            print(f'Warning: Could not save state: {str(e)}')
    
    • 2 つ目のファイル: 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 functions の関数をトリガーします。

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

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

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

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

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

統合をテストする

  1. Cloud Scheduler コンソールで、ジョブ(delinea-sso-log-export-hourly など)を見つけます。
  2. [強制実行] をクリックして、ジョブを手動でトリガーします。
  3. 数秒待ちます。
  4. Cloud Run > サービスに移動します。
  5. 関数名 delinea-sso-log-export をクリックします。
  6. [Logs] タブをクリックします。
  7. 関数が正常に実行されたことを確認します。次の内容を確認します。

    Processing logs since YYYY-MM-DDTHH:MM:SS+00:00
    Page 1: Retrieved X events
    Wrote X events to centrify-sso-logs/centrify-sso-events_YYYYMMDD_HHMMSS.json
    Successfully processed X events
    
  8. [Cloud Storage] > [バケット] に移動します。

  9. バケット名(delinea-centrify-logs-bucket など)をクリックします。

  10. プレフィックス フォルダ centrify-sso-logs/ に移動します。

  11. 現在のタイムスタンプで新しい .json ファイルが作成されたことを確認します。

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

  • HTTP 401: 環境変数(CLIENT_ID、CLIENT_SECRET、OAUTH_APP_ID)で API 認証情報を確認します。
  • HTTP 403: OAuth クライアントにレポート: 監査イベント: 表示権限があることを確認する
  • HTTP 429: レート制限 - 関数はバックオフで自動的に再試行されます
  • 環境変数がありません: 必要な変数がすべて Cloud Run 関数の構成で設定されていることを確認します

Google SecOps サービス アカウントを取得する

Google SecOps は、一意のサービス アカウントを使用して GCS バケットからデータを読み取ります。このサービス アカウントにバケットへのアクセス権を付与する必要があります。

サービス アカウントのメールアドレスを取得する

  1. [SIEM 設定] > [フィード] に移動します。
  2. [Add New Feed] をクリックします。
  3. [単一フィードを設定] をクリックします。
  4. [フィード名] フィールドに、フィードの名前を入力します(例: Delinea Centrify SSO logs)。
  5. [ソースタイプ] として [Google Cloud Storage V2] を選択します。
  6. [ログタイプ] として [Centrify] を選択します。
  7. [サービス アカウントを取得する] をクリックします。一意のサービス アカウント メールアドレスが表示されます(例:)。

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

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

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

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

Delinea(Centrify)SSO ログを取り込むように Google SecOps でフィードを構成する

  1. [SIEM 設定] > [フィード] に移動します。
  2. [Add New Feed] をクリックします。
  3. [単一フィードを設定] をクリックします。
  4. [フィード名] フィールドに、フィードの名前を入力します(例: Delinea Centrify SSO logs)。
  5. [ソースタイプ] として [Google Cloud Storage V2] を選択します。
  6. [ログタイプ] として [Centrify] を選択します。
  7. [次へ] をクリックします。
  8. 次の入力パラメータの値を指定します。

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

      gs://delinea-centrify-logs-bucket/centrify-sso-logs/
      
      • 次のように置き換えます。

        • delinea-centrify-logs-bucket: GCS バケット名。
        • centrify-sso-logs: ログが保存されるオプションの接頭辞/フォルダパス(ルートの場合は空のままにします)。
      • 例:

        • ルートバケット: gs://company-logs/
        • 接頭辞あり: gs://company-logs/centrify-sso-logs/
        • サブフォルダあり: gs://company-logs/delinea/sso/
    • Source deletion option: 必要に応じて削除オプションを選択します。

      • なし: 転送後にファイルを削除しません(テストにおすすめ)。
      • 転送されたファイルを削除する: 転送が完了した後にファイルを削除します。
      • 転送されたファイルと空のディレクトリを削除する: 転送が完了した後にファイルと空のディレクトリを削除します。

    • ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます。デフォルトは 180 日です。

    • アセットの名前空間: アセットの名前空間

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

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

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

UDM マッピング テーブル

ログフィールド UDM マッピング 論理
AccountID security_result.detection_fields.value 未加工ログの AccountID の値は、キーが Account ID の security_result.detection_fields オブジェクトに割り当てられます。
ApplicationName target.application 未加工ログの ApplicationName の値が target.application フィールドに割り当てられます。
AuthorityFQDN target.asset.network_domain 未加工ログの AuthorityFQDN の値が target.asset.network_domain フィールドに割り当てられます。
AuthorityID target.asset.asset_id 未加工ログの AuthorityID の値が、接頭辞「AuthorityID:」を付けて target.asset.asset_id フィールドに割り当てられます。
AzDeploymentId security_result.detection_fields.value 未加工ログの AzDeploymentId の値は、キーが AzDeploymentId の security_result.detection_fields オブジェクトに割り当てられます。
AzRoleId additional.fields.value.string_value 未加工ログの AzRoleId の値が、キー AzRoleId を持つ additional.fields オブジェクトに割り当てられます。
AzRoleName target.user.attribute.roles.name 未加工ログの AzRoleName の値が target.user.attribute.roles.name フィールドに割り当てられます。
ComputerFQDN principal.asset.network_domain 未加工ログの ComputerFQDN の値が principal.asset.network_domain フィールドに割り当てられます。
ComputerID principal.asset.asset_id 未加工ログの ComputerID の値は、接頭辞「ComputerId:」付きで principal.asset.asset_id フィールドに割り当てられます。
ComputerName about.hostname 未加工ログの ComputerName の値が about.hostname フィールドに割り当てられます。
CredentialId security_result.detection_fields.value 未加工ログの CredentialId の値は、キーが Credential Id の security_result.detection_fields オブジェクトに割り当てられます。
DirectoryServiceName security_result.detection_fields.value 未加工ログの DirectoryServiceName の値は、キーが Directory Service Name の security_result.detection_fields オブジェクトに割り当てられます。
DirectoryServiceNameLocalized security_result.detection_fields.value 未加工ログの DirectoryServiceNameLocalized の値は、キーが「Directory Service Name Localized」の security_result.detection_fields オブジェクトに割り当てられます。
DirectoryServiceUuid security_result.detection_fields.value 未加工ログの DirectoryServiceUuid の値は、キーが Directory Service Uuid の security_result.detection_fields オブジェクトに割り当てられます。
EventMessage security_result.summary 未加工ログの EventMessage の値が security_result.summary フィールドに割り当てられます。
EventType metadata.product_event_type 未加工ログの EventType の値が metadata.product_event_type フィールドに割り当てられます。また、metadata.event_type の特定にも使用されます。
FailReason security_result.summary 未加工ログの FailReason の値は、存在する場合は security_result.summary フィールドに割り当てられます。
FailUserName target.user.email_addresses 未加工ログの FailUserName の値は、存在する場合は target.user.email_addresses フィールドに割り当てられます。
FromIPAddress principal.ip 未加工ログの FromIPAddress の値が principal.ip フィールドに割り当てられます。
ID security_result.detection_fields.value 未加工ログの ID の値は、キーが ID の security_result.detection_fields オブジェクトに割り当てられます。
InternalTrackingID metadata.product_log_id 未加工ログの InternalTrackingID の値は、metadata.product_log_id フィールドに割り当てられます。
JumpType additional.fields.value.string_value 未加工ログの JumpType の値が、キー「Jump Type」を持つ additional.fields オブジェクトに割り当てられます。
NormalizedUser target.user.email_addresses 未加工ログの NormalizedUser の値が target.user.email_addresses フィールドに割り当てられます。
OperationMode additional.fields.value.string_value 未加工ログの OperationMode の値は、キーが「Operation Mode」の additional.fields オブジェクトに割り当てられます。
ProxyId security_result.detection_fields.value 未加工ログの ProxyId の値は、キー「Proxy Id」を持つ security_result.detection_fields オブジェクトに割り当てられます。
RequestUserAgent network.http.user_agent 未加工ログの RequestUserAgent の値は、network.http.user_agent フィールドに割り当てられます。
SessionGuid network.session_id 未加工ログの SessionGuid の値が network.session_id フィールドに割り当てられます。
テナント additional.fields.value.string_value 未加工ログの Tenant の値が、キー Tenant を持つ additional.fields オブジェクトに割り当てられます。
ThreadType additional.fields.value.string_value 未加工ログの ThreadType の値は、キー「Thread Type」を持つ additional.fields オブジェクトに割り当てられます。
UserType principal.user.attribute.roles.name 未加工ログの UserType の値が principal.user.attribute.roles.name フィールドに割り当てられます。
WhenOccurred metadata.event_timestamp 未加工ログの WhenOccurred の値が解析され、metadata.event_timestamp フィールドに割り当てられます。このフィールドには、最上位のタイムスタンプ フィールドも入力されます。
ハードコードされた値 metadata.product_name 「SSO」と入力します。
ハードコードされた値 metadata.event_type EventType フィールドによって決まります。EventType が存在しない場合や、特定の条件に一致しない場合のデフォルトは STATUS_UPDATE です。USER_LOGIN、USER_CREATION、USER_RESOURCE_ACCESS、USER_LOGOUT、USER_CHANGE_PASSWORD のいずれかになります。
ハードコードされた値 metadata.vendor_name "CENTRIFY_SSO"。
ハードコードされた値 metadata.product_version 「SSO」と入力します。
ハードコードされた値 metadata.log_type 「Centrify」と入力します。
メッセージ フィールドから抽出 network.session_id メッセージ フィールドにセッション ID が含まれている場合は、抽出されて使用されます。それ以外の場合はデフォルトで「1」になります。
ホスト フィールドから抽出 principal.hostname Syslog ヘッダーから取得したホスト フィールドから抽出されます(利用可能な場合)。
pid フィールドから抽出 principal.process.pid syslog ヘッダーから取得される pid フィールドから抽出されます(利用可能な場合)。
UserGuid またはメッセージから抽出 target.user.userid UserGuid が存在する場合は、その値が使用されます。それ以外の場合、メッセージ フィールドにユーザー ID が含まれていれば、抽出されて使用されます。
Level と FailReason によって決定されます security_result.action Level が「Info」の場合は「ALLOW」、FailReason が存在する場合は「BLOCK」に設定されます。
FailReason で判断 security_result.category FailReason が存在する場合は、「AUTH_VIOLATION」に設定します。
[Level] フィールドで決定 security_result.severity Level フィールドによって決定されます。レベルが「Info」の場合は「INFORMATIONAL」、レベルが「Warning」の場合は「MEDIUM」、レベルが「Error」の場合は「ERROR」に設定します。

ご不明な点がございましたら、コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。