Coletar registros de auditoria do Azure DevOps
Visão geral
Esse analisador processa registros de auditoria do Azure DevOps no formato JSON. Ele extrai campos de estruturas JSON aninhadas e de nível superior, mapeando-os 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ê atende aos seguintes pré-requisitos:
- Instância do Google SecOps
- Uma organização ativa do Azure DevOps
- Acesso privilegiado à organização do Azure DevOps e ao Azure
Configurar feeds
Há dois pontos de entrada diferentes para configurar feeds na plataforma do Google SecOps:
- Configurações do SIEM > Feeds > Adicionar novo
- Central de conteúdo > Pacotes de conteúdo > Começar
Como configurar o feed de auditoria do Azure DevOps
- Clique no pacote Plataforma do Azure.
- Localize o tipo de registro Auditoria do Azure DevOps e clique em Adicionar novo feed.
Especifique valores para os seguintes campos:
- Tipo de origem: Armazenamento de blobs do Microsoft Azure V2.
- URI do Azure: o URL do endpoint do blob.
ENDPOINT_URL/BLOB_NAME
- Substitua:
ENDPOINT_URL
: o URL do endpoint do blob (https://<storageaccountname>.blob.core.windows.net
)BLOB_NAME
: o nome do blob (por exemplo,insights-logs-<logname>
)
- Substitua:
Opções de exclusão de origem: selecione a opção de exclusão de acordo com suas preferências de ingestão.
Idade máxima do arquivo: inclui arquivos modificados no último número de dias. O padrão é de 180 dias.
Chave compartilhada: a chave compartilhada (uma string aleatória de 512 bits em codificação base64) usada para acessar recursos do Azure.
Opções avançadas
- Nome do feed: um valor pré-preenchido que identifica o feed.
- Namespace do recurso: o namespace do recurso.
- Rótulos de ingestão: o rótulo aplicado aos eventos deste feed.
Clique em Criar feed.
Para mais informações sobre como configurar vários feeds para diferentes tipos de registros nessa família de produtos, consulte Configurar feeds por produto.
Criar uma chave de API para o feed de webhook
Acesse console doGoogle Cloud > Credenciais.
Clique em Criar credenciais e, em seguida, selecione Chave de API.
Restrinja o acesso da chave de API à API Google Security Operations.
Especifique o URL do endpoint
- No aplicativo cliente, especifique o URL do endpoint HTTPS fornecido no feed do 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 no URL. Se o cliente de webhook não aceitar 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 autenticar 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 para Configurações da organização.
- Selecione Políticas em Segurança.
- Mude 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. Forneça 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 registros do Azure DevOps para o Event Grid
- Faça login na sua organização (
https://dev.azure.com/{yourorganization}
). - Selecione o ícone de engrenagem para 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 Event Grid.
- Selecione o Tópico criado anteriormente.
- Acesse Entidades > Assinatura de evento.
- Clique em + Assinatura de evento.
- Forneça um nome descritivo (por exemplo, *
Google SecOps Integration
). - Selecione Web Hook e clique em Configurar um endpoint.
- Configure o endpoint:
- Endpoint do assinante: insira o URL do endpoint de API Google SecOps.
- Na seção Cabeçalhos HTTP, adicione os seguintes cabeçalhos:
- Header 1:
- Chave:
X-goog-api-key
- Valor: a chave de API que você criou na seção Criar uma chave de API para o feed de webhook.
- Chave:
- Header 2:
- Chave:
X-Webhook-Access-Key
- Valor: a chave secreta gerada na seção Configurar um feed no Google SecOps para ingerir os registros do Azure DevOps.
- Chave:
- Header 1:
- 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 adicional com a chave "Actor CUID". |
ActorDisplayName |
principal.user.user_display_name |
Mapeado diretamente do campo ActorDisplayName se não for "Serviço do Azure DevOps". Se for "Serviço do Azure DevOps", ele será adicionado como um rótulo a principal.resource.attribute.labels . |
ActorUPN |
principal.user.email_addresses |
Mapeado diretamente do campo ActorUPN se 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 criar o campo target.application adicionando "DevOps " antes do valor Area . |
AuthenticationMechanism |
extensions.auth.auth_details , security_result.rule_id |
Analisado para extrair detalhes de autenticação e ID da regra. Os detalhes de autenticação são mapeados para extensions.auth.auth_details . O ID da regra extraída é 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 da UDM com base nos nomes e no contexto deles. Confira exemplos específicos abaixo. |
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 extra com a chave "CallerProcedure". |
Data.CheckSuiteId |
additional.fields |
Adicionado como um campo extra com a chave "CheckSuiteId". |
Data.CheckSuiteStatus |
additional.fields |
Adicionado como um campo extra 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 extra 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 extra com a chave "OwnerDetails". |
Data.OwnerId |
additional.fields |
Adicionado como um campo extra 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 extra 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 |
Adicionadas como rótulos com a chave "Scope". |
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 extra com a chave "Humidity". |
Icon |
additional.fields |
Adicionado como um campo extra com a chave "Icon". |
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 "Pressure". |
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 extra com a chave "Temperatura". |
TenantId |
metadata.product_deployment_id , additional.fields |
Mapeado diretamente para metadata.product_deployment_id . Também adicionado como um campo extra 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 extra com a chave "UVIndex". |
Visibility |
additional.fields |
Adicionado como um campo extra com a chave "Visibility". |
WindDirection |
additional.fields |
Adicionado como um campo extra com a chave "WindDirection". |
WindSpeed |
additional.fields |
Adicionado como um campo extra com a chave "WindSpeed". |
_Internal_WorkspaceResourceId |
additional.fields |
Adicionado como um campo extra com a chave "workspace_resource_id". |
N/A | metadata.event_type |
Determinado por uma lógica baseada no OperationName e em outros campos. O padrão é "GENERIC_EVENT" se nenhum tipo de evento específico for correspondente. 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 |
Definido como "ALLOW" para operações bem-sucedidas (Succeeded, Created, Modified, executed, updated, removed) e "BLOCK" para operações com falha (Failed, TimedOut). |
N/A | extensions.auth.mechanism |
Definido como "USERNAME_PASSWORD" se summary for "UserAuthToken". |
N/A | target.resource.resource_type |
Definido 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, será definido como "STORAGE_BUCKET" em alguns casos com base em operationName . |
N/A | target.resource.resource_subtype |
Definido como "Pipeline" se pipeline_id estiver presente, "Token" se authorization_id estiver presente, "Agent" se agent_id estiver presente ou "Namespace" se namespace_id estiver presente. |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.