Raccogliere i log di controllo di Azure DevOps
Panoramica
Questo parser gestisce i log di controllo di Azure DevOps in formato JSON. Estrae i campi dalle strutture JSON nidificate e di primo livello, mappandoli a UDM. La logica condizionale basata su valori di campi specifici classifica gli eventi e arricchisce l'output con informazioni di sicurezza pertinenti. Il parser gestisce anche i messaggi non in formato JSON tentando di estrarre un payload JSON utilizzando i pattern grok.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Istanza Google SecOps
- Un'organizzazione Azure DevOps attiva
- Accesso con privilegi all'organizzazione Azure DevOps e ad Azure
Configurare i feed
Esistono due diversi punti di accesso per configurare i feed nella piattaforma Google SecOps:
- Impostazioni SIEM > Feed > Aggiungi nuovo
- Hub dei contenuti > Pacchetti di contenuti > Inizia
Come configurare il feed di controllo di Azure DevOps
- Fai clic sul pacchetto Azure Platform.
- Individua il tipo di log Azure DevOps audit e fai clic su Aggiungi nuovo feed.
Specifica i valori per i seguenti campi:
- Tipo di origine: Microsoft Azure Blob Storage V2.
- URI di Azure: l'URL dell'endpoint blob.
ENDPOINT_URL/BLOB_NAME
- Sostituisci quanto segue:
ENDPOINT_URL
: l'URL dell'endpoint blob (https://<storageaccountname>.blob.core.windows.net
)BLOB_NAME
: il nome del blob (ad esempio,insights-logs-<logname>
)
- Sostituisci quanto segue:
Opzioni di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze di importazione.
Età massima dei file: include i file modificati nell'ultimo numero di giorni. Il valore predefinito è 180 giorni.
Chiave condivisa: la chiave condivisa (una stringa casuale di 512 bit con codifica base64) utilizzata per accedere alle risorse Azure.
Opzioni avanzate
- Nome feed: un valore precompilato che identifica il feed.
- Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset.
- Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
Fai clic su Crea feed.
Per ulteriori informazioni sulla configurazione di più feed per diversi tipi di log all'interno di questa famiglia di prodotti, consulta Configurare i feed per prodotto.
Crea una chiave API per il feed webhook
Vai alla consoleGoogle Cloud > Credenziali.
Fai clic su Crea credenziali e poi seleziona Chiave API.
Limita l'accesso della chiave API all'API Google Security Operations.
Specifica l'URL dell'endpoint
- Nella tua applicazione client, specifica l'URL dell'endpoint HTTPS fornito nel feed webhook.
Attiva l'autenticazione specificando la chiave API e la chiave segreta come parte dell'intestazione personalizzata nel seguente formato:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
Consiglio: specifica la chiave API come intestazione anziché nell'URL. Se il client webhook non supporta le intestazioni personalizzate, puoi specificare la chiave API e la chiave segreta utilizzando parametri di ricerca nel seguente formato:
ENDPOINT_URL?key=API_KEY&secret=SECRET
Sostituisci quanto segue:
ENDPOINT_URL
: l'URL dell'endpoint del feed.API_KEY
: la chiave API per l'autenticazione a Google Security Operations.SECRET
: la chiave segreta che hai generato per autenticare il feed.
Configurare la funzionalità di controllo in Azure DevOps
- Accedi alla tua organizzazione (
https://dev.azure.com/{yourorganization}
). - Seleziona l'icona a forma di ingranaggio per Impostazioni dell'organizzazione.
- Seleziona Policy nella sezione Sicurezza.
- Attiva il pulsante Registra eventi di controllo.
Configura un argomento Event Grid in Azure
- Accedi al portale Azure.
- Cerca e accedi a Event Grid.
- Individua Argomenti in Eventi personalizzati.
- Fai clic su + Crea.
- Seleziona l'abbonamento e il gruppo di risorse. Fornisci un nome (ad esempio,
DevopsAuditLog
) e seleziona la regione. Fai clic su Rivedi e crea. - Accedi al nuovo argomento e copia l'URL dell'endpoint dell'argomento.
- Vai a Impostazioni > Chiavi di accesso e copia Chiave 1.
Configurare il flusso di log di Azure DevOps in Event Grid
- Accedi alla tua organizzazione (
https://dev.azure.com/{yourorganization}
). - Seleziona l'icona a forma di ingranaggio per Impostazioni dell'organizzazione.
- Seleziona Controlli.
- Vai alla scheda Stream e seleziona Nuovo stream > Event Grid.
- Inserisci l'endpoint dell'argomento e la chiave di accesso creati in Configurare un argomento Event Grid in Azure.
Configura un webhook in Azure DevOps per Google SecOps
- Nel portale Azure, cerca e accedi a Event Grid.
- Seleziona l'argomento creato in precedenza.
- Vai a Entità > Abbonamento agli eventi.
- Fai clic su + Event Subscription (Abbonamento all'evento).
- Fornisci un nome descrittivo (ad esempio, *
Google SecOps Integration
). - Seleziona Web Hook e fai clic su Configura un endpoint.
- Configura l'endpoint:
- Endpoint abbonato: inserisci l'URL dell'endpoint API Google SecOps.
- Nella sezione Intestazioni HTTP, aggiungi le seguenti intestazioni:
- Header 1:
- Chiave:
X-goog-api-key
- Valore: la chiave API che hai creato nella sezione Crea una chiave API per il feed webhook.
- Chiave:
- Header 2:
- Chiave:
X-Webhook-Access-Key
- Valore: la chiave segreta che hai generato nella sezione Configura un feed in Google SecOps per importare i log di Azure DevOps.
- Chiave:
- Header 1:
- Imposta l'intestazione Content-Type su
application/json
.
- Fai clic su Crea.
Tabella di mappatura UDM
Campo log | Mappatura UDM | Logic |
---|---|---|
ActivityId |
metadata.product_log_id |
Mappato direttamente dal campo Id nel log non elaborato quando il campo records non è presente o dal campo ActivityId all'interno dell'oggetto data quando records è presente. |
ActionId |
metadata.product_event_type |
Mappato direttamente dal campo ActionId all'interno dell'oggetto data . |
ActorCUID |
additional.fields |
Incluso come campo aggiuntivo con la chiave "Actor CUID". |
ActorDisplayName |
principal.user.user_display_name |
Mappato direttamente dal campo ActorDisplayName se non è "Servizio Azure DevOps". Se è "Azure DevOps Service", viene aggiunto come etichetta a principal.resource.attribute.labels . |
ActorUPN |
principal.user.email_addresses |
Mappato direttamente dal campo ActorUPN se corrisponde a un pattern di indirizzo email. |
ActorUserId |
principal.user.userid |
Mappato direttamente dal campo ActorUserId . |
Area |
target.application |
Utilizzato per creare il campo target.application anteponendo "DevOps " al valore Area . |
AuthenticationMechanism |
extensions.auth.auth_details , security_result.rule_id |
Analizzato per estrarre i dettagli di autenticazione e l'ID regola. I dettagli di autenticazione sono mappati a extensions.auth.auth_details . L'ID regola estratto è mappato a security_result.rule_id . |
CategoryDisplayName |
security_result.action_details |
Mappato direttamente a security_result.action_details . |
City |
principal.location.city |
Mappato direttamente dal campo City . |
Conditions |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Conditions". |
Country |
principal.location.country_or_region |
Mappato direttamente dal campo Country . |
Data.* |
Varie | I campi all'interno dell'oggetto Data vengono mappati su campi UDM diversi in base ai nomi e al contesto. Di seguito sono riportati alcuni esempi specifici. |
Data.AccessLevel |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "AccessLevel". |
Data.AgentId |
target.resource.product_object_id |
Mappato a target.resource.product_object_id se PipelineId e AuthorizationId non sono presenti. |
Data.AgentName |
target.resource.name |
Mappato a target.resource.name se PipelineName , NamespaceName e DisplayName non sono presenti. |
Data.AuthorizationId |
target.resource.product_object_id |
Mappato a target.resource.product_object_id se PipelineId non è presente. |
Data.CallerProcedure |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "CallerProcedure". |
Data.CheckSuiteId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "CheckSuiteId". |
Data.CheckSuiteStatus |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "CheckSuiteStatus". |
Data.ConnectionId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "ConnectionId". |
Data.ConnectionName |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "ConnectionName". |
Data.ConnectionType |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "ConnectionType". |
Data.DefinitionId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "DefinitionId". |
Data.DeploymentResult |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "DeploymentResult". |
Data.DisplayName |
target.resource.name |
Mappato a target.resource.name se PipelineName e NamespaceName non sono presenti. |
Data.EndpointIdList |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "EndpointIdList". |
Data.EnvironmentName |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "EnvironmentName". |
Data.Filter.continuationToken |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "continuation_token". |
Data.Filter.endTime |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "filter_end_time". |
Data.Filter.startTime |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "filter_start_time". |
Data.FinishTime |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "FinishTime". |
Data.GroupId |
target.group.product_object_id |
Mappato direttamente su target.group.product_object_id quando Data.Updates.0.GroupId non è presente. |
Data.GroupName |
target.group.group_display_name |
Mappato direttamente a target.group.group_display_name . |
Data.JobName |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "JobName". |
Data.MemberId |
target.user.userid |
Mappato direttamente su target.user.userid quando Data.Updates.0.MemberId non è presente. |
Data.MemberDisplayName |
target.user.user_display_name |
Mappato direttamente a target.user.user_display_name . |
Data.NamespaceId |
target.resource.product_object_id |
Mappato a target.resource.product_object_id se PipelineId , AuthorizationId e AgentId non sono presenti. |
Data.NamespaceName |
target.resource.name |
Mappato a target.resource.name se PipelineName non è presente. |
Data.ownerDetails |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "OwnerDetails". |
Data.OwnerId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "OwnerId". |
Data.PipelineId |
target.resource.product_object_id |
Mappato direttamente a target.resource.product_object_id . |
Data.PipelineName |
target.resource.name |
Mappato direttamente a target.resource.name . |
Data.PipelineRevision |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "PipelineRevision". |
Data.PipelineScope |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "PipelineScope". |
Data.PlanType |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "PlanType". |
Data.PreviousAccessLevel |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "PreviousAccessLevel". |
Data.PublisherName |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "PublisherName". |
Data.Reason |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Motivo". |
Data.ReleaseId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "ReleaseId". |
Data.ReleaseName |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "ReleaseName". |
Data.RequesterId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "RequesterId". |
Data.RetentionLeaseId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "RetentionLeaseId". |
Data.RetentionOwnerId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "RetentionOwnerId". |
Data.RunName |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "RunName". |
Data.Scopes |
target.resource.attribute.labels |
Aggiunti come etichette con la chiave "Ambito". |
Data.StageName |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "StageName". |
Data.StartTime |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "StartTime". |
Data.TargetUser |
target.user.userid |
Mappato direttamente a target.user.userid . |
Data.Timestamp |
metadata.event_timestamp |
Analizzato e mappato a metadata.event_timestamp . |
Data.TokenType |
target.resource.attribute.labels |
Aggiunto come etichetta con la chiave "TokenType". |
Data.Updates.0.GroupId |
target.group.product_object_id |
Mappato direttamente a target.group.product_object_id . |
Data.Updates.0.MemberId |
target.user.userid |
Mappato direttamente a target.user.userid . |
Data.ValidFrom |
target.resource.attribute.labels |
Aggiunta come etichetta con la chiave "ValidFrom". |
Data.ValidTo |
target.resource.attribute.labels |
Aggiunta come etichetta con la chiave "ValidTo". |
DewPoint |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "DewPoint". |
Details |
metadata.description |
Mappato direttamente a metadata.description . |
Humidity |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Umidità". |
Icon |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Icona". |
Id |
metadata.product_log_id |
Mappato direttamente a metadata.product_log_id . |
IpAddress |
principal.ip |
Mappato direttamente a principal.ip . |
MoonPhase |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "MoonPhase". |
Moonrise |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Alba lunare". |
Moonset |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Tramonto della luna". |
OperationName |
metadata.product_event_type |
Mappato direttamente a metadata.product_event_type . |
Precipitation |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Precipitazioni". |
Pressure |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Pressione". |
ProjectId |
target.resource_ancestors.product_object_id |
Utilizzato per compilare il campo product_object_id all'interno di target.resource_ancestors quando l'elemento principale è di tipo CLOUD_PROJECT . |
ProjectName |
target.resource_ancestors.name , target.resource.attribute.labels |
Utilizzato per compilare il campo name all'interno di target.resource_ancestors quando l'elemento principale è di tipo CLOUD_PROJECT . Aggiunto anche come etichetta a target.resource.attribute.labels con la chiave "ProjectName". |
RoleLocation |
target.location.name |
Mappato direttamente a target.location.name . |
ScopeDisplayName |
target.resource_ancestors.name |
Utilizzato per compilare il campo name all'interno di target.resource_ancestors quando l'elemento principale è di tipo CLOUD_ORGANIZATION . |
ScopeId |
target.resource_ancestors.product_object_id |
Utilizzato per compilare il campo product_object_id all'interno di target.resource_ancestors quando l'elemento principale è di tipo CLOUD_ORGANIZATION . |
ScopeType |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "ScopeType". |
Sunrise |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Sunrise". |
Sunset |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Tramonto". |
Temperature |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Temperatura". |
TenantId |
metadata.product_deployment_id , additional.fields |
Mappato direttamente a metadata.product_deployment_id . Aggiunto anche come campo aggiuntivo con la chiave "TenantId". |
TimeGenerated |
metadata.event_timestamp |
Analizzato e mappato a metadata.event_timestamp . |
UserAgent |
network.http.user_agent , network.http.parsed_user_agent |
Mappato direttamente a network.http.user_agent . Inoltre, è stato analizzato e mappato a network.http.parsed_user_agent . |
UVIndex |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "UVIndex". |
Visibility |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "Visibilità". |
WindDirection |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "WindDirection". |
WindSpeed |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "WindSpeed". |
_Internal_WorkspaceResourceId |
additional.fields |
Aggiunto come campo aggiuntivo con la chiave "workspace_resource_id". |
N/A | metadata.event_type |
Determinato dalla logica in base a OperationName e ad altri campi. Se non viene trovata una corrispondenza con un tipo di evento specifico, il valore predefinito è "GENERIC_EVENT". I valori possibili includono "STATUS_SHUTDOWN", "RESOURCE_CREATION", "STATUS_UPDATE", "USER_RESOURCE_DELETION", "RESOURCE_READ", "RESOURCE_WRITTEN", "RESOURCE_DELETION" e "GROUP_MODIFICATION". |
N/A | metadata.vendor_name |
Imposta su "Microsoft". |
N/A | metadata.product_name |
Imposta "Azure DevOps". |
N/A | metadata.log_type |
Imposta il valore su "AZURE_DEVOPS". |
N/A | principal.user.account_type |
Imposta "SERVICE_ACCOUNT_TYPE" se AuthenticationMechanism contiene "ServicePrincipal", altrimenti imposta "CLOUD_ACCOUNT_TYPE". |
N/A | target.asset.attribute.cloud.environment |
Imposta su MICROSOFT_AZURE . |
N/A | security_result.action |
Imposta "ALLOW" per le operazioni riuscite (Riuscita, Creata, Modificata, Eseguita, Aggiornata, Rimossa) e "BLOCK" per le operazioni non riuscite (Non riuscita, Timeout). |
N/A | extensions.auth.mechanism |
Imposta su "USERNAME_PASSWORD" se summary è "UserAuthToken". |
N/A | target.resource.resource_type |
Impostato su "SETTING" se è presente pipeline_id , "CREDENTIAL" se è presente authorization_id , "DEVICE" se è presente agent_id o "DATABASE" se è presente namespace_id . In caso contrario, in alcuni casi viene impostato su "STORAGE_BUCKET" in base a operationName . |
N/A | target.resource.resource_subtype |
Impostato su "Pipeline" se è presente pipeline_id , "Token" se è presente authorization_id , "Agente" se è presente agent_id o "Spazio dei nomi" se è presente namespace_id . |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.