Saltar para o conteudo
Avanet

Gerir a quarentena do Sophos Email através da API

A Email Quarantine API processa mensagens que o Sophos Email colocou na quarentena normal de segurança de email antes da entrega. O procedimento seguro consiste em pesquisar com filtros restritos, avaliar todas as páginas, registar o X-Sophos-Email-ID e o destinatário, inspecionar o conteúdo, efetuar uma alteração de âmbito reduzido e verificar o resultado para cada destinatário.

Este artigo utiliza apenas caminhos sob /email/v1/quarantine. A Post-Delivery Quarantine, apesar do nome semelhante, trata de mensagens já entregues e posteriormente retiradas e possui outra família de endpoints. Não misture os respetivos caminhos, IDs ou estados com este procedimento.

Preparar os pré-requisitos e as variáveis

Comece por concluir a introdução à Sophos Email Management API. O guia planeado Autenticar a Sophos Email API e encaminhar pedidos para um tenant aprofunda o Service Principal, a resolução do tenant e as permissões mínimas. Os seguintes valores já devem ter sido determinados de forma segura:

  • SOPHOS_ACCESS_TOKEN: token bearer OAuth2 de curta duração;
  • SOPHOS_TENANT_ID: UUID do tenant de destino;
  • SOPHOS_API_HOST: host regional da API desse tenant;
  • uma permissão de Email Quarantine atribuída ao Service Principal.
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"

Tokens, URLs de download, palavras-passe ZIP, cabeçalhos MIME e texto das mensagens são segredos ou dados pessoais. Não devem aparecer no histórico da shell, em argumentos de processos, na saída de CI ou em tickets. Os blocos JSON abaixo são exemplos de documentação; em produção, grave os payloads em ficheiros temporários protegidos ou envie-os pela entrada padrão.

Os contratos descritos foram verificados com a Email Management API v1.4.0. Antes da implementação, volte a confirmar o método, o caminho, o esquema, a permissão e os limites na especificação atual.

Pesquisar a quarentena com precisão e paginar todos os resultados

POST /quarantine/messages/search exige beginDate e endDate como instantes ISO 8601. Os filtros são opcionais. Este exemplo restringe um caso de malware recebido a um destinatário e pede 100 registos, o máximo documentado por página de pesquisa:

{
  "beginDate": "2026-09-14T00:00:00.000Z",
  "endDate": "2026-09-15T00:00:00.000Z",
  "pageSize": 100,
  "sort": ["quarantinedAt:DESC"],
  "filter": {
    "direction": "inbound",
    "toContains": "analyst@example.test",
    "reason": ["malware"]
  }
}

O contrato de filtro inclui id, fromContains, toContains, subjectContains, attachmentNameContains, hasAnyAttachment, sizeInMBGreaterThan, sizeInMBLowerThan, direction (inbound ou outbound), productType (mailflow, gateway ou ems) e reason. Os campos de ordenação documentados são from, forRecipient e quarantinedAt. É possível pedir uma resposta parcial com fields; o cliente não deve interpretar campos omitidos como valores vazios.

A resposta contém items e pages. Para obter a página seguinte, copie pages.nextKey sem alterações e como string para pageFromKey no corpo do POST seguinte. Termine apenas quando já não existir nextKey e proteja também o ciclo com limites de páginas e de duração e com a deteção de chaves repetidas. pages.size descreve apenas a página atual. Por isso, uma primeira página cheia ou vazia não prova que a pesquisa esteja completa nem que não existam outros resultados.

Para cada resultado, registe pelo menos id, forRecipient, reason, quarantinedAt, direction e a operação prevista. id é o UUID do cabeçalho MIME X-Sophos-Email-ID; mimeMessageId é o cabeçalho Message-ID normal e não o substitui num caminho da API nem num corpo em massa. A mesma mensagem pode produzir resultados específicos por destinatário.

Inspecionar a mensagem, os URLs e os anexos

As três operações de leitura utilizam o id codificado para URL no caminho:

GET /quarantine/messages/{id}/preview
GET /quarantine/messages/{id}/urls?pageSize=50&page=1
GET /quarantine/messages/{id}/attachments?pageSize=50&page=1

A pré-visualização devolve headers, htmlBody e textBody. Trate o HTML como conteúdo hostil: não o renderize diretamente num navegador ou portal de administração, não carregue recursos externos e não abra links incluídos. Para a análise, prefira texto e cabeçalhos selecionados.

As listas de URLs e anexos usam páginas numeradas a partir de 1. O valor predefinido de pageSize é 50; a resposta indica o máximo permitido em pages.maxSize e, segundo o esquema verificado, pode conter até 500 elementos. Continue até pages.current atingir a última página indicada ou até surgir uma página vazia. Não use aqui o modelo de chaves da pesquisa (nextKey).

Um registo de URL é um indício, não uma avaliação de segurança. Um registo de anexo contém name, sizeInBytes, fileType e stripped. As ações identificam os anexos pelo nome documentado, não por um UUID de anexo inventado. Se existirem nomes iguais ou uma lista inesperada, não adivinhe: esclareça o caso manualmente.

Transferir, remover ou voltar a anexar ficheiros

O download é assíncrono e tem duas fases. Primeiro, inicie um job para uma mensagem. Se attachments for omitido, o pedido abrange todos os anexos; uma lista explícita é mais segura num caso controlado:

POST /quarantine/messages/{id}/attachments/download
{
  "attachments": ["sample.zip"]
}

A resposta contém, pelo menos, o id e o status do job. Este ID do job torna-se o downloadId do caminho de estado e não deve ser confundido com o ID da mensagem:

GET /quarantine/downloads/{downloadId}/status

Consulte o estado com backoff limitado até status ser completed ou failed. Em completed, podem surgir attachments, um url assinado e uma password para o ZIP protegido. O URL é material de acesso de curta duração: transfira-o de imediato apenas para um ambiente de análise isolado e aprovado, nunca o registe e, se expirar, use o estado do job ou um novo pedido de download autorizado. Em failed, avalie error; o cliente não deve criar indefinidamente novos jobs.

Strip e reattach alteram o estado do anexo por destinatário:

POST /quarantine/messages/{id}/attachments/strip
POST /quarantine/messages/{id}/attachments/reattach
{
  "attachments": ["sample.zip"],
  "forRecipients": ["analyst@example.test"]
}

forRecipients limita a alteração. Sem esta restrição, a ação pode afetar outros destinatários da mensagem. Separe sempre a resposta em items bem-sucedidos e errors falhados. Em seguida, volte a obter a lista de anexos e verifique stripped para o nome pretendido. Reattach não liberta a mensagem nem prova que o anexo é seguro.

Libertar ou eliminar mensagens de forma controlada

Release e delete aceitam, no máximo, 50 registos por pedido. Cada registo exige o X-Sophos-Email-ID; forRecipients é opcional, mas constitui a restrição segura numa operação específica por destinatário.

POST /quarantine/messages/release
POST /quarantine/messages/delete

Uma libertação de âmbito restrito tem este aspeto:

{
  "items": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "forRecipients": ["analyst@example.test"],
      "stripAttachments": ["sample.zip"]
    }
  ],
  "allowSender": false,
  "enforceSenderAuthentication": false,
  "submitMessageToLabs": false
}

Release devolve HTTP 202: a mensagem foi aceite e colocada na fila para libertação, mas a entrega não está comprovada. allowSender e enforceSenderAuthentication permanecem false por predefinição. Autorize um remetente apenas após uma aprovação de segurança separada; se ativar intencionalmente allowSender, não deixe a autenticação do remetente desativada por engano. submitMessageToLabs aplica-se apenas a mensagens de spam e vírus. stripAttachments atua por registo de libertação.

Peça a eliminação separadamente e sem bloquear implicitamente o remetente:

{
  "items": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "forRecipients": ["analyst@example.test"]
    }
  ],
  "blockSender": false
}

Delete devolve HTTP 200 em caso de sucesso. blockSender é uma alteração de política adicional e mais abrangente e permanece false sem um pedido de bloqueio aprovado. Não repita cegamente release ou delete após um timeout: o servidor pode já ter aceite o primeiro pedido.

Ambas as respostas em massa podem conter simultaneamente items e errors. O sucesso HTTP não significa, portanto, que todos os pares ID/destinatário tenham sido processados. Compare cada par pedido exatamente uma vez com ambos os arrays; resultados ausentes, duplicados ou contraditórios devem impedir uma confirmação automática de sucesso.

Verificar o resultado

Efetue estes controlos para cada alteração:

  1. Registe o request ID ou correlation ID, estado HTTP, hora, tenant e uma lista expurgada dos pares ID/destinatário; não guarde conteúdo nem segredos.
  2. Para strip/reattach, liste novamente os anexos e verifique stripped para cada nome.
  3. Para release, avalie todos os items e errors, repita a mesma pesquisa na quarentena e confirme a entrega real através da evidência operacional prevista. O 202, por si só, não basta.
  4. Para delete, avalie todos os items e errors e repita a mesma pesquisa. Considere a ausência de um registo como prova apenas em conjunto com a resposta em massa positiva, pois janelas temporais e filtros também podem ocultar resultados.
  5. Para downloads, confirme o downloadId, o estado final e os nomes pedidos; remova o URL e a palavra-passe da memória e do armazenamento temporário no fim.

Resolver falhas parciais, jobs expirados e permissões

  • Parte da ação em massa falha: Avalie errors por id, recipient e error. Não reenvie pares bem-sucedidos. Envie num novo pedido apenas os pares com erro que ainda existam e tenham sido novamente aprovados.
  • 400 Bad Request: Verifique tipos JSON, campos obrigatórios, instantes ISO, UUID, valores enum, modelo de paginação e os respetivos limites de 50 ou 100. pageFromKey é uma string, não um número de página.
  • 401 ou 403: Renove o token pelo fluxo OAuth2 normal ou verifique a atribuição do Service Principal, a permissão de Email Quarantine e o tenant. Não mude para outro tenant ou host.
  • 404 ou ID inválido: Confirme que o UUID vem de X-Sophos-Email-ID, ainda existe na quarentena normal e pertence ao tenant. Não use mimeMessageId, downloadId nem um ID da Post-Delivery Quarantine.
  • O download permanece processing: Limite o intervalo e a duração total das consultas, confirme o ID do job e o tenant e escale com o request/correlation ID. Não inicie continuamente jobs paralelos.
  • O download está failed ou o URL expirou: Guarde error, volte a verificar o estado e crie um novo download apenas se o pedido continuar válido. Não altere nem reutilize um URL assinado.
  • O anexo não existe ou o estado difere: Leia todas as páginas numeradas de anexos, compare os nomes exatamente e verifique os errors por destinatário. Pare se houver colisões de nomes ou se a mensagem já tiver sido libertada.
  • A libertação desaparece da lista, mas não chega: Apenas foi colocada na fila. Verifique o destinatário, repita os filtros e inspecione a evidência de entrega posterior; não volte a libertar automaticamente.

Uma escalação deve incluir a versão da API, o host regional sem credenciais, o ID do tenant, a janela UTC, o método e o caminho, o estado HTTP, o request/correlation ID e IDs de objetos e códigos de erro expurgados. Exclua tokens, URLs assinados, palavras-passe ZIP, texto das mensagens e anexos.