收集 Azure DevOps 稽核記錄
支援的國家/地區:
Google SecOps
SIEM
總覽
這個剖析器會處理 JSON 格式的 Azure DevOps 稽核記錄。這個外掛程式會從巢狀和頂層 JSON 結構中擷取欄位,並將這些欄位對應至 UDM。系統會根據特定欄位值套用條件式邏輯,將事件分類,並在輸出內容中加入相關安全性資訊。剖析器也會處理非 JSON 格式的訊息,嘗試使用 grok 模式擷取 JSON 酬載。
事前準備
請確認您已完成下列事前準備事項:
- Google SecOps 執行個體
- 有效的 Azure DevOps 組織
- Azure DevOps Organization 和 Azure 的特殊存取權
設定動態饋給
在 Google SecOps 平台中,有兩種不同的進入點可設定動態饋給:
- 「SIEM 設定」>「動態消息」
- 內容中心 > 內容包
依序前往「SIEM 設定」>「動態消息」,設定動態消息
如要為這個產品系列中的不同記錄類型設定多個動態饋給,請參閱「依產品設定動態饋給」。
如要設定單一動態饋給,請按照下列步驟操作:
- 依序前往「SIEM 設定」>「動態饋給」。
- 按一下「新增動態消息」。
- 在下一個頁面中,按一下「設定單一動態饋給」。
- 在「動態饋給名稱」欄位中,輸入動態饋給的名稱 (例如「Azure Devops Logs」)。
- 選取「Webhook」做為「來源類型」。
- 選取「Azure Devops Audit」做為「記錄類型」。
- 點選「下一步」。
- 選用:指定下列輸入參數的值:
- 分割分隔符號:用於分隔記錄行的分隔符號,例如
\n
。 - 資產命名空間:資產命名空間。
- 擷取標籤:套用至這個動態饋給事件的標籤。
- 分割分隔符號:用於分隔記錄行的分隔符號,例如
- 點選「下一步」。
- 在「Finalize」畫面中檢查動態饋給設定,然後按一下「Submit」。
- 按一下「產生密鑰」,產生驗證這個動態消息的密鑰。
- 複製並儲存密鑰。您無法再次查看這個密鑰。如有需要,您可以重新產生新的密鑰,但這項操作會使先前的密鑰失效。
- 在「詳細資料」分頁中,從「端點資訊」欄位複製動態消息端點網址。您需要在用戶端應用程式中指定這個端點網址。
- 按一下 [完成]。
從內容中心設定動態饋給
為下列欄位指定值:
- 分割分隔符號:用於分隔記錄行的分隔符號,例如
\n
。
進階選項
- 動態饋給名稱:系統預先填入的值,用於識別動態饋給。
- 來源類型:將記錄收集到 Google SecOps 的方法。
- 資產命名空間:資產命名空間。
- 擷取標籤:套用至這個動態饋給事件的標籤。
- 點選「下一步」。
- 在「Finalize」畫面中檢查動態饋給設定,然後按一下「Submit」。
- 按一下「產生密鑰」,產生驗證這個動態消息的密鑰。
為 Webhook 資訊提供建立 API 金鑰
前往 Google Cloud 控制台 > 憑證。
按一下 [Create credentials] (建立憑證),然後選取 [API key] (API 金鑰)。
將 API 金鑰存取權限制在 Google Security Operations API。
指定端點網址
- 在用戶端應用程式中,指定 webhook 動態饋給中提供的 HTTPS 端點網址。
如要啟用驗證,請在自訂標頭中指定 API 金鑰和私密金鑰,格式如下:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
建議:請將 API 金鑰指定為標頭,而非在網址中指定。如果 Webhook 用戶端不支援自訂標頭,您可以使用查詢參數指定 API 金鑰和密鑰,格式如下:
ENDPOINT_URL?key=API_KEY&secret=SECRET
更改下列內容:
ENDPOINT_URL
:動態消息端點網址。API_KEY
:用於向 Google Security Operations 進行驗證的 API 金鑰。SECRET
:您產生的密鑰,用於驗證動態饋給。
在 Azure DevOps 中設定稽核功能
- 登入貴機構 (
https://dev.azure.com/{yourorganization}
)。 - 選取「機構設定」的齒輪圖示。
- 選取「安全性」下方的「政策」。
- 將「記錄稽核事件」按鈕切換為「開啟」。
在 Azure 中設定事件方格主題
- 登入 Azure 入口網站。
- 搜尋並存取 Event Grid。
- 在「自訂事件」下方找到「主題」。
- 點選「+ 建立」。
- 選取「Subscription」(訂閱項目) 和「Resource Group」(資源群組)。提供名稱 (例如
DevopsAuditLog
) 並選取區域。按一下「檢查並建立」。 - 存取新的「主題」,然後複製「主題端點網址」。
- 依序前往「設定」>「存取金鑰」,然後複製「金鑰 1」。
將 Azure DevOps 記錄串流設定為事件方格
- 登入貴機構 (
https://dev.azure.com/{yourorganization}
)。 - 選取「機構設定」的齒輪圖示。
- 選取「稽核」。
- 前往「串流」分頁,然後依序選取「新串流」>「事件格線」。
- 輸入在「在 Azure 中設定 Event Grid 主題」中建立的主題端點和存取金鑰。
在 Azure DevOps 中為 Google SecOps 設定 Webhook
- 在 Azure 入口網站中,搜尋並存取「事件方格」。
- 選取先前建立的「主題」。
- 依序前往「實體」>「事件訂閱」。
- 按一下「+ 事件訂閱」。
- 提供描述性名稱 (例如 *
Google SecOps Integration
)。 - 選取「Web Hook」,然後按一下「設定端點」。
- 設定端點:
- 訂閱者端點:輸入 Google SecOps API 端點網址。
- 在「HTTP headers」(HTTP 標頭) 區段中,新增下列標頭:
- 標題 1:
- 金鑰:
X-goog-api-key
- 值:您在「為 Webhook 動態饋給建立 API 金鑰」一節中建立的 API 金鑰。
- 金鑰:
- 標題 2:
- 金鑰:
X-Webhook-Access-Key
- 值:您在「在 Google SecOps 中設定動態饋給,以便擷取 Azure DevOps 記錄」一節中產生的密鑰。
- 金鑰:
- 標題 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 |
用於建構 target.application 欄位,方法是在 Area 值前面加上「DevOps 」。 |
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 |
以「條件」為鍵新增為額外欄位。 |
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 |
以「範圍」為鍵新增為標籤。 |
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 |
新增為額外欄位,索引鍵為「露點」。 |
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 |
如果作業成功 (成功、已建立、已修改、已執行、已更新、已移除),請設為「ALLOW」;如果作業失敗 (失敗、逾時),請設為「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 專業人員尋求答案。