APIs de pesquisa assíncrona
A plataforma de pesquisa do Google Security Operations permite usar APIs assíncronas para consultas de longa duração que retornam grandes conjuntos de resultados de até 1 milhão de resultados. Essas APIs permitem iniciar pesquisas em fontes de dados, incluindo eventos do Modelo de dados unificado (UDM, na sigla em inglês), detecções, tabelas de dados e o gráfico de contexto de entidades (ECG, na sigla em inglês), sem bloquear o aplicativo. Ao executar uma consulta de pesquisa usando uma API de operação de longa duração (LRO), você recebe um ID de operação. É possível usar esse ID para monitorar o status 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 - Listar resultados:
chronicle.searchedResults.listno recursoSearchSession.
Verifique se o principal de 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.
Executar uma pesquisa usando APIs de LRO
Siga estas etapas para executar uma pesquisa usando as APIs de LRO:
Iniciar a pesquisa
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 requer os seguintes parâmetros de chave:
query: a string de consulta de pesquisa.time_range: o intervalo de tempo da pesquisa.dialect: especifica o dialeto do idioma comoYL2.result_limit: opcional. O número máximo de linhas a serem materializadas. O valor padrão é10000, e o valor máximo é1000000.
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
Pesquise 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 pesquisando até que o campo done na resposta GetOperation retorne true.
- Se a operação for bem-sucedida, o campo
metadata.stateretornaráSUCCEEDED, e o campo de resposta conterá o recursoSearchSessioncriado. - Se a operação falhar, o campo
doneretornarátrue, e o campo de erro conterá os detalhes da falha relacionados.
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 de chave:
done: quando definido comotrue, a operação é concluída.state: quando definido comoSUCCEEDED, a pesquisa foi concluída com sucesso.response.name: o nome do recursoSearchSession. 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 todas as operações de LRO das últimas 24 horas, adicione o filtro name: "operations/s-lro".
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/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 pula 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 é compatível com 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 umaListSearchedResultsResponseanterior usado para recuperar a próxima página.order_by: opcional. O campo é usado para classificar os resultados.UDM events (eventRecord): use caminhos no campoudm, por exemplo,udm.metadata.timestamp descouudm.principal.hostname asc. Nomes de colunas, incluindohostname,user,process nameeevent type, também são compatíveis.O valor padrão é
udm.metadata.event_timestamp.Entities / ECG (entityContextRecord): use caminhos no campoentity, por exemplo,graph.entity.ip asc.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-chavedetectionseguida pelo caminho, por exemplo,detection.id.Joins: 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 (junção UDM-tabela de dados):
%<table_alias>.<column_name>
Alias predefinidos, como
hostname,user,process nameeevent type, também são compatíveis. Para eles, use o formato$e1.hostname.at.- ECG (junção UDM-ECG): entidade:
skip: opcional. O número de resultados a serem pulados. Não use se estiver usandopage_token.
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 próxima página 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.