APIs de pesquisa assíncrona

Compatível com:

A plataforma de pesquisa no Google Security Operations permite usar APIs assíncronas para consultas de longa duração que retornam grandes conjuntos de até 1 milhão de resultados. Com essas APIs, é possível iniciar pesquisas em fontes de dados, incluindo eventos do Modelo de Dados Unificado (UDM), detecções, tabelas de dados e Gráfico de Contexto de Entidade (ECG), sem bloquear o aplicativo. Ao executar uma consulta de pesquisa usando uma API de operação de longa duração (LRO, na sigla em inglês), você recebe um ID de operação. Use esse ID para monitorar o status de funcionamento da operação e receber os resultados página por página.

Pré-requisitos

Para usar APIs de operação de longa duração, o principal de chamada precisa de permissões específicas do Identity and Access Management (IAM).

Para realizar as ações a seguir, você precisa ter as permissões do IAM correspondentes:

  • Iniciar uma pesquisa: chronicle.searchSessions.search
  • Resultados da lista: chronicle.searchedResults.list no recurso SearchSession.

Verifique se o principal que faz a chamada tem um papel que concede essas permissões, por exemplo, o papel de Leitor da API Chronicle, Editor da API Chronicle ou Administrador da API Chronicle.

Fazer uma pesquisa usando APIs LRO

Siga estas etapas para fazer uma pesquisa usando as APIs LRO:

  1. Inicie a pesquisa.
  2. Monitore a operação.
  3. Busque os resultados.

Envie uma solicitação POST para o método personalizado search na instância do Google SecOps.

  • Endpoint: POST /{$api_version}/projects/{project}/locations/{location}/instances/{instance}:search
  • Método:Search
  • Corpo da solicitação: SearchRequest

O exemplo a seguir mostra um objeto SearchRequest:

{
  "parent": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID",
  "query": "metadata.event_type = \"USER_LOGIN\"",
  "time_range": {},
  "start_time": "2026-03-16T14:40:13Z",
  "endTime": "2026-03-16T15:40:13Z",
  "dialect": "YL2"
}

A solicitação exige os seguintes parâmetros principais:

  • query: a string de consulta de pesquisa.
  • time_range: o intervalo de tempo da pesquisa.
  • dialect: especifica o dialeto do idioma como YL2.
    • O dialeto SQL não é compatível com a recuperação assíncrona de resultados de LRO usando ListSearchedResults (searchedResults.list).
    • O dialeto RAW_LOG está em pré-lançamento e pode retornar um erro 501 UNIMPLEMENTED se não estiver ativado para sua instância.
  • result_limit: opcional. O número máximo de linhas a serem materializadas. O valor padrão é 10000, e o valor máximo é 1000000.
  • simulated_data_visibility (ou simulatedDataVisibility em JSON): opcional. Controla se os resultados da pesquisa incluem eventos simulados. Defina como SIMULATED_DATA_INCLUDED para incluir eventos simulados nos resultados da pesquisa. Se não for especificado, o padrão será SIMULATED_DATA_EXCLUDED, que exclui eventos simulados.

Essa chamada retorna um objeto google.longrunning.Operation.

O exemplo a seguir mostra uma resposta de operação bem-sucedida:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata)",
    "state": "RUNNING",
    "start_time": "2026-03-13T10:00:00Z"
  }
}

O campo state: RUNNING indica que a pesquisa está em andamento.

Monitorar a operação

Consulte o status da LRO usando o método GetOperation padrão do serviço google.longrunning.Operations. Use o valor name da resposta anterior.

  • Endpoint: GET /{$api_version}/projects/{project}/locations/{location}/instances/{instance}/operations/{operationID}

Continue sondando até que o campo done na resposta GetOperation retorne true.

  • Se a operação for bem-sucedida, o campo metadata.state vai retornar SUCCEEDED, e o campo de resposta vai conter o recurso SearchSession criado.
  • Se a operação falhar, o campo done vai retornar true, e o campo de erro vai conter os detalhes da falha relacionada.

O exemplo a seguir mostra uma resposta GetOperation bem-sucedida:

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation) Metadata",
    "state": "SUCCEEDED",
    "startTime": "2026-03-16T15:42:11.037506921Z"
  },
  "endTime": "2026-03-16T15:42:17.504730842Z",
  "expireTime": "2026-03-17T15:42:17.504731874Z",
  "progress": 100,
  "done": true,
  "response": {
    "@type": "[type.googleapis.com/google.cloud.chronicle.v1main.SearchSession](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchSession)",
    "name": "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/SEARCH_SESSION_ID",
    "query": "metadata.event_type = \"USER_LOGIN\"",
    "timeRange": {},
    "startTime": "2026-03-16T14:40:13Z",
    "endTime": "2026-03-16T15:40:13Z",
    "dialect": "YL2",
    "metadata": {
      "operationId": "OPERATION_ID",
      "startTime": "2026-03-16T15:42:11.037506921Z",
      "endTime": "2026-03-16T15:42:17.504730842Z",
      "expireTime": "2026-03-17T15:42:17.504731874Z",
      "resultRowCount": 10000,
      "moreDataAvailable": true
    }
  }
}

O formato do nome do recurso SearchSession é projects/{project}/locations/{location}/instances/{instance}/searchSessions/{search_session}.

A resposta bem-sucedida contém os seguintes campos principais:

  • done: quando definido como true, a operação é concluída.
  • state: quando definido como SUCCEEDED, a pesquisa foi concluída com sucesso.
  • response.name: o nome do recurso do SearchSession. Use esse valor como a propriedade pai na próxima etapa.
  • response.metadata.resultRowCount: indica o número total de linhas encontradas.
  • response.metadata.moreDataAvailable: indica que o número de resultados disponíveis excede o limite de retorno definido.

Listar operações de LRO

Para listar operações de LRO, use o método ListOperations do serviço google.longrunning.Operations. Use o valor name da resposta anterior.

  • Endpoint: GET /{$api_version}/projects/{project}/locations/{location}/instances/{instance}

Para listar as operações de LRO de pesquisa das últimas 24 horas, especifique o filtro name:"operations/s-lro-", incluindo o hífen final.

O exemplo a seguir mostra uma solicitação ListOperations bem-sucedida:

google.longrunning.ListOperationsRequest {
  name: "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID"
  filter: "name:\"operations/s-lro-\""
  page_size: 100
}

O exemplo a seguir mostra uma resposta ListOperations bem-sucedida:

{
  operations {
    name: "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID_1"
    metadata {
      type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperation) Metadata"
      value: "\b\002\022\f\b\367\304\363\316\006\020\317\352\232\240\003\032\f\b\237\307\363\316\006\020\326\334\351\311\001\"\f\b\237\352\370\316\006\020\352\342\351\311\001(d"
    }
    done: true
    response {
      type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchSession](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchSession)"
      value: "\n\213\001projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/OPERATION_ID_11022\bip != \"\"\032\020\n\006\b\251\255\334\316\006\022\006\b\351\345\336\316\006\0012\\\n*OPERATION_ID_1\022\f\b\367\304\363\316\006\020\317\352\232\240\003\032\f\b\237\307\363\316\006\020\326\334\351\311\001\"\f\b\237\352\370\316\006\020\352\342\351\311\001(\300\204=0\001"
    }
  }
  operations {
    name: "projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/operations/OPERATION_ID_2"
    metadata {
      type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchOperationMetadata)"
      value: "\b\002\022\f\b\200\305\363\316\006\020\324\262\367\225\001\032\v\b\241\307\363\316\006\020\321\261\333?\"\v\b\241\352\370\316\006\020\317\264\333?(d"
    }
    done: true
    response {
      type_url: "[type.googleapis.com/google.cloud.chronicle.v1main.SearchSession](https://type.googleapis.com/google.cloud.chronicle.v1main.SearchSession)"
      value: "\n\213\001projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/OPERATION_ID_2\022\bip != \"\"\0321020\n\006\b\251\255\334\316\006\022\006\b\351\345\336\316\006\0012Z\n*OPERATION_ID_2\022\f\b\200\305\363\316\006\0201324\262\367\225\001\032\v\b\241\307\363\316\006\020\321\261\333?\"\v\b\241\352\370\316\006\020\317\264\333?(\300\204=0\001"
    }
  }
}

Buscar os resultados

Depois que o estado da operação retornar SUCCEEDED, use o método ListSearchedResults() para recuperar os resultados da pesquisa.

  • Endpoint: GET /{$api_version}/{parent=projects/*/locations/*/instances/*/searchSessions/*}/searchedResults
  • Método:ListSearchedResults
  • Parâmetros de solicitação: ListSearchedResultsRequest

O exemplo a seguir mostra um ListSearchedResultsRequest que recupera três resultados e ignora os cinco primeiros:

// GET
/v1alpha/projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/SEARCH_SESSION_ID/searchedResults?page_size=3&skip=5

A solicitação aceita os seguintes parâmetros de consulta:

  • page_size: o número máximo de resultados a serem retornados por página. O valor padrão é 100, e o valor máximo é 10.000.
  • page_token: o token de um ListSearchedResultsResponse anterior usado para recuperar a próxima página.
  • order_by (ou orderBy em JSON): opcional. O campo usado para ordenar os resultados. Quando você omite order_by, os resultados do evento de UDM são classificados por udm.metadata.event_timestamp em ordem decrescente por padrão, retornando os eventos mais recentes primeiro. Quando você especifica um caminho de campo em order_by sem um sufixo de direção, como udm.principal.hostname, os resultados são classificados em ordem crescente por padrão. Não anexe asc, porque o sufixo asc não é compatível e retorna um erro 400 INVALID_ARGUMENT. Para classificar os resultados em ordem decrescente, adicione o sufixo desc ao caminho do campo, como udm.metadata.event_timestamp desc. Não é possível classificar várias colunas.

    • UDM events (eventRecord): use caminhos totalmente qualificados no campo udm, como udm.metadata.event_timestamp desc ou udm.principal.hostname. Nomes de colunas como hostname, user, process name e event type também são aceitos.

      A ordem de classificação padrão é udm.metadata.event_timestamp em ordem decrescente, que retorna os eventos mais recentes primeiro.

    • Entities / ECG (entityContextRecord): use caminhos no campo entity, como graph.entity.ip ou graph.entity.ip desc.

    • data tables (dataTableRecord): use o formato %<table_alias>.<column_name>. Por exemplo, %dt.user desc.

      O valor padrão é a primeira coluna da tabela de dados.

    • Detections (DetectionRecord): use a palavra-chave detection seguida pelo caminho, por exemplo, detection.id.

    • Mesclagens: para eventos e entidades, use a variável de marcador de posição que os define. Para todas as outras fontes, o formato permanece o mesmo.

      Exemplo:

      • ECG (junção UDM-ECG): entidade: $e1.graph.entity.hostname
      • UDM (todas as junções com UDM): $e1.principal.ip
      • Tabela de dados (mesclagem de tabela de dados do UDM): %<table_alias>.<column_name>

      Também há suporte para aliases predefinidos, como hostname, user, process name e event type. Para isso, use o formato $e1.hostname.at.

  • skip: opcional. O número de resultados a serem pulados. Não use esse parâmetro com page_token.

    • A classificação padrão (udm.metadata.event_timestamp) não é exclusiva em eventos que compartilham o mesmo carimbo de data/hora. Além disso, a ordem de classificação dos resultados da pesquisa é definida na primeira chamada ListSearchedResults (searchedResults.list).
    • Ao paginar com skip, especialmente em solicitações paralelas, especifique um campo de classificação exclusivo, como udm.metadata.id, no parâmetro order_by. Como alternativa, busque a primeira página antes de enviar solicitações skip paralelas para que a ordem de classificação já esteja definida.

O exemplo a seguir mostra uma resposta ListSearchedResultsResponse bem-sucedida:

{
"searchedResults": [
{
"name":
"projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/searchSessions/SEARCH_SESSION_ID/searchedResults/
RESULT_ID",
"resultRow": {
"eventRecord": {
"event": {
"name":
"projects/PROJECT_NUMBER/locations/LOCATION/instances/INSTANCE_ID/events/EVENT_ID",
"udm": {
"metadata": {
"eventTimestamp": "2026-03-16T14:45:18Z",
"eventType": "USER_LOGIN",
"vendorName": "Microsoft",
"productName": "Azure AD"
}
},
//... other UDM fields
}
//... other UDM fields
"eventLogToken":
"EVENT_LOG_TOKEN"
}
},
{ }
},
{
"name": "projects/PROJECT_NUMBER/locations/
LOCATION/instances/INSTANCE_ID</span>
/searchSessions/SEARCH_SESSION_ID/searchedResults/RESULT_ID", "resultRow": {
"eventRecord": {
//... Similar UDM event structure...
}
}
},
{
""name": "projects/PROJECT_NUMBER/locations/
LOCATION/instances/INSTANCE_ID</span>
/searchSessions/SEARCH_SESSION_ID/searchedResults/RESULT_ID", "resultRow": {
"eventRecord": {
//... Similar UDM event structure...
}
}
}
],
"totalSize": 10000,
"columnNames": [],
"columnSchema": {},
"nextPageToken": "CAKYASAB"
}

Para buscar a página seguinte de resultados, use o valor nextPageToken retornado no parâmetro de consulta page_token da próxima solicitação ListSearchedResults. O campo resultRow contém os dados reais.

Continue chamando ListSearchedResults com o valor next_page_token de cada resposta. Quando next_page_token retornar vazio, todos os resultados terão sido recuperados.

A seguir

Para mais informações sobre métodos, campos de solicitação e resposta e tipos, consulte a seguinte documentação de referência da API:

Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.