Coletar registros de autenticação do Duo
Este documento explica como ingerir registros de autenticação do Duo no Google Security Operations. O analisador extrai os registros de mensagens formatadas em JSON. Ele transforma os dados de registro brutos no modelo de dados unificado (UDM), mapeando campos como usuário, dispositivo, aplicativo, local e detalhes de autenticação, além de processar vários fatores e resultados de autenticação para categorizar eventos de segurança. O analisador também realiza limpeza de dados, conversão de tipos e tratamento de erros para garantir a qualidade e a consistência dos dados.
Escolha entre dois métodos de coleta:
- Opção 1: ingestão direta usando a API de terceiros
- Opção 2: coletar registros usando a função do Cloud Run e o Google Cloud Storage
Antes de começar
Verifique se você atende os seguintes pré-requisitos:
- Uma instância do Google SecOps
- Acesso privilegiado ao painel de administração do Duo (a função de proprietário é necessária para criar aplicativos da API Admin)
- Acesso privilegiado ao GCP se você estiver usando a opção 2
Opção 1: ingerir registros de autenticação do Duo usando a API de terceiros
Coletar os pré-requisitos do Duo (credenciais da API)
- Faça login no painel de administração do Duo como administrador com a função de Proprietário, Administrador ou Gerente de aplicativos.
- Acesse Aplicativos > Catálogo de aplicativos.
- Localize a entrada da API Admin no catálogo.
- Clique em + Adicionar para criar o aplicativo.
- Copie e salve em um local seguro os seguintes detalhes:
- Chave de integração
- Chave secreta
- Nome do host da API (por exemplo,
api-XXXXXXXX.duosecurity.com)
- Acesse a seção Permissões.
- Desmarque todas as opções de permissão, exceto Conceder leitura de registros.
- Clique em Salvar alterações.
Configurar um feed no Google SecOps para ingerir registros de autenticação do Duo
- Acesse Configurações do SIEM > Feeds.
- Clique em + Adicionar novo feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
Duo Authentication Logs). - Selecione API de terceiros como o Tipo de fonte.
- Selecione Autenticação do Duo como o Tipo de registro.
- Clique em Próxima.
- Especifique valores para os seguintes parâmetros de entrada:
- Nome de usuário: insira a chave de integração do Duo.
- Secret: insira a chave secreta do Duo.
- Nome do host da API: digite o nome do host da API (por exemplo,
api-XXXXXXXX.duosecurity.com). - Namespace do recurso: opcional. O namespace do recurso.
- Rótulos de ingestão: opcional. O rótulo a ser aplicado aos eventos deste feed.
- Clique em Próxima.
- Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Opção 2: ingerir registros de autenticação do Duo usando o Google Cloud Storage
Coletar credenciais da API Duo Admin
- Faça login no painel de administração do Duo.
- Acesse Aplicativos > Catálogo de aplicativos.
- Localize a API Admin no catálogo de aplicativos.
- Clique em + Adicionar para adicionar o aplicativo da API Admin.
- Copie e salve os seguintes valores:
- Chave de integração (ikey)
- Chave secreta (skey)
- Nome do host da API (por exemplo,
api-XXXXXXXX.duosecurity.com)
- Em Permissões, ative Conceder leitura de registros.
- Clique em Salvar alterações.
Criar um bucket do Google Cloud Storage
- Acesse o Console do Google Cloud.
- Selecione seu projeto ou crie um novo.
- No menu de navegação, acesse Cloud Storage > Buckets.
- Clique em Criar bucket.
Informe os seguintes detalhes de configuração:
Configuração Valor Nomeie seu bucket Insira um nome exclusivo globalmente, por exemplo, duo-auth-logs.Tipo de local Escolha com base nas suas necessidades (região, birregional, multirregional) Local Selecione o local (por exemplo, us-central1).Classe de armazenamento Padrão (recomendado para registros acessados com frequência) Controle de acesso Uniforme (recomendado) Ferramentas de proteção Opcional: ativar o controle de versões de objetos ou a política de retenção Clique em Criar.
Criar uma conta de serviço para a função do Cloud Run
A função do Cloud Run precisa de uma conta de serviço com permissões para gravar no bucket do GCS.
Criar conta de serviço
- No Console do GCP, acesse IAM e administrador > Contas de serviço.
- Clique em Criar conta de serviço.
- Informe os seguintes detalhes de configuração:
- Nome da conta de serviço: insira
duo-auth-collector-sa. - Descrição da conta de serviço: insira
Service account for Cloud Run function to collect Duo authentication logs.
- Nome da conta de serviço: insira
- Clique em Criar e continuar.
- Na seção Conceder acesso a essa conta de serviço ao projeto, adicione os seguintes papéis:
- Clique em Selecionar papel.
- Pesquise e selecione Administrador de objetos do Storage.
- Clique em + Adicionar outro papel.
- Pesquise e selecione Invocador do Cloud Run.
- Clique em + Adicionar outro papel.
- Pesquise e selecione Invocador do Cloud Functions.
- Clique em Continuar.
- Clique em Concluído.
Esses papéis são necessários para:
- Administrador de objetos do Storage: grava registros em um bucket do GCS e gerencia arquivos de estado.
- Invocador do Cloud Run: permite que o Pub/Sub invoque a função
- Invocador do Cloud Functions: permite a invocação de funções
Conceder permissões do IAM no bucket do GCS
Conceda permissões de gravação à conta de serviço no bucket do GCS:
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket.
- Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar principais: insira o e-mail da conta de serviço (por exemplo,
duo-auth-collector-sa@PROJECT_ID.iam.gserviceaccount.com). - Atribuir papéis: selecione Administrador de objetos do Storage.
- Adicionar principais: insira o e-mail da conta de serviço (por exemplo,
- Clique em Salvar.
Criar tópico Pub/Sub
Crie um tópico do Pub/Sub em que o Cloud Scheduler vai publicar e a função do Cloud Run vai se inscrever.
- No Console do GCP, acesse Pub/Sub > Tópicos.
- Selecione Criar tópico.
- Informe os seguintes detalhes de configuração:
- ID do tópico: insira
duo-auth-trigger. - Não altere as outras configurações.
- ID do tópico: insira
- Clique em Criar.
Criar uma função do Cloud Run para coletar registros
A função do Cloud Run é acionada por mensagens do Pub/Sub do Cloud Scheduler para buscar registros da API Duo Admin e gravá-los no GCS.
- No console do GCP, acesse o Cloud Run.
- Clique em Criar serviço.
- Selecione Função (use um editor in-line para criar uma função).
Na seção Configurar, forneça os seguintes detalhes de configuração:
Configuração Valor Nome do serviço duo-auth-collectorRegião Selecione a região que corresponde ao seu bucket do GCS (por exemplo, us-central1).Ambiente de execução Selecione Python 3.12 ou uma versão mais recente. Na seção Acionador (opcional):
- Clique em + Adicionar gatilho.
- Selecione Cloud Pub/Sub.
- Em Selecionar um tópico do Cloud Pub/Sub, escolha o tópico
duo-auth-trigger. - Clique em Salvar.
Na seção Autenticação:
- Selecione Exigir autenticação.
- Confira o Identity and Access Management (IAM).
Role a tela para baixo e abra Contêineres, rede, segurança.
Acesse a guia Segurança:
- Conta de serviço: selecione a conta de serviço
duo-auth-collector-sa.
- Conta de serviço: selecione a conta de serviço
Acesse a guia Contêineres:
- Clique em Variáveis e secrets.
- Clique em + Adicionar variável para cada variável de ambiente:
Nome da variável Valor de exemplo GCS_BUCKETduo-auth-logsGCS_PREFIXduo/auth/STATE_KEYduo/auth/state.jsonDUO_IKEYDIXYZ...DUO_SKEY****************DUO_API_HOSTNAMEapi-XXXXXXXX.duosecurity.comLIMIT500Role a tela para baixo na guia Variáveis e secrets até Solicitações:
- Tempo limite da solicitação: insira
600segundos (10 minutos).
- Tempo limite da solicitação: insira
Acesse a guia Configurações em Contêineres:
- Na seção Recursos:
- Memória: selecione 512 MiB ou mais.
- CPU: selecione 1.
- Clique em Concluído.
- Na seção Recursos:
Role até Ambiente de execução:
- Selecione Padrão (recomendado).
Na seção Escalonamento de revisão:
- Número mínimo de instâncias: insira
0. - Número máximo de instâncias: insira
100ou ajuste com base na carga esperada.
- Número mínimo de instâncias: insira
Clique em Criar.
Aguarde a criação do serviço (1 a 2 minutos).
Depois que o serviço é criado, o editor de código inline é aberto automaticamente.
Adicionar código da função
- Insira main em Ponto de entrada da função.
No editor de código em linha, crie dois arquivos:
- Primeiro arquivo: main.py::
#!/usr/bin/env python3 # Cloud Run Function: Pull Duo Admin API v2 Authentication Logs to GCS (raw JSON pages) # Notes: # - Duo v2 requires mintime/maxtime in *milliseconds* (13-digit epoch). # - Pagination via metadata.next_offset ("<millis>,<txid>"). # - We save state (mintime_ms) in ms to resume next run without gaps. import functions_framework from google.cloud import storage import os import json import time import hmac import hashlib import base64 import email.utils import urllib.parse from urllib.request import Request, urlopen from urllib.error import HTTPError, URLError DUO_IKEY = os.environ["DUO_IKEY"] DUO_SKEY = os.environ["DUO_SKEY"] DUO_API_HOSTNAME = os.environ["DUO_API_HOSTNAME"].strip() GCS_BUCKET = os.environ["GCS_BUCKET"] GCS_PREFIX = os.environ.get("GCS_PREFIX", "duo/auth/").strip("/") STATE_KEY = os.environ.get("STATE_KEY", "duo/auth/state.json") LIMIT = min(int(os.environ.get("LIMIT", "500")), 1000) # default 500, max 1000 storage_client = storage.Client() def _canon_params(params: dict) -> str: parts = [] for k in sorted(params.keys()): v = params[k] if v is None: continue parts.append(f"{urllib.parse.quote(str(k), '~')}={urllib.parse.quote(str(v), '~')}") return "&".join(parts) def _sign(method: str, host: str, path: str, params: dict) -> dict: now = email.utils.formatdate() canon = "\n".join([ now, method.upper(), host.lower(), path, _canon_params(params) ]) sig = hmac.new( DUO_SKEY.encode("utf-8"), canon.encode("utf-8"), hashlib.sha1 ).hexdigest() auth = base64.b64encode(f"{DUO_IKEY}:{sig}".encode()).decode() return { "Date": now, "Authorization": f"Basic {auth}" } def _http(method: str, path: str, params: dict, timeout: int = 60, max_retries: int = 5) -> dict: host = DUO_API_HOSTNAME assert host.startswith("api-") and host.endswith(".duosecurity.com"), \ "DUO_API_HOSTNAME must be like api-XXXXXXXX.duosecurity.com" qs = _canon_params(params) url = f"https://{host}{path}" + (f"?{qs}" if qs else "") attempt, backoff = 0, 1.0 while True: req = Request(url, method=method.upper()) req.add_header("Accept", "application/json") for k, v in _sign(method, host, path, params).items(): req.add_header(k, v) try: with urlopen(req, timeout=timeout) as r: return json.loads(r.read().decode("utf-8")) except HTTPError as e: if (e.code == 429 or 500 <= e.code <= 599) and attempt < max_retries: time.sleep(backoff) attempt += 1 backoff *= 2 continue raise except URLError: if attempt < max_retries: time.sleep(backoff) attempt += 1 backoff *= 2 continue raise def _read_state_ms() -> int | None: try: bucket = storage_client.bucket(GCS_BUCKET) blob = bucket.blob(STATE_KEY) if blob.exists(): state_data = blob.download_as_text() val = json.loads(state_data).get("mintime") if val is None: return None # Backward safety: if seconds were stored, convert to ms return int(val) * 1000 if len(str(int(val))) <= 10 else int(val) except Exception: return None def _write_state_ms(mintime_ms: int): bucket = storage_client.bucket(GCS_BUCKET) blob = bucket.blob(STATE_KEY) body = json.dumps({"mintime": int(mintime_ms)}).encode("utf-8") blob.upload_from_string(body, content_type="application/json") def _write_page(payload: dict, when_epoch_s: int, page: int) -> str: bucket = storage_client.bucket(GCS_BUCKET) key = f"{GCS_PREFIX}/{time.strftime('%Y/%m/%d', time.gmtime(when_epoch_s))}/duo-auth-{page:05d}.json" blob = bucket.blob(key) blob.upload_from_string( json.dumps(payload, separators=(",", ":")).encode("utf-8"), content_type="application/json" ) return key def fetch_and_store(): now_s = int(time.time()) # Duo recommends a ~2-minute delay buffer; use maxtime = now - 120 seconds (in ms) maxtime_ms = (now_s - 120) * 1000 mintime_ms = _read_state_ms() or (maxtime_ms - 3600 * 1000) # 1 hour on first run page = 0 total = 0 next_offset = None while True: params = { "mintime": mintime_ms, "maxtime": maxtime_ms, "limit": LIMIT } if next_offset: params["next_offset"] = next_offset data = _http("GET", "/admin/v2/logs/authentication", params) _write_page(data, maxtime_ms // 1000, page) page += 1 resp = data.get("response") items = resp if isinstance(resp, list) else [] total += len(items) meta = data.get("metadata") or {} next_offset = meta.get("next_offset") if not next_offset: break # Advance window to maxtime_ms for next run _write_state_ms(maxtime_ms) return { "ok": True, "pages": page, "events": total, "next_mintime_ms": maxtime_ms } @functions_framework.cloud_event def main(cloud_event): """ Cloud Run function triggered by Pub/Sub to fetch Duo authentication logs and write to GCS. Args: cloud_event: CloudEvent object containing Pub/Sub message """ try: result = fetch_and_store() print(f"Successfully processed {result['events']} events in {result['pages']} pages") print(f"Next mintime_ms: {result['next_mintime_ms']}") except Exception as e: print(f"Error processing logs: {str(e)}") raise- Segundo arquivo: requirements.txt:
functions-framework==3.* google-cloud-storage==2.*Clique em Implantar para salvar e implantar a função.
Aguarde a conclusão da implantação (2 a 3 minutos).
Criar o job do Cloud Scheduler
O Cloud Scheduler publica mensagens no tópico do Pub/Sub em intervalos regulares, acionando a função do Cloud Run.
- No Console do GCP, acesse o Cloud Scheduler.
- Clique em Criar job.
Informe os seguintes detalhes de configuração:
Configuração Valor Nome duo-auth-collector-hourlyRegião Selecione a mesma região da função do Cloud Run Frequência 0 * * * *(a cada hora, na hora)Fuso horário Selecione o fuso horário (UTC recomendado) Tipo de destino Pub/Sub Tópico Selecione o tópico duo-auth-trigger.Corpo da mensagem {}(objeto JSON vazio)Clique em Criar.
Opções de frequência de programação
Escolha a frequência com base no volume de registros e nos requisitos de latência:
Frequência Expressão Cron Caso de uso A cada 5 minutos */5 * * * *Alto volume e baixa latência A cada 15 minutos */15 * * * *Volume médio A cada hora 0 * * * *Padrão (recomendado) A cada 6 horas 0 */6 * * *Baixo volume, processamento em lote Diário 0 0 * * *Coleta de dados históricos
Testar o job do programador
- No console do Cloud Scheduler, encontre seu job.
- Clique em Forçar execução para acionar manualmente.
- Aguarde alguns segundos e acesse Cloud Run > Serviços > duo-auth-collector > Registros.
- Verifique se a função foi executada com sucesso.
- Verifique o bucket do GCS para confirmar se os registros foram gravados.
Recuperar a conta de serviço do Google SecOps
O Google SecOps usa uma conta de serviço exclusiva para ler dados do seu bucket do GCS. Você precisa conceder a essa conta de serviço acesso ao seu bucket.
Receber o e-mail da conta de serviço
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
Duo Authentication Logs). - Selecione Google Cloud Storage V2 como o Tipo de origem.
- Selecione Autenticação do Duo como o Tipo de registro.
Clique em Receber conta de serviço. Um e-mail exclusivo da conta de serviço é exibido, por exemplo:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopie esse endereço de e-mail para usar na próxima etapa.
Conceder permissões do IAM à conta de serviço do Google SecOps
A conta de serviço do Google SecOps precisa do papel de Leitor de objetos do Storage no seu bucket do GCS.
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket.
- Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar participantes: cole o e-mail da conta de serviço do Google SecOps.
- Atribuir papéis: selecione Leitor de objetos do Storage.
Clique em Salvar.
Configurar um feed no Google SecOps para ingerir registros de autenticação do Duo
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
Duo Authentication Logs). - Selecione Google Cloud Storage V2 como o Tipo de origem.
- Selecione Autenticação do Duo como o Tipo de registro.
- Clique em Próxima.
Especifique valores para os seguintes parâmetros de entrada:
URL do bucket de armazenamento: insira o URI do bucket do GCS com o caminho do prefixo:
gs://duo-auth-logs/duo/auth/Substitua:
duo-auth-logs: o nome do bucket do GCS.duo/auth/: prefixo/caminho da pasta opcional onde os registros são armazenados (deixe em branco para a raiz).
Exemplos:
- Bucket raiz:
gs://company-logs/ - Com prefixo:
gs://company-logs/duo-logs/ - Com subpasta:
gs://company-logs/duo/auth/
- Bucket raiz:
Opção de exclusão da fonte: selecione a opção de exclusão de acordo com sua preferência:
- Nunca: nunca exclui arquivos após as transferências (recomendado para testes).
- Excluir arquivos transferidos: exclui os arquivos após a transferência bem-sucedida.
Excluir arquivos transferidos e diretórios vazios: exclui arquivos e diretórios vazios após a transferência bem-sucedida.
Idade máxima do arquivo: inclui arquivos modificados no último número de dias. O padrão é de 180 dias.
Namespace do recurso: o namespace do recurso.
Rótulos de ingestão: o rótulo a ser aplicado aos eventos deste feed.
Clique em Próxima.
Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Tabela de mapeamento do UDM
| Campo de registro | Mapeamento do UDM | Lógica |
|---|---|---|
| access_device.browser | target.resource.attribute.labels.value | Se "access_device.browser" estiver presente, o valor será mapeado para a UDM. |
| access_device.hostname | principal.hostname | Se access_device.hostname estiver presente e não estiver vazio, o valor será mapeado para a UDM. Se estiver vazio e o event_type for USER_CREATION, o event_type será alterado para USER_UNCATEGORIZED. Se access_device.hostname estiver vazio e o campo hostname existir, o valor de hostname será usado. |
| access_device.ip | principal.ip | Se "access_device.ip" existir e for um endereço IPv4 válido, o valor dele será mapeado para a UDM. Se não for um endereço IPv4 válido, ele será adicionado como um valor de string a additional.fields com a chave access_device.ip. |
| access_device.location.city | principal.location.city | Se presente, o valor será mapeado para a UDM. |
| access_device.location.country | principal.location.country_or_region | Se presente, o valor será mapeado para a UDM. |
| access_device.location.state | principal.location.state | Se presente, o valor será mapeado para a UDM. |
| access_device.os | principal.platform | Se presente, o valor será traduzido para o valor correspondente do UDM (MAC, WINDOWS, LINUX). |
| access_device.os_version | principal.platform_version | Se presente, o valor será mapeado para a UDM. |
| application.key | target.resource.id | Se presente, o valor será mapeado para a UDM. |
| application.name | target.application | Se presente, o valor será mapeado para a UDM. |
| auth_device.ip | target.ip | Se estiver presente e não for "None", o valor será mapeado para a UDM. |
| auth_device.location.city | target.location.city | Se presente, o valor será mapeado para a UDM. |
| auth_device.location.country | target.location.country_or_region | Se presente, o valor será mapeado para a UDM. |
| auth_device.location.state | target.location.state | Se presente, o valor será mapeado para a UDM. |
| auth_device.name | target.hostname OR target.user.phone_numbers | Se auth_device.name estiver presente e for um número de telefone (após a normalização), ele será adicionado a target.user.phone_numbers. Caso contrário, ele será mapeado para target.hostname. |
| client_ip | target.ip | Se estiver presente e não for "None", o valor será mapeado para a UDM. |
| client_section | target.resource.attribute.labels.value | Se client_section estiver presente, o valor dele será mapeado para o UDM com a chave client_section. |
| dn | target.user.userid | Se "dn" estiver presente e "user.name" e "username" não estiverem, o userid será extraído do campo "dn" usando grok e mapeado para a UDM. O event_type é definido como USER_LOGIN. |
| event_type | metadata.product_event_type AND metadata.event_type | O valor é mapeado para "metadata.product_event_type". Também é usado para determinar que metadata.event_type: "authentication" se torna USER_LOGIN, "enrollment" se torna USER_CREATION e, se estiver vazio ou nenhum dos dois, se torna GENERIC_EVENT. |
| fator | extensions.auth.mechanism AND extensions.auth.auth_details | O valor é traduzido para o valor auth.mechanism correspondente da UDM (HARDWARE_KEY, REMOTE_INTERACTIVE, LOCAL, OTP). O valor original também é mapeado para "extensions.auth.auth_details". |
| nome do host | principal.hostname | Se estiver presente e access_device.hostname estiver vazio, o valor será mapeado para o UDM. |
| log_format | target.resource.attribute.labels.value | Se log_format estiver presente, o valor será mapeado para a UDM com a chave log_format. |
| loglevel._classuuid_ | target.resource.attribute.labels.value | Se loglevel._classuuid_ estiver presente, o valor será mapeado para a UDM com a chave class_uuid. |
| log_level.name | target.resource.attribute.labels.value AND security_result.severity | Se log_level.name estiver presente, o valor será mapeado para a UDM com o nome da chave. Se o valor for "info", security_result.severity será definido como "INFORMATIONAL". |
| log_logger.unpersistable | target.resource.attribute.labels.value | Se log_logger.unpersistable estiver presente, o valor dele será mapeado para a UDM com a chave "unpersistable". |
| log_namespace | target.resource.attribute.labels.value | Se log_namespace estiver presente, o valor dele será mapeado para a UDM com a chave log_namespace. |
| log_source | target.resource.attribute.labels.value | Se log_source estiver presente, o valor dele será mapeado para a UDM com a chave log_source. |
| msg | security_result.summary | Se estiver presente e o motivo estiver vazio, o valor será mapeado para a UDM. |
| reason | security_result.summary | Se presente, o valor será mapeado para a UDM. |
| resultado | security_result.action_details AND security_result.action | Se presente, o valor será mapeado para security_result.action_details. "success" ou "SUCCESS" se traduz em security_result.action ALLOW. Caso contrário, BLOCK. |
| server_section | target.resource.attribute.labels.value | Se server_section estiver presente, o valor será mapeado para a UDM com a chave server_section. |
| server_section_ikey | target.resource.attribute.labels.value | Se server_section_ikey estiver presente, o valor dele será mapeado para a UDM com a chave server_section_ikey. |
| status | security_result.action_details AND security_result.action | Se presente, o valor será mapeado para security_result.action_details. "Permitir" é traduzido como security_result.action ALLOW, e "Rejeitar" é traduzido como BLOCK. |
| timestamp | metadata.event_timestamp AND event.timestamp | O valor é convertido em um carimbo de data/hora e mapeado para metadata.event_timestamp e event.timestamp. |
| txid | metadata.product_log_id AND network.session_id | O valor é mapeado para metadata.product_log_id e network.session_id. |
| user.groups | target.user.group_identifiers | Todos os valores na matriz são adicionados a "target.user.group_identifiers". |
| user.key | target.user.product_object_id | Se presente, o valor será mapeado para a UDM. |
| user.name | target.user.userid | Se presente, o valor será mapeado para a UDM. |
| nome de usuário | target.user.userid | Se estiver presente e user.name não estiver, o valor será mapeado para a UDM. O event_type é definido como USER_LOGIN. |
| (Lógica do analisador) | metadata.vendor_name | Sempre definido como "DUO_SECURITY". |
| (Lógica do analisador) | metadata.product_name | Sempre definido como "MULTI-FACTOR_AUTHENTICATION". |
| (Lógica do analisador) | metadata.log_type | Extraído do campo "log_type" de nível superior do registro bruto. |
| (Lógica do analisador) | extensions.auth.type | Sempre definido como "SSO". |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.