Ir al contenido
Avanet

Gestionar la cuarentena de Sophos Email mediante la API

La Email Quarantine API procesa mensajes que Sophos Email ha trasladado a la cuarentena normal de seguridad de correo antes de la entrega. El procedimiento seguro consiste en realizar una búsqueda restringida, evaluar cada página, registrar el X-Sophos-Email-ID y el destinatario, inspeccionar el contenido, efectuar un cambio de alcance reducido y comprobar el resultado para cada destinatario.

Este artículo utiliza únicamente rutas bajo /email/v1/quarantine. La Post-Delivery Quarantine, de nombre parecido, afecta a mensajes ya entregados que posteriormente se retiraron y cuenta con su propia familia de endpoints. No mezcle sus rutas, identificadores ni estados con este procedimiento.

Preparar los requisitos y las variables

Complete primero la introducción a la Sophos Email Management API. La guía prevista Autenticar la Sophos Email API y enrutar solicitudes al tenant profundiza en el Service Principal, la resolución del tenant y los permisos mínimos. Los valores siguientes ya deben haberse determinado de forma segura:

  • SOPHOS_ACCESS_TOKEN: token bearer OAuth2 de corta duración;
  • SOPHOS_TENANT_ID: UUID del tenant de destino;
  • SOPHOS_API_HOST: host regional de API de ese tenant;
  • un permiso de Email Quarantine asignado al Service Principal.
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"

Los tokens, las URL de descarga, las contraseñas ZIP, las cabeceras MIME y el texto de los mensajes son secretos o datos personales. No deben aparecer en el historial del shell, los argumentos de procesos, la salida de CI ni los tickets. Los bloques JSON siguientes son ejemplos de documentación deliberados; los clientes de producción escriben los payloads en archivos temporales protegidos o los pasan por la entrada estándar.

Los contratos descritos se comprobaron con la Email Management API v1.4.0. Antes de implementarlos, vuelva a verificar el método, la ruta, el esquema, el permiso y los límites en la especificación actual.

Buscar de forma restringida y paginar todos los resultados

POST /quarantine/messages/search requiere beginDate y endDate como instantes ISO 8601. Los filtros son opcionales. El ejemplo limita un caso de malware entrante a un destinatario y solicita 100 registros, el máximo documentado por página de búsqueda:

{
  "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"]
  }
}

El contrato de filtro incluye id, fromContains, toContains, subjectContains, attachmentNameContains, hasAnyAttachment, sizeInMBGreaterThan, sizeInMBLowerThan, direction (inbound u outbound), productType (mailflow, gateway o ems) y reason. Los campos de ordenación documentados son from, forRecipient y quarantinedAt. Con fields puede solicitarse una respuesta parcial; el cliente no debe interpretar campos omitidos como valores vacíos.

La respuesta contiene items y pages. Para la página siguiente, copie pages.nextKey sin modificar y como string en pageFromKey del siguiente cuerpo POST. Termine únicamente cuando ya no exista nextKey y proteja además el bucle con límites de páginas y tiempo de ejecución y con detección de claves repetidas. pages.size solo describe la página actual. Por tanto, que la primera página esté llena o vacía no demuestra que la búsqueda esté completa ni que no haya más resultados.

Registre al menos id, forRecipient, reason, quarantinedAt, direction y la operación prevista para cada resultado. id es el UUID de la cabecera MIME X-Sophos-Email-ID; mimeMessageId es la cabecera Message-ID normal y no la sustituye en una ruta API ni en un cuerpo masivo. Un mismo mensaje puede producir resultados específicos por destinatario.

Inspeccionar el mensaje, las URL y los adjuntos

Las tres operaciones de lectura usan el id codificado para URL en la ruta:

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

La vista previa devuelve headers, htmlBody y textBody. Trate el HTML como contenido hostil: no lo renderice directamente en un navegador o portal administrativo, no cargue recursos externos y no abra los enlaces incluidos. Para analizar, prefiera texto y cabeceras concretas.

Las listas de URL y adjuntos utilizan páginas numeradas desde 1. El valor predeterminado de pageSize es 50; la respuesta indica el máximo permitido en pages.maxSize y, según el esquema comprobado, puede contener hasta 500 elementos. Continúe hasta que pages.current alcance la última página indicada o hasta que aparezca una página vacía. No use aquí el modelo de claves de la búsqueda (nextKey).

Un registro de URL es un hallazgo, no un veredicto de seguridad. Un registro de adjunto contiene name, sizeInBytes, fileType y stripped. Las acciones identifican los adjuntos por su nombre documentado, no mediante un UUID de adjunto inventado. Si hay nombres duplicados o una lista inesperada, no haga suposiciones: aclare el caso manualmente.

Descargar, retirar o volver a adjuntar archivos

La descarga es asíncrona y consta de dos fases. Primero se inicia un trabajo para un mensaje. Si se omite attachments, el trabajo incluye todos los adjuntos; una lista explícita es más segura para un caso controlado:

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

La respuesta contiene al menos el id y el status del trabajo. Este identificador se convierte en el downloadId de la ruta de estado y no debe confundirse con el ID del mensaje:

GET /quarantine/downloads/{downloadId}/status

Consulte con un backoff limitado hasta que status sea completed o failed. En completed pueden aparecer attachments, una url firmada y una password para el ZIP protegido. La URL es material de acceso de corta duración: descárguela de inmediato únicamente en un entorno de análisis aislado y aprobado, nunca la registre y, si caduca, utilice el estado del trabajo o un nuevo trabajo de descarga autorizado. En failed, evalúe error; el cliente no debe iniciar una serie interminable de trabajos.

Strip y reattach modifican el estado de los adjuntos por destinatario:

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

forRecipients limita el cambio. Sin esta restricción, la acción puede afectar a otros destinatarios del mensaje. Separe siempre la respuesta en items correctos y errors fallidos. Después, vuelva a obtener la lista de adjuntos y compruebe stripped para el nombre previsto. Reattach no libera el mensaje ni demuestra que el adjunto sea seguro.

Liberar o eliminar mensajes de forma controlada

Release y delete aceptan como máximo 50 registros por solicitud. Cada registro requiere el X-Sophos-Email-ID; forRecipients es opcional, pero es la restricción segura para una operación específica por destinatario.

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

Una liberación de alcance restringido tiene este aspecto:

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

Release devuelve HTTP 202: el mensaje fue aceptado y puesto en cola para su liberación, no entregado de forma demostrable. allowSender y enforceSenderAuthentication permanecen en false de forma predeterminada. Permita un remitente únicamente tras una aprobación de seguridad independiente; si activa allowSender de forma intencionada, no deje desactivada por error la autenticación del remitente. submitMessageToLabs solo se aplica a mensajes de spam y virus. stripAttachments actúa por cada registro de liberación.

Solicite la eliminación por separado y sin bloquear implícitamente al remitente:

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

Delete devuelve HTTP 200 si se completa correctamente. blockSender supone un cambio de política adicional y más amplio y permanece en false sin una solicitud de bloqueo aprobada. No repita a ciegas release o delete tras un timeout: el servidor puede haber aceptado ya la primera solicitud.

Ambas respuestas masivas pueden contener items y errors simultáneamente. Por tanto, el éxito HTTP no significa que todos los pares ID/destinatario hayan tenido éxito. Compare cada par solicitado una sola vez con ambos arrays; los resultados ausentes, duplicados o contradictorios deben impedir una confirmación automática de éxito.

Verificar el resultado

Realice estos controles para cada cambio:

  1. Registre el request ID o correlation ID, el estado HTTP, la hora, el tenant y una lista censurada de pares ID/destinatario; no almacene contenido ni secretos.
  2. Para strip/reattach, vuelva a enumerar los adjuntos y compruebe stripped para cada nombre.
  3. Para release, evalúe todos los items y errors, repita la misma búsqueda en cuarentena y confirme la entrega real mediante la evidencia operativa prevista. El 202 por sí solo no basta.
  4. Para delete, evalúe todos los items y errors y repita la misma búsqueda. Considere la ausencia de un registro como prueba solo junto con la respuesta masiva positiva, ya que las ventanas temporales y los filtros también pueden ocultar resultados.
  5. Para descargas, coteje el downloadId, el estado final y los nombres solicitados; elimine la URL y la contraseña de la memoria y del almacenamiento temporal al terminar.

Resolver fallos parciales, trabajos caducados y permisos

  • Falla una parte de la acción masiva: Evalúe errors por id, recipient y error. No reenvíe los pares correctos. Procese en una solicitud nueva solo los pares con error que aún existan y se hayan aprobado de nuevo.
  • 400 Bad Request: Compruebe tipos JSON, campos obligatorios, instantes ISO, UUID, valores enum, modelo de paginación y los límites respectivos de 50 o 100. pageFromKey es un string, no un número de página.
  • 401 o 403: Renueve el token mediante el flujo OAuth2 normal o compruebe la asignación del Service Principal, el permiso de Email Quarantine y el tenant. No cambie a otro tenant ni host.
  • 404 o ID no válido: Confirme que el UUID procede de X-Sophos-Email-ID, sigue en la cuarentena normal y pertenece al tenant. No use mimeMessageId, downloadId ni un ID de Post-Delivery Quarantine.
  • La descarga permanece en processing: Limite el intervalo y la duración total de las consultas, compruebe el ID del trabajo y el tenant y escale con el request/correlation ID. No inicie continuamente trabajos paralelos.
  • La descarga está failed o la URL ha caducado: Conserve error, vuelva a comprobar el estado e inicie una descarga nueva solo si la solicitud sigue vigente. No modifique ni reutilice una URL firmada.
  • Falta el adjunto o su estado difiere: Lea todas las páginas numeradas de adjuntos, compare los nombres exactamente y revise los errors por destinatario. Deténgase si hay colisiones de nombres o el mensaje ya se ha liberado.
  • La liberación desaparece de la lista pero no llega: Solo se puso en cola. Compruebe el destinatario, repita los filtros y examine la evidencia de entrega posterior; no vuelva a liberar automáticamente.

Una escalación debe incluir la versión de API, el host regional sin credenciales, el ID del tenant, el intervalo UTC, el método y la ruta, el estado HTTP, el request/correlation ID y los identificadores de objetos y códigos de error censurados. Excluya tokens, URL firmadas, contraseñas ZIP, texto de mensajes y adjuntos.