Azure DevOps 監査ログを収集する
概要
このパーサーは、JSON 形式の Azure DevOps 監査ログを処理します。ネストされた JSON 構造と最上位の JSON 構造からフィールドを抽出し、UDM にマッピングします。特定のフィールド値に基づく条件ロジックにより、イベントが分類され、関連するセキュリティ情報で出力が拡充されます。パーサーは、grok パターンを使用して JSON ペイロードの抽出を試みることで、JSON 形式以外のメッセージも処理します。
始める前に
次の前提条件を満たしていることを確認します。
- Google SecOps インスタンス
- アクティブな Azure DevOps 組織
- Azure Devops 組織と Azure への特権アクセス
フィードを設定する
Google SecOps プラットフォームでフィードを設定するには、次の 2 つのエントリ ポイントがあります。
- [SIEM 設定] > [フィード] > [新しいフィードを追加]
- Content Hub > Content Packs > Get Started
Azure DevOps 監査フィードの設定方法
- [Azure Platform] パックをクリックします。
- [Azure DevOps audit] ログタイプを見つけて、[新しいフィードを追加] をクリックします。
- 次のフィールドに値を指定します。 - ソースタイプ: Microsoft Azure Blob Storage V2。
- Azure URI: Blob エンドポイントの URL。- ENDPOINT_URL/BLOB_NAME- 次のように置き換えます。
- ENDPOINT_URL: BLOB エンドポイント URL(- https://<storageaccountname>.blob.core.windows.net)
- BLOB_NAME: blob の名前(- insights-logs-<logname>など)
 
 
- 次のように置き換えます。
 
- Source deletion options: 取り込みの設定に応じて削除オプションを選択します。 
- ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます。デフォルトは 180 日です。 
- 共有キー: Azure リソースへのアクセスに使用される共有キー(base-64 でエンコードされた 512 ビットのランダムな文字列)。 
 - 詳細オプション - フィード名: フィードを識別する事前入力された値。
- アセットの名前空間: アセットの名前空間。
- Ingestion labels: このフィードのイベントに適用されるラベル。
 
- [フィードを作成] をクリックします。 
このプロダクト ファミリー内の異なるログタイプに対して複数のフィードを構成する方法については、プロダクト別にフィードを構成するをご覧ください。
Webhook フィード用の API キーを作成する
- Google Cloud コンソール > [認証情報] に移動します。 
- [認証情報を作成] をクリックして [API キー] を選択します。 
- API キーのアクセスを Google Security Operations API に制限します。 
エンドポイント URL を指定する
- クライアント アプリケーション内で、Webhook フィードで提供される HTTPS エンドポイント URL を指定します。
- 次の形式でカスタム ヘッダーの一部として API キーと秘密鍵を指定して、認証を有効にします。 - X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET- 推奨事項: API キーは URL 内ではなくヘッダーとして指定してください。Webhook クライアントがカスタム ヘッダーをサポートしていない場合は、次の形式のクエリ パラメータを使用して API キーと秘密鍵を指定できます。 - ENDPOINT_URL?key=API_KEY&secret=SECRET
次のように置き換えます。
- ENDPOINT_URL: フィード エンドポイントの URL。
- API_KEY: Google Security Operations に対する認証に使用する API キー。
- SECRET: フィードの認証用に生成した秘密鍵。
Azure DevOps で監査機能を構成する
- 組織(https://dev.azure.com/{yourorganization})にログインします。
- [組織の設定] の歯車アイコンを選択します。
- [セキュリティ] で [ポリシー] を選択します。
- [監査イベントをログに記録する] ボタンを [オン] に切り替えます。
Azure で Event Grid トピックを構成する
- Azure Portal にログインします。
- Event Grid を検索してアクセスします。
- [カスタム イベント] の [トピック] を見つけます。
- [+ 作成] をクリックします。
- サブスクリプションとリソース グループを選択します。名前(例: DevopsAuditLog)を指定して、リージョンを選択します。[確認して作成] をクリックします。
- 新しいトピックにアクセスし、トピック エンドポイント URL をコピーします。
- [Settings] > [Access Keys] に移動し、[Key 1] をコピーします。
Azure DevOps ログ ストリームを Event Grid に構成する
- 組織(https://dev.azure.com/{yourorganization})にログインします。
- [組織の設定] の歯車アイコンを選択します。
- [監査] を選択します。
- [ストリーム] タブに移動し、[新しいストリーム] > [Event Grid] を選択します。
- Azure で Event Grid トピックを構成するで作成したトピック エンドポイントとアクセスキーを入力します。
Google SecOps 用に Azure DevOps で Webhook を構成する
- Azure Portal で、Event Grid を検索してアクセスします。
- 以前に作成したトピックを選択します。
- [Entities] > [Event Subscription] に移動します。
- [+ イベント サブスクリプション] をクリックします。
- わかりやすい名前を指定します(*Google SecOps Integrationなど)。
- [Web Hook] を選択して、[エンドポイントを構成] をクリックします。
- エンドポイントを構成します。
- サブスクライバー エンドポイント: Google SecOps API エンドポイント URL を入力します。
- [HTTP ヘッダー] セクションで、次のヘッダーを追加します。
- ヘッダー 1:
- キー: X-goog-api-key
- 値: Webhook フィード用の API キーを作成するで作成した API キー。
 
- キー: 
- ヘッダー 2:
- キー: X-Webhook-Access-Key
- 値: Azure Devops のログを取り込むように Google SecOps でフィードを構成するセクションで生成したシークレット キー。
 
- キー: 
 
- ヘッダー 1:
- Content-Type ヘッダーを application/jsonに設定します。
 
- [作成] をクリックします。
UDM マッピング テーブル
| ログフィールド | UDM マッピング | ロジック | 
|---|---|---|
| ActivityId | metadata.product_log_id | recordsフィールドが存在しない場合は未加工ログのIdフィールドから、recordsが存在する場合はdataオブジェクト内のActivityIdフィールドから直接マッピングされます。 | 
| ActionId | metadata.product_event_type | dataオブジェクト内のActionIdフィールドから直接マッピングされます。 | 
| ActorCUID | additional.fields | キーが「Actor CUID」の追加フィールドとして含まれます。 | 
| ActorDisplayName | principal.user.user_display_name | 「Azure DevOps Service」でない場合、 ActorDisplayNameフィールドから直接マッピングされます。「Azure DevOps Service」の場合は、principal.resource.attribute.labelsにラベルとして追加されます。 | 
| ActorUPN | principal.user.email_addresses | メールアドレスのパターンと一致する場合は、 ActorUPNフィールドから直接マッピングされます。 | 
| ActorUserId | principal.user.userid | ActorUserIdフィールドから直接マッピングされます。 | 
| Area | target.application | Area値の先頭に「DevOps 」を追加してtarget.applicationフィールドを構築するために使用されます。 | 
| AuthenticationMechanism | extensions.auth.auth_details、security_result.rule_id | 解析されて、認証の詳細とルール ID が抽出されます。認証の詳細は extensions.auth.auth_detailsにマッピングされます。抽出されたルール ID はsecurity_result.rule_idにマッピングされます。 | 
| CategoryDisplayName | security_result.action_details | security_result.action_detailsに直接マッピングされます。 | 
| City | principal.location.city | Cityフィールドから直接マッピングされます。 | 
| Conditions | additional.fields | キーが「Conditions」の追加フィールドとして追加されます。 | 
| Country | principal.location.country_or_region | Countryフィールドから直接マッピングされます。 | 
| Data.* | 各種 | Dataオブジェクト内のフィールドは、名前とコンテキストに基づいて異なる UDM フィールドにマッピングされます。具体的な例については、以下をご覧ください。 | 
| Data.AccessLevel | target.resource.attribute.labels | キー「AccessLevel」のラベルとして追加されます。 | 
| Data.AgentId | target.resource.product_object_id | PipelineIdとAuthorizationIdが存在しない場合、target.resource.product_object_idにマッピングされます。 | 
| Data.AgentName | target.resource.name | PipelineName、NamespaceName、DisplayNameが存在しない場合はtarget.resource.nameにマッピングされます。 | 
| Data.AuthorizationId | target.resource.product_object_id | PipelineIdが存在しない場合、target.resource.product_object_idにマッピングされます。 | 
| Data.CallerProcedure | additional.fields | キーが「CallerProcedure」の追加フィールドとして追加されます。 | 
| Data.CheckSuiteId | additional.fields | キー「CheckSuiteId」の追加フィールドとして追加されます。 | 
| Data.CheckSuiteStatus | additional.fields | キー「CheckSuiteStatus」の追加フィールドとして追加されます。 | 
| Data.ConnectionId | additional.fields | キーが「ConnectionId」の追加フィールドとして追加されます。 | 
| Data.ConnectionName | additional.fields | キーが「ConnectionName」の追加フィールドとして追加されます。 | 
| Data.ConnectionType | additional.fields | キー「ConnectionType」の追加フィールドとして追加されます。 | 
| Data.DefinitionId | additional.fields | キー「DefinitionId」の追加フィールドとして追加されます。 | 
| Data.DeploymentResult | additional.fields | キーが「DeploymentResult」の追加フィールドとして追加されます。 | 
| Data.DisplayName | target.resource.name | PipelineNameとNamespaceNameが存在しない場合、target.resource.nameにマッピングされます。 | 
| Data.EndpointIdList | additional.fields | キー「EndpointIdList」の追加フィールドとして追加されます。 | 
| Data.EnvironmentName | additional.fields | キーが「EnvironmentName」の追加フィールドとして追加されます。 | 
| Data.Filter.continuationToken | target.resource.attribute.labels | キー「continuation_token」のラベルとして追加されます。 | 
| Data.Filter.endTime | target.resource.attribute.labels | キー「filter_end_time」のラベルとして追加されます。 | 
| Data.Filter.startTime | target.resource.attribute.labels | キー「filter_start_time」のラベルとして追加されます。 | 
| Data.FinishTime | additional.fields | キーが「FinishTime」の追加フィールドとして追加されます。 | 
| Data.GroupId | target.group.product_object_id | Data.Updates.0.GroupIdが存在しない場合、target.group.product_object_idに直接マッピングされます。 | 
| Data.GroupName | target.group.group_display_name | target.group.group_display_nameに直接マッピングされます。 | 
| Data.JobName | additional.fields | キーが「JobName」の追加フィールドとして追加されます。 | 
| Data.MemberId | target.user.userid | Data.Updates.0.MemberIdが存在しない場合、target.user.useridに直接マッピングされます。 | 
| Data.MemberDisplayName | target.user.user_display_name | target.user.user_display_nameに直接マッピングされます。 | 
| Data.NamespaceId | target.resource.product_object_id | PipelineId、AuthorizationId、AgentIdが存在しない場合はtarget.resource.product_object_idにマッピングされます。 | 
| Data.NamespaceName | target.resource.name | PipelineNameが存在しない場合、target.resource.nameにマッピングされます。 | 
| Data.ownerDetails | additional.fields | キー「OwnerDetails」の追加フィールドとして追加されます。 | 
| Data.OwnerId | additional.fields | キー「OwnerId」の追加フィールドとして追加されます。 | 
| Data.PipelineId | target.resource.product_object_id | target.resource.product_object_idに直接マッピングされます。 | 
| Data.PipelineName | target.resource.name | target.resource.nameに直接マッピングされます。 | 
| Data.PipelineRevision | target.resource.attribute.labels | キー「PipelineRevision」のラベルとして追加されます。 | 
| Data.PipelineScope | target.resource.attribute.labels | キー「PipelineScope」のラベルとして追加されます。 | 
| Data.PlanType | additional.fields | キー「PlanType」の追加フィールドとして追加されます。 | 
| Data.PreviousAccessLevel | target.resource.attribute.labels | キー「PreviousAccessLevel」のラベルとして追加されます。 | 
| Data.PublisherName | target.resource.attribute.labels | キー「PublisherName」のラベルとして追加されます。 | 
| Data.Reason | additional.fields | キーが「Reason」の追加フィールドとして追加されます。 | 
| Data.ReleaseId | additional.fields | キーが「ReleaseId」の追加フィールドとして追加されます。 | 
| Data.ReleaseName | additional.fields | キーが「ReleaseName」の追加フィールドとして追加されます。 | 
| Data.RequesterId | additional.fields | キーが「RequesterId」の追加フィールドとして追加されます。 | 
| Data.RetentionLeaseId | additional.fields | キーが「RetentionLeaseId」の追加フィールドとして追加されます。 | 
| Data.RetentionOwnerId | additional.fields | キーが「RetentionOwnerId」の追加フィールドとして追加されます。 | 
| Data.RunName | additional.fields | キーが「RunName」の追加フィールドとして追加されます。 | 
| Data.Scopes | target.resource.attribute.labels | キー「Scope」のラベルとして追加されます。 | 
| Data.StageName | additional.fields | キーが「StageName」の追加フィールドとして追加されます。 | 
| Data.StartTime | additional.fields | キーが「StartTime」の追加フィールドとして追加されます。 | 
| Data.TargetUser | target.user.userid | target.user.useridに直接マッピングされます。 | 
| Data.Timestamp | metadata.event_timestamp | 解析され、 metadata.event_timestampにマッピングされます。 | 
| Data.TokenType | target.resource.attribute.labels | キー「TokenType」のラベルとして追加されます。 | 
| Data.Updates.0.GroupId | target.group.product_object_id | target.group.product_object_idに直接マッピングされます。 | 
| Data.Updates.0.MemberId | target.user.userid | target.user.useridに直接マッピングされます。 | 
| Data.ValidFrom | target.resource.attribute.labels | キー「ValidFrom」のラベルとして追加されます。 | 
| Data.ValidTo | target.resource.attribute.labels | キー「ValidTo」のラベルとして追加されます。 | 
| DewPoint | additional.fields | キーが「DewPoint」の追加フィールドとして追加されます。 | 
| Details | metadata.description | metadata.descriptionに直接マッピングされます。 | 
| Humidity | additional.fields | キーが「Humidity」の追加フィールドとして追加されます。 | 
| Icon | additional.fields | キーが「Icon」の追加フィールドとして追加されます。 | 
| Id | metadata.product_log_id | metadata.product_log_idに直接マッピングされます。 | 
| IpAddress | principal.ip | principal.ipに直接マッピングされます。 | 
| MoonPhase | additional.fields | キーが「MoonPhase」の追加フィールドとして追加されます。 | 
| Moonrise | additional.fields | キーが「Moonrise」の追加フィールドとして追加されます。 | 
| Moonset | additional.fields | キーが「Moonset」の追加フィールドとして追加されます。 | 
| OperationName | metadata.product_event_type | metadata.product_event_typeに直接マッピングされます。 | 
| Precipitation | additional.fields | キーが「Precipitation」の追加フィールドとして追加されます。 | 
| Pressure | additional.fields | キーが「Pressure」の追加フィールドとして追加されます。 | 
| ProjectId | target.resource_ancestors.product_object_id | 祖先が CLOUD_PROJECT型の場合に、target.resource_ancestors内のproduct_object_idフィールドに値を設定するために使用されます。 | 
| ProjectName | target.resource_ancestors.name、target.resource.attribute.labels | 祖先が CLOUD_PROJECT型の場合に、target.resource_ancestors内のnameフィールドに値を設定するために使用されます。また、キー「ProjectName」のラベルとしてtarget.resource.attribute.labelsにも追加されます。 | 
| RoleLocation | target.location.name | target.location.nameに直接マッピングされます。 | 
| ScopeDisplayName | target.resource_ancestors.name | 祖先が CLOUD_ORGANIZATION型の場合に、target.resource_ancestors内のnameフィールドに値を設定するために使用されます。 | 
| ScopeId | target.resource_ancestors.product_object_id | 祖先が CLOUD_ORGANIZATION型の場合に、target.resource_ancestors内のproduct_object_idフィールドに値を設定するために使用されます。 | 
| ScopeType | additional.fields | キーが「ScopeType」の追加フィールドとして追加されます。 | 
| Sunrise | additional.fields | キーが「Sunrise」の追加フィールドとして追加されます。 | 
| Sunset | additional.fields | キーが「Sunset」の追加フィールドとして追加されます。 | 
| Temperature | additional.fields | キーが「Temperature」の追加フィールドとして追加されます。 | 
| TenantId | metadata.product_deployment_id、additional.fields | metadata.product_deployment_idに直接マッピングされます。また、キーが「TenantId」の追加フィールドも追加されます。 | 
| TimeGenerated | metadata.event_timestamp | 解析され、 metadata.event_timestampにマッピングされます。 | 
| UserAgent | network.http.user_agent、network.http.parsed_user_agent | network.http.user_agentに直接マッピングされます。また、解析されてnetwork.http.parsed_user_agentにマッピングされます。 | 
| UVIndex | additional.fields | キーが「UVIndex」の追加フィールドとして追加されます。 | 
| Visibility | additional.fields | キーが「Visibility」の追加フィールドとして追加されます。 | 
| WindDirection | additional.fields | キーが「WindDirection」の追加フィールドとして追加されます。 | 
| WindSpeed | additional.fields | キーが「WindSpeed」の追加フィールドとして追加されます。 | 
| _Internal_WorkspaceResourceId | additional.fields | キーが「workspace_resource_id」の追加フィールドとして追加されます。 | 
| なし | metadata.event_type | OperationNameなどのフィールドに基づくロジックによって決定されます。特定のイベントタイプが一致しない場合のデフォルトは「GENERIC_EVENT」です。有効な値は、「STATUS_SHUTDOWN」、「RESOURCE_CREATION」、「STATUS_UPDATE」、「USER_RESOURCE_DELETION」、「RESOURCE_READ」、「RESOURCE_WRITTEN」、「RESOURCE_DELETION」、「GROUP_MODIFICATION」です。 | 
| なし | metadata.vendor_name | 「Microsoft」に設定します。 | 
| なし | metadata.product_name | 「Azure DevOps」に設定します。 | 
| なし | metadata.log_type | 「AZURE_DEVOPS」に設定します。 | 
| なし | principal.user.account_type | AuthenticationMechanismに「ServicePrincipal」が含まれている場合は「SERVICE_ACCOUNT_TYPE」に設定し、それ以外の場合は「CLOUD_ACCOUNT_TYPE」に設定します。 | 
| なし | target.asset.attribute.cloud.environment | MICROSOFT_AZUREに設定します。 | 
| なし | security_result.action | 成功したオペレーション(Succeeded、Created、Modified、executed、updated、removed)の場合は「ALLOW」、失敗したオペレーション(Failed、TimedOut)の場合は「BLOCK」に設定されます。 | 
| なし | extensions.auth.mechanism | summaryが「UserAuthToken」の場合は、「USERNAME_PASSWORD」に設定します。 | 
| なし | target.resource.resource_type | pipeline_idが存在する場合は「SETTING」、authorization_idが存在する場合は「CREDENTIAL」、agent_idが存在する場合は「DEVICE」、namespace_idが存在する場合は「DATABASE」に設定されます。それ以外の場合、operationNameに基づいて「STORAGE_BUCKET」に設定されることがあります。 | 
| なし | target.resource.resource_subtype | pipeline_idが存在する場合は「Pipeline」、authorization_idが存在する場合は「Token」、agent_idが存在する場合は「Agent」、namespace_idが存在する場合は「Namespace」に設定します。 | 
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。