Raccogliere gli audit log di Azure DevOps

Supportato in:

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
  • Hub dei contenuti > Pacchetti di contenuti

Configurare i feed da Impostazioni SIEM > Feed

Per configurare più feed per diversi tipi di log all'interno di questa famiglia di prodotti, consulta Configurare i feed per prodotto.

Per configurare un singolo feed:

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su Aggiungi nuovo feed.
  3. Nella pagina successiva, fai clic su Configura un singolo feed.
  4. Nel campo Nome feed, inserisci un nome per il feed (ad esempio, Azure Devops Logs).
  5. Seleziona Webhook come Tipo di origine.
  6. Seleziona Azure Devops Audit come Tipo di log.
  7. Fai clic su Avanti.
  8. (Facoltativo) Specifica i valori per i seguenti parametri di input:
    • Delimitatore di suddivisione: il delimitatore utilizzato per separare le righe di log, ad esempio \n.
    • Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset.
    • Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
  9. Fai clic su Avanti.
  10. Controlla la configurazione del feed nella schermata Finalizza e poi fai clic su Invia.
  11. Fai clic su Genera chiave segreta per generare una chiave segreta per autenticare questo feed.
  12. Copia e memorizza la chiave segreta. Non puoi visualizzare di nuovo questa chiave segreta. Se necessario, puoi rigenerare una nuova chiave segreta, ma questa azione rende obsoleta la chiave segreta precedente.
  13. Nella scheda Dettagli, copia l'URL dell'endpoint del feed dal campo Informazioni sull'endpoint. Devi specificare questo URL dell'endpoint nell'applicazione client.
  14. Fai clic su Fine.

Configurare i feed dall'hub dei contenuti

Specifica i valori per i seguenti campi:

  • Delimitatore di suddivisione: il delimitatore utilizzato per separare le righe di log, ad esempio \n.

Opzioni avanzate

  • Nome feed: un valore precompilato che identifica il feed.
  • Tipo di origine: metodo utilizzato per raccogliere i log in Google SecOps.
  • 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 Avanti.
  • Controlla la configurazione del feed nella schermata Finalizza e poi fai clic su Invia.
  • Fai clic su Genera chiave segreta per generare una chiave segreta per autenticare questo feed.

Crea una chiave API per il feed webhook

  1. Vai alla console Google Cloud > Credenziali.

    Vai a credenziali

  2. Fai clic su Crea credenziali e poi seleziona Chiave API.

  3. Limita l'accesso della chiave API all'API Google Security Operations.

Specifica l'URL dell'endpoint

  1. Nella tua applicazione client, specifica l'URL dell'endpoint HTTPS fornito nel feed webhook.
  2. 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

  1. Accedi alla tua organizzazione (https://dev.azure.com/{yourorganization}).
  2. Seleziona l'icona a forma di ingranaggio per Impostazioni dell'organizzazione.
  3. Seleziona Policy nella sezione Sicurezza.
  4. Imposta il pulsante Registra eventi di controllo su ON.

Configura un argomento Event Grid in Azure

  1. Accedi al portale Azure.
  2. Cerca e accedi a Event Grid.
  3. Individua Argomenti in Eventi personalizzati.
  4. Fai clic su + Crea.
  5. Seleziona l'abbonamento e il gruppo di risorse. Fornisci un nome (ad esempio, DevopsAuditLog) e seleziona la regione. Fai clic su Rivedi e crea.
  6. Accedi al nuovo argomento e copia l'URL dell'endpoint dell'argomento.
  7. Vai a Impostazioni > Chiavi di accesso e copia Chiave 1.

Configurare il flusso di log di Azure DevOps in Event Grid

  1. Accedi alla tua organizzazione (https://dev.azure.com/{yourorganization}).
  2. Seleziona l'icona a forma di ingranaggio per Impostazioni dell'organizzazione.
  3. Seleziona Controlli.
  4. Vai alla scheda Stream e seleziona Nuovo stream > Event Grid.
  5. 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

  1. Nel portale Azure, cerca e accedi a Event Grid.
  2. Seleziona l'argomento creato in precedenza.
  3. Vai a Entità > Abbonamento agli eventi.
  4. Fai clic su + Event Subscription (Abbonamento all'evento).
  5. Fornisci un nome descrittivo (ad esempio, *Google SecOps Integration).
  6. Seleziona Web Hook e fai clic su Configura un endpoint.
  7. Configura l'endpoint:
    1. Endpoint abbonato: inserisci l'URL dell'endpoint API Google SecOps.
    2. Nella sezione Intestazioni HTTP, aggiungi le seguenti intestazioni:
    3. Imposta l'intestazione Content-Type su application/json.
  8. 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 a campi UDM diversi in base ai loro 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 della luna".
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.