Coletar registros de auditoria do Azure DevOps
Visão geral
Esse analisador processa os registros de auditoria do Azure DevOps no formato JSON. Ele extrai campos de estruturas JSON aninhadas e de nível superior, mapeando-as para o UDM. A lógica condicional baseada em valores de campo específicos categoriza eventos e enriquece a saída com informações de segurança relevantes. O analisador também processa mensagens não formatadas em JSON tentando extrair um payload JSON usando padrões grok.
Antes de começar
- Verifique se você tem uma instância do Google SecOps.
- Verifique se você tem uma organização ativa do Azure DevOps.
- Verifique se você tem acesso privilegiado à organização do Azure DevOps e ao Azure.
Configurar um feed no Google SecOps para processar os registros do Azure DevOps
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo.
- No campo Nome do feed, insira um nome para o feed (por exemplo, Azure Devops Logs).
- Selecione Webhook como o Tipo de origem.
- Selecione Azure Devops como o Tipo de registro.
- Clique em Próxima.
- Opcional: especifique valores para os seguintes parâmetros de entrada:
- Delimitador de divisão: o delimitador usado para separar linhas de registro, como
\n
. - Namespace de recursos: o namespace de recursos.
- Rótulos de ingestão: o rótulo aplicado aos eventos desse feed.
- Delimitador de divisão: o delimitador usado para separar linhas de registro, como
- Clique em Próxima.
- Revise a configuração do feed na tela Finalizar e clique em Enviar.
- Clique em Gerar chave secreta para gerar uma chave secreta para autenticar esse feed.
- Copie e armazene a chave secreta. Não é possível acessar essa chave secreta novamente. Se necessário, você pode gerar uma nova chave secreta, mas essa ação torna a chave secreta anterior obsoleta.
- Na guia Detalhes, copie o URL do endpoint do feed no campo Informações do endpoint. É necessário especificar esse URL de endpoint no aplicativo cliente.
- Clique em Concluído.
Criar uma chave de API para o feed de webhook
Acesse o console do Google Cloud > Credenciais.
Clique em Criar credenciais e, em seguida, selecione Chave de API.
Restrinja o acesso da chave de API à API Google Security Operations.
Especificar o URL do endpoint
- No aplicativo cliente, especifique o URL do endpoint HTTPS fornecido no feed de webhook.
Ative a autenticação especificando a chave de API e a chave secreta como parte do cabeçalho personalizado no seguinte formato:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
Recomendação: especifique a chave de API como um cabeçalho em vez de especificar no URL. Se o cliente do webhook não tiver suporte a cabeçalhos personalizados, especifique a chave de API e a chave secreta usando parâmetros de consulta no seguinte formato:
ENDPOINT_URL?key=API_KEY&secret=SECRET
Substitua:
ENDPOINT_URL
: o URL do endpoint do feed.API_KEY
: a chave de API para autenticação no Google Security Operations.SECRET
: a chave secreta gerada para autenticar o feed.
Configurar o recurso de auditoria no Azure DevOps
- Faça login na sua organização (
https://dev.azure.com/{yourorganization}
). - Selecione o ícone de engrenagem em Configurações da organização.
- Selecione Políticas em Segurança.
- Alterne o botão Registrar eventos de auditoria para Ativado.
Configurar um tópico do Event Grid no Azure
- Faça login no portal do Azure.
- Pesquise e acesse a grade de eventos.
- Localize Tópicos em Eventos personalizados.
- Clique em Criar.
- Selecione sua assinatura e o grupo de recursos. Informe um nome (por exemplo, DevopsAuditLog) e selecione a região. Clique em Revisar e criar.
- Acesse o novo Tópico e copie o URL do endpoint do tópico.
- Acesse Configurações > Chaves de acesso e copie a Chave 1.
Configurar o fluxo de registro do Azure DevOps para o Event Grid
- Faça login na sua organização (
https://dev.azure.com/{yourorganization}
). - Selecione o ícone de engrenagem em Configurações da organização.
- Selecione Auditoria.
- Acesse a guia Streams e selecione New stream > Event Grid.
- Insira o endpoint do tópico e a chave de acesso criados em Configurar um tópico do Event Grid no Azure.
Configurar um webhook no Azure DevOps para o Google SecOps
- No portal do Azure, pesquise e acesse o Event Grid.
- Selecione o Tópico criado anteriormente.
- Acesse Entidades > Assinatura de eventos.
- Clique em + Assinatura de evento.
- Forneça um nome descritivo (por exemplo, Integração do Google SecOps).
- Selecione Gancho da Web e clique em Configurar um endpoint.
- Configure o endpoint:
- Endpoint do assinante: insira o URL do endpoint da API Google SecOps.
- Anexe
?key=<API_KEY>&secret=<SECRET_KEY>
ao URL do payload. - Defina o cabeçalho Content-Type como application/json.
- Clique em Criar.
Tabela de mapeamento do UDM
Campo de registro | Mapeamento do UDM | Lógica |
---|---|---|
ActivityId |
metadata.product_log_id |
Mapeado diretamente do campo Id no registro bruto quando o campo records não está presente ou do campo ActivityId no objeto data quando records está presente. |
ActionId |
metadata.product_event_type |
Mapeado diretamente do campo ActionId no objeto data . |
ActorCUID |
additional.fields |
Incluído como um campo extra com a chave "Actor CUID". |
ActorDisplayName |
principal.user.user_display_name |
Mapeado diretamente do campo ActorDisplayName , se não for "Azure DevOps Service". Se for "Azure DevOps Service", ele será adicionado como um rótulo a principal.resource.attribute.labels . |
ActorUPN |
principal.user.email_addresses |
Mapeado diretamente do campo ActorUPN se ele corresponder a um padrão de endereço de e-mail. |
ActorUserId |
principal.user.userid |
Mapeado diretamente do campo ActorUserId . |
Area |
target.application |
É usado para construir o campo target.application precedido por "DevOps " no valor Area . |
AuthenticationMechanism |
extensions.auth.auth_details , security_result.rule_id |
Analisado para extrair detalhes de autenticação e o ID da regra. Os detalhes de autenticação são mapeados para extensions.auth.auth_details . O ID da regra extraído é mapeado para security_result.rule_id . |
CategoryDisplayName |
security_result.action_details |
Mapeado diretamente para security_result.action_details . |
City |
principal.location.city |
Mapeado diretamente do campo City . |
Conditions |
additional.fields |
Adicionado como um campo extra com a chave "Condições". |
Country |
principal.location.country_or_region |
Mapeado diretamente do campo Country . |
Data.* |
Vários | Os campos no objeto Data são mapeados para diferentes campos do UDM com base nos nomes e no contexto. Confira abaixo exemplos específicos. |
Data.AccessLevel |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "AccessLevel". |
Data.AgentId |
target.resource.product_object_id |
Mapeado para target.resource.product_object_id se PipelineId e AuthorizationId não estiverem presentes. |
Data.AgentName |
target.resource.name |
É mapeado para target.resource.name se PipelineName , NamespaceName e DisplayName não estiverem presentes. |
Data.AuthorizationId |
target.resource.product_object_id |
Mapeado para target.resource.product_object_id se PipelineId não estiver presente. |
Data.CallerProcedure |
additional.fields |
Adicionado como um campo adicional com a chave "CallerProcedure". |
Data.CheckSuiteId |
additional.fields |
Adicionado como um campo adicional com a chave "CheckSuiteId". |
Data.CheckSuiteStatus |
additional.fields |
Adicionado como um campo adicional com a chave "CheckSuiteStatus". |
Data.ConnectionId |
additional.fields |
Adicionado como um campo extra com a chave "ConnectionId". |
Data.ConnectionName |
additional.fields |
Adicionado como um campo extra com a chave "ConnectionName". |
Data.ConnectionType |
additional.fields |
Adicionado como um campo extra com a chave "ConnectionType". |
Data.DefinitionId |
additional.fields |
Adicionado como um campo extra com a chave "DefinitionId". |
Data.DeploymentResult |
additional.fields |
Adicionado como um campo extra com a chave "DeploymentResult". |
Data.DisplayName |
target.resource.name |
Mapeado para target.resource.name se PipelineName e NamespaceName não estiverem presentes. |
Data.EndpointIdList |
additional.fields |
Adicionado como um campo extra com a chave "EndpointIdList". |
Data.EnvironmentName |
additional.fields |
Adicionado como um campo extra com a chave "EnvironmentName". |
Data.Filter.continuationToken |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "continuation_token". |
Data.Filter.endTime |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "filter_end_time". |
Data.Filter.startTime |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "filter_start_time". |
Data.FinishTime |
additional.fields |
Adicionado como um campo extra com a chave "FinishTime". |
Data.GroupId |
target.group.product_object_id |
Mapeado diretamente para target.group.product_object_id quando Data.Updates.0.GroupId não está presente. |
Data.GroupName |
target.group.group_display_name |
Mapeado diretamente para target.group.group_display_name . |
Data.JobName |
additional.fields |
Adicionado como um campo adicional com a chave "JobName". |
Data.MemberId |
target.user.userid |
Mapeado diretamente para target.user.userid quando Data.Updates.0.MemberId não está presente. |
Data.MemberDisplayName |
target.user.user_display_name |
Mapeado diretamente para target.user.user_display_name . |
Data.NamespaceId |
target.resource.product_object_id |
Mapeado para target.resource.product_object_id se PipelineId , AuthorizationId e AgentId não estiverem presentes. |
Data.NamespaceName |
target.resource.name |
Mapeado para target.resource.name se PipelineName não estiver presente. |
Data.ownerDetails |
additional.fields |
Adicionado como um campo adicional com a chave "OwnerDetails". |
Data.OwnerId |
additional.fields |
Adicionado como um campo adicional com a chave "OwnerId". |
Data.PipelineId |
target.resource.product_object_id |
Mapeado diretamente para target.resource.product_object_id . |
Data.PipelineName |
target.resource.name |
Mapeado diretamente para target.resource.name . |
Data.PipelineRevision |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "PipelineRevision". |
Data.PipelineScope |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "PipelineScope". |
Data.PlanType |
additional.fields |
Adicionado como um campo extra com a chave "PlanType". |
Data.PreviousAccessLevel |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "PreviousAccessLevel". |
Data.PublisherName |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "PublisherName". |
Data.Reason |
additional.fields |
Adicionado como um campo extra com a chave "Reason". |
Data.ReleaseId |
additional.fields |
Adicionado como um campo extra com a chave "ReleaseId". |
Data.ReleaseName |
additional.fields |
Adicionado como um campo extra com a chave "ReleaseName". |
Data.RequesterId |
additional.fields |
Adicionado como um campo adicional com a chave "RequesterId". |
Data.RetentionLeaseId |
additional.fields |
Adicionado como um campo extra com a chave "RetentionLeaseId". |
Data.RetentionOwnerId |
additional.fields |
Adicionado como um campo extra com a chave "RetentionOwnerId". |
Data.RunName |
additional.fields |
Adicionado como um campo extra com a chave "RunName". |
Data.Scopes |
target.resource.attribute.labels |
Adicionados como rótulos com a chave "Escopo". |
Data.StageName |
additional.fields |
Adicionado como um campo extra com a chave "StageName". |
Data.StartTime |
additional.fields |
Adicionado como um campo extra com a chave "StartTime". |
Data.TargetUser |
target.user.userid |
Mapeado diretamente para target.user.userid . |
Data.Timestamp |
metadata.event_timestamp |
Analisado e mapeado para metadata.event_timestamp . |
Data.TokenType |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "TokenType". |
Data.Updates.0.GroupId |
target.group.product_object_id |
Mapeado diretamente para target.group.product_object_id . |
Data.Updates.0.MemberId |
target.user.userid |
Mapeado diretamente para target.user.userid . |
Data.ValidFrom |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "ValidFrom". |
Data.ValidTo |
target.resource.attribute.labels |
Adicionado como um rótulo com a chave "ValidTo". |
DewPoint |
additional.fields |
Adicionado como um campo extra com a chave "DewPoint". |
Details |
metadata.description |
Mapeado diretamente para metadata.description . |
Humidity |
additional.fields |
Adicionado como um campo adicional com a chave "Humidity". |
Icon |
additional.fields |
Adicionado como um campo extra com a chave "Ícone". |
Id |
metadata.product_log_id |
Mapeado diretamente para metadata.product_log_id . |
IpAddress |
principal.ip |
Mapeado diretamente para principal.ip . |
MoonPhase |
additional.fields |
Adicionado como um campo extra com a chave "MoonPhase". |
Moonrise |
additional.fields |
Adicionado como um campo extra com a chave "Moonrise". |
Moonset |
additional.fields |
Adicionado como um campo extra com a chave "Moonset". |
OperationName |
metadata.product_event_type |
Mapeado diretamente para metadata.product_event_type . |
Precipitation |
additional.fields |
Adicionado como um campo extra com a chave "Precipitação". |
Pressure |
additional.fields |
Adicionado como um campo extra com a chave "Pressão". |
ProjectId |
target.resource_ancestors.product_object_id |
Usado para preencher o campo product_object_id em target.resource_ancestors quando o ancestral é do tipo CLOUD_PROJECT . |
ProjectName |
target.resource_ancestors.name , target.resource.attribute.labels |
Usado para preencher o campo name em target.resource_ancestors quando o ancestral é do tipo CLOUD_PROJECT . Também adicionado como um rótulo a target.resource.attribute.labels com a chave "ProjectName". |
RoleLocation |
target.location.name |
Mapeado diretamente para target.location.name . |
ScopeDisplayName |
target.resource_ancestors.name |
Usado para preencher o campo name em target.resource_ancestors quando o ancestral é do tipo CLOUD_ORGANIZATION . |
ScopeId |
target.resource_ancestors.product_object_id |
Usado para preencher o campo product_object_id em target.resource_ancestors quando o ancestral é do tipo CLOUD_ORGANIZATION . |
ScopeType |
additional.fields |
Adicionado como um campo extra com a chave "ScopeType". |
Sunrise |
additional.fields |
Adicionado como um campo extra com a chave "Sunrise". |
Sunset |
additional.fields |
Adicionado como um campo extra com a chave "Sunset". |
Temperature |
additional.fields |
Adicionado como um campo adicional com a chave "Temperature". |
TenantId |
metadata.product_deployment_id , additional.fields |
Mapeado diretamente para metadata.product_deployment_id . Também foi adicionado como um campo adicional com a chave "TenantId". |
TimeGenerated |
metadata.event_timestamp |
Analisado e mapeado para metadata.event_timestamp . |
UserAgent |
network.http.user_agent , network.http.parsed_user_agent |
Mapeado diretamente para network.http.user_agent . Também analisado e mapeado para network.http.parsed_user_agent . |
UVIndex |
additional.fields |
Adicionado como um campo adicional com a chave "UVIndex". |
Visibility |
additional.fields |
Adicionado como um campo extra com a chave "Visibilidade". |
WindDirection |
additional.fields |
Adicionado como um campo adicional com a chave "WindDirection". |
WindSpeed |
additional.fields |
Adicionado como um campo extra com a chave "WindSpeed". |
_Internal_WorkspaceResourceId |
additional.fields |
Adicionado como um campo adicional com a chave "workspace_resource_id". |
N/A | metadata.event_type |
Determinado pela lógica com base no OperationName e em outros campos. O padrão é "GENERIC_EVENT" se nenhum tipo de evento específico for encontrado. Os valores possíveis incluem "STATUS_SHUTDOWN", "RESOURCE_CREATION", "STATUS_UPDATE", "USER_RESOURCE_DELETION", "RESOURCE_READ", "RESOURCE_WRITTEN", "RESOURCE_DELETION" e "GROUP_MODIFICATION". |
N/A | metadata.vendor_name |
Defina como "Microsoft". |
N/A | metadata.product_name |
Defina como "Azure DevOps". |
N/A | metadata.log_type |
Defina como "AZURE_DEVOPS". |
N/A | principal.user.account_type |
Defina como "SERVICE_ACCOUNT_TYPE" se AuthenticationMechanism contiver "ServicePrincipal". Caso contrário, defina como "CLOUD_ACCOUNT_TYPE". |
N/A | target.asset.attribute.cloud.environment |
Defina como MICROSOFT_AZURE . |
N/A | security_result.action |
Defina como "PERMITIR" para operações bem-sucedidas (sucedidas, criadas, modificadas, executadas, atualizadas, removidas) e "BLOQUEAR" para operações com falha (falha, tempo limite). |
N/A | extensions.auth.mechanism |
Defina como "USERNAME_PASSWORD" se summary for "UserAuthToken". |
N/A | target.resource.resource_type |
Defina como "SETTING" se pipeline_id estiver presente, "CREDENTIAL" se authorization_id estiver presente, "DEVICE" se agent_id estiver presente ou "DATABASE" se namespace_id estiver presente. Caso contrário, ele será definido como "STORAGE_BUCKET" em alguns casos com base em operationName . |
N/A | target.resource.resource_subtype |
Defina como "Pipeline" se pipeline_id estiver presente, "Token" se authorization_id estiver presente, "Agente" se agent_id estiver presente ou "Namespace" se namespace_id estiver presente. |
Alterações
2024-01-19
- O valor "metadata.eventtype" foi alterado de "SERVICE*" para "USER_RESOURCE_UPDATE_CONTENT" se os dados do usuário principal e do recurso de destino estiverem presentes.
- O mapeamento de "IpAddress" mudou de "target.ip" para "principal.ip".
- O mapeamento de "ActorCUID" foi alterado de "principal.user.product_object_id" para "additional.fields".
- O mapeamento de "ScopeId" mudou de "principal.asset_id" para "resource_ancestors.product_object_id".
- O mapeamento de "_Internal_WorkspaceResourceId" foi alterado de "target.resource.product_object_id" para "additional.fields".
- O mapeamento de "ProjectId" mudou de "target.resource.attribute.labels" para "target.resource_ancestors.product_object_id".
- O mapeamento de "AuthenticationMechanism" mudou de "security_result.summary" para "extensions.auth.auth_details".
- O mapeamento de "CorrelationId" mudou de "network.session_id" para "additional.fields".
- O mapeamento de "ScopeDisplayName" mudou de "additional.fields" para "target.resource_ancestors.name".
- O mapeamento de "PipelineId" foi alterado de "additional.fields" para "target.resource.product_object_id".
- O mapeamento de "PipelineName" mudou de "additional.fields" para "target.resource.name".
- O mapeamento de "PipelineScope" mudou de "additional.fields" para "target.resource.attribute.labels".
- O mapeamento de "PipelineRevision" mudou de "additional.fields" para "target.resource.attribute.labels".
- O mapeamento de "ProjectId" mudou de "target.resource.resource.attribute.labels" para "target.resource_ancestors.product_object_id".
- O mapeamento de "Área" foi alterado de "additional.fields" para "target.application".
- O valor "MICROSOFT_AZURE" foi mapeado para "target.asset.attribute.cloud.environment".
- Quando "AuthenticationMechanism" tiver o valor "ServicePrincipal", defina "SERVICE_ACCOUNT_TYPE" como "principal.user.account_type". Caso contrário, defina "CLOUD_ACCOUNT_TYPE" como "principal.user.account_type".
- Mapeamos "Categoria" para "security_result.action_details".
- "ALLOW" ou "BLOCK" foram mapeados para "security_result.action" com base no campo "Details".
- "ActivityId" foi mapeado para "additional.fields".
2024-01-09
- Foram adicionados Grok e gsub para analisar os registros JSON não analisados.
- "rec.correlationId", "properties.currentHealthStatus", "properties.previousHealthStatus", "properties.type", "properties.cause", "properties.title", "properties.details", "properties.recommendationType", "properties.recommendationCategory", "properties.recommendationImpact", "properties.recommendationName", "properties.recommendationResourceLink", "properties.recommendationSchemaVersion", "properties.eventCategory", "properties.hierarchy", "properties.message", "properties.entity", "identity.claims.xms.tcdt", "identity.claims.aio", "identity.claims.appid", "identity.claims.appidacr", "identity.claims.aud", "identity.claims.exp", "identity.claims.iat", "identity.claims.idtyp", "identity.claims.iss", "identity.claims.uti", "identity.claims.rh", "identity.claims.ver", "identity.claims.nbf", "identity.authorization.evidence.roleAssignmentId", "identity.authorization.evidence.principalType", "identity.authorization.evidence.principalId", "identity.authorization.evidence.roleAssignmentScope", "identity.authorization.evidence.roleDefinitionId" para "security_result.detection_fields".
- "resultSignature.label", "rec.resultType", "Visibility", "Humidity", "Precipitation","MoonPhase", "Moonrise", "Moonset", "Pressure", "WindSpeed", "UVIndex", "DewPoint", "WindDirection", "Sunrise", "Sunset", "Temperature", "Icon", "Conditions" foram mapeados para "additional.fields".
- "level" foi mapeado para "security_result.severity".
- Mapeamos "appname" para "target.application".
- "category.details" foi associado a "security.result.category.details".
- "rec.resourceId" foi mapeado para "target.resource.id".
- "res.extensionResourceName" foi mapeado para "principal.hostname".
2023-11-23
- Adição de suporte a um novo padrão de registros JSON.
- "data.TimeGenerated" foi associado a "metadata.event_timestamp".
- Quando "_Internal_WorkspaceResourceId" está ausente, "topic" é mapeado para "target.resource.product_object_id".
- "data.Data.ConnectionId" foi mapeado para "additional.fields".
- "data.Data.ownerDetails" foi associado a "additional.fields".
- "data.Data.DeploymentResult" foi mapeado para "additional.fields".
- "data.Data.EnvironmentName" foi associado a "additional.fields".
- Mapeamos "data.Data.JobName" para "additional.fields".
- "data.Data.StageName" foi associado a "additional.fields".
- "data.Data.RunName" foi mapeado para "additional.fields".
- "data.Data.RetentionLeaseId" foi mapeado para "additional.fields".
- "data.Data.CheckSuiteId" foi mapeado para "additional.fields".
- "data.Data.CheckSuiteStatus" foi mapeado para "additional.fields".
- "data.Data.ApprovalRequest" foi associado a "additional.fields".
- "data.Data.ApprovalType" foi mapeado para "additional.fields".
- "subject" foi mapeado para "additional.fields".
- "data.ActorUserId" foi associado a "principal.user.userid".
- "data.ActorDisplayName" foi mapeado para "principal.user.user_display_name".
- "data.ActorCUID" foi associado a "principal.user.product_object_id".
- "data.ActorUPN" foi associado a "principal.user.email_addresses".
- "data.ScopeId" foi mapeado para "principal.asset_id".
- "data.CorrelationId" foi mapeado para "network.session_id".
- "data.UserAgent" foi associado a "network.http.user_agent".
- "data.ProjectId" foi mapeado para "target.resource.attribute.labels".
- Mapeamos "data.ScopeType" para "additional.fields".
- Mapeamos "data.ProjectName" para "target.resource.attribute.labels".
- "data.Details" foi associado a "metadata.description".
- Mapeamos "data.CategoryDisplayName" para "security_result.rule_name".
- Mapeamos "data.Area" para "additional.fields".
- Mapeamos "data.Id" para "metadata.product_log_id".
- Mapeamos "data.ActionId" para "metadata.product_event_type".
- "data.Timestamp" foi mapeado para "metadata.event_timestamp".
2022-06-28
- Parser recém-criado
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.