Sophos Email-quarantaine beheren via de API
De Email Quarantine API verwerkt berichten die Sophos Email vóór aflevering naar de gewone e-mailbeveiligingsquarantaine heeft verplaatst. De veilige werkwijze is: zoek gericht, beoordeel elke pagina, leg de X-Sophos-Email-ID en ontvanger vast, inspecteer de inhoud, voer een wijziging met beperkte reikwijdte uit en controleer het resultaat per ontvanger.
Dit artikel gebruikt uitsluitend paden onder /email/v1/quarantine. De vergelijkbaar genoemde Post-Delivery Quarantine betreft berichten die al zijn afgeleverd en daarna zijn teruggehaald en heeft een eigen endpointfamilie. Vermeng de paden, ID’s en statussen daarvan niet met deze werkwijze.
Vereisten en variabelen voorbereiden
Doorloop eerst de inleiding tot de Sophos Email Management API. De geplande handleiding De Sophos Email API authenticeren en aanvragen naar een tenant routeren gaat dieper in op de Service Principal, tenantbepaling en minimale rechten. De volgende waarden moeten al veilig zijn vastgesteld:
SOPHOS_ACCESS_TOKEN: een kortlevend OAuth2-bearertoken;SOPHOS_TENANT_ID: de UUID van de doeltenant;SOPHOS_API_HOST: de regionale API-host van die tenant;- een Email Quarantine-recht dat aan de Service Principal is toegewezen.
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"
Tokens, download-URL’s, ZIP-wachtwoorden, MIME-headers en berichttekst zijn geheimen of persoonsgegevens. Ze horen niet thuis in shellgeschiedenis, procesargumenten, CI-uitvoer of tickets. De volgende JSON-blokken zijn bewust documentatievoorbeelden; productieclients schrijven payloads naar beveiligde tijdelijke bestanden of geven ze door via standaardinvoer.
De beschreven contracten zijn gecontroleerd aan de hand van Email Management API v1.4.0. Controleer vóór implementatie de methode, het pad, het schema, de rechten en de limieten opnieuw in de actuele specificatie.
Gericht zoeken en alle resultaten pagineren
POST /quarantine/messages/search vereist beginDate en endDate als ISO 8601-tijdstippen. Filters zijn optioneel. Het voorbeeld beperkt een inkomend malwaregeval tot één ontvanger en vraagt 100 records op, het gedocumenteerde maximum per zoekpagina:
{
"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"]
}
}
Het filtercontract omvat id, fromContains, toContains, subjectContains, attachmentNameContains, hasAnyAttachment, sizeInMBGreaterThan, sizeInMBLowerThan, direction (inbound of outbound), productType (mailflow, gateway of ems) en reason. De gedocumenteerde sorteervelden zijn from, forRecipient en quarantinedAt. Met fields kan een gedeeltelijk antwoord worden opgevraagd; een client mag weggelaten velden niet als lege waarden interpreteren.
Het antwoord bevat items en pages. Kopieer voor de volgende pagina pages.nextKey ongewijzigd als string naar pageFromKey in de volgende POST-body. Stop pas wanneer nextKey ontbreekt en beveilig de lus daarnaast met grenzen voor het aantal pagina’s en de looptijd en met detectie van herhaalde sleutels. pages.size beschrijft alleen de huidige pagina. Een volle of lege eerste pagina bewijst dus niet dat de zoekopdracht volledig is of dat er geen verdere resultaten zijn.
Leg voor elk resultaat minimaal id, forRecipient, reason, quarantinedAt, direction en de geplande handeling vast. id is de UUID uit de MIME-header X-Sophos-Email-ID; mimeMessageId is de normale Message-ID-header en is geen vervanging in een API-pad of bulkbody. Hetzelfde bericht kan ontvangerspecifieke resultaten hebben.
Bericht, URL’s en bijlagen inspecteren
Alle drie leesbewerkingen gebruiken de URL-gecodeerde id in het pad:
GET /quarantine/messages/{id}/preview
GET /quarantine/messages/{id}/urls?pageSize=50&page=1
GET /quarantine/messages/{id}/attachments?pageSize=50&page=1
De voorbeeldweergave retourneert headers, htmlBody en textBody. Behandel HTML als vijandige inhoud: render deze niet rechtstreeks in een browser of beheerportaal, laad geen externe bronnen en open geen opgenomen links. Gebruik voor analyse bij voorkeur tekst en geselecteerde headers.
URL- en bijlagelijsten gebruiken genummerde pagina’s vanaf 1. De standaardwaarde van pageSize is 50; het antwoord vermeldt het toegestane maximum in pages.maxSize en kan volgens het gecontroleerde schema maximaal 500 elementen bevatten. Ga door totdat pages.current de laatst gemelde pagina bereikt of totdat een lege pagina volgt. Gebruik hier niet het sleutelmodel van de zoekopdracht (nextKey).
Een URL-record is een bevinding, geen veiligheidsoordeel. Een bijlagerecord bevat name, sizeInBytes, fileType en stripped. Handelingen adresseren bijlagen met hun gedocumenteerde naam, niet met een verzonnen bijlage-UUID. Ga bij dubbele namen of een onverwachte lijst niet gokken, maar onderzoek de zaak handmatig.
Bijlagen downloaden, verwijderen of opnieuw koppelen
Een download is asynchroon en bestaat uit twee stappen. Start eerst een job voor één bericht. Als attachments wordt weggelaten, omvat de job alle bijlagen; een expliciete lijst is veiliger voor een gecontroleerd geval:
POST /quarantine/messages/{id}/attachments/download
{
"attachments": ["sample.zip"]
}
Het antwoord bevat minimaal de id en status van de job. Deze job-ID wordt de downloadId in het statuspad en mag niet worden verward met de bericht-ID:
GET /quarantine/downloads/{downloadId}/status
Poll met begrensde backoff totdat status gelijk is aan completed of failed. Bij completed kunnen attachments, een ondertekende url en een password voor het beveiligde ZIP-bestand verschijnen. De URL is kortlevend toegangsmateriaal: download deze direct en uitsluitend naar een geïsoleerde, goedgekeurde analyseomgeving, log deze nooit en gebruik bij verlopen de jobstatus of een nieuwe geautoriseerde downloadjob. Evalueer bij failed de error; de client mag niet eindeloos nieuwe jobs starten.
Strip en reattach wijzigen de ontvangerspecifieke bijlagestatus:
POST /quarantine/messages/{id}/attachments/strip
POST /quarantine/messages/{id}/attachments/reattach
{
"attachments": ["sample.zip"],
"forRecipients": ["analyst@example.test"]
}
forRecipients beperkt de wijziging. Zonder deze beperking kan de handeling andere ontvangers van het bericht treffen. Verdeel het antwoord altijd in geslaagde items en mislukte errors. Haal daarna de bijlagelijst opnieuw op en controleer stripped voor de bedoelde naam. Reattach geeft het bericht niet vrij en bewijst niet dat de bijlage veilig is.
Berichten gecontroleerd vrijgeven of verwijderen
Release en delete accepteren maximaal 50 records per aanvraag. Elk record vereist de X-Sophos-Email-ID; forRecipients is optioneel, maar vormt de veilige beperking voor een ontvangerspecifieke handeling.
POST /quarantine/messages/release
POST /quarantine/messages/delete
Een nauw begrensde vrijgave ziet er als volgt uit:
{
"items": [
{
"id": "11111111-1111-4111-8111-111111111111",
"forRecipients": ["analyst@example.test"],
"stripAttachments": ["sample.zip"]
}
],
"allowSender": false,
"enforceSenderAuthentication": false,
"submitMessageToLabs": false
}
Release retourneert HTTP 202: het bericht is geaccepteerd en in de wachtrij geplaatst voor vrijgave, niet aantoonbaar afgeleverd. allowSender en enforceSenderAuthentication blijven standaard false. Sta een afzender pas toe na een afzonderlijke beveiligingsgoedkeuring; als allowSender bewust wordt ingeschakeld, mag afzenderauthenticatie niet onbedoeld uitgeschakeld blijven. submitMessageToLabs geldt alleen voor spam- en virusberichten. stripAttachments werkt per vrijgaverecord.
Vraag verwijdering afzonderlijk aan zonder de afzender impliciet te blokkeren:
{
"items": [
{
"id": "11111111-1111-4111-8111-111111111111",
"forRecipients": ["analyst@example.test"]
}
],
"blockSender": false
}
Delete retourneert bij succes HTTP 200. blockSender is een aanvullende, bredere beleidswijziging en blijft false zonder een goedgekeurde blokkeeropdracht. Herhaal release of delete niet blind na een timeout: de server kan het eerste verzoek al hebben geaccepteerd.
Beide bulkantwoorden kunnen tegelijk items en errors bevatten. HTTP-succes betekent daarom niet dat elk ID/ontvangerpaar is geslaagd. Vergelijk elk aangevraagd paar precies één keer met beide arrays; ontbrekende, dubbele of tegenstrijdige resultaten moeten een automatische succesmelding blokkeren.
Het resultaat verifiëren
Voer voor elke wijziging deze controles uit:
- Log de request ID of correlation ID, HTTP-status, tijd, tenant en een geredigeerde lijst met ID/ontvangerparen; sla geen inhoud of geheimen op.
- Geef na strip/reattach de bijlagen opnieuw weer en controleer
strippedvoor elke naam. - Evalueer na release alle
itemsenerrors, herhaal dezelfde quarantainezoekopdracht en controleer de werkelijke aflevering met het bedoelde operationele bewijs. Alleen202is onvoldoende. - Evalueer na delete alle
itemsenerrorsen herhaal dezelfde zoekopdracht. Gebruik een ontbrekend record alleen samen met het positieve bulkantwoord als bewijs, omdat tijdvensters en filters eveneens resultaten kunnen verbergen. - Vergelijk voor downloads de
downloadId, eindstatus en aangevraagde bestandsnamen; verwijder URL en wachtwoord na afloop uit het geheugen en de tijdelijke opslag.
Deelfouten, verlopen jobs en rechten oplossen
- Een deel van de bulkactie mislukt: Evalueer
errorsopid,recipientenerror. Stuur geslaagde paren niet opnieuw. Verwerk in een nieuwe aanvraag alleen foutparen die nog bestaan en opnieuw zijn goedgekeurd. 400 Bad Request: Controleer JSON-typen, verplichte velden, ISO-tijdstippen, UUID, enumwaarden, pagineringsmodel en de respectieve limieten van 50 of 100.pageFromKeyis een string, geen paginanummer.401of403: Vernieuw het token via de normale OAuth2-flow of controleer de toewijzing aan de Service Principal, het Email Quarantine-recht en de tenant. Schakel niet over naar een andere tenant of host.404of ongeldige ID: Controleer of de UUID uitX-Sophos-Email-IDkomt, nog in de gewone quarantaine bestaat en bij de tenant hoort. Gebruik geenmimeMessageId,downloadIdof Post-Delivery-ID.- De download blijft
processing: Begrens het pollinterval en de totale duur, controleer job-ID en tenant en escaleer met de request/correlation ID. Start niet voortdurend nieuwe parallelle jobs. - De download is
failedof de URL is verlopen: Bewaarerror, controleer de status nog eenmaal en start alleen een nieuwe download als de opdracht nog geldig is. Wijzig of hergebruik een ondertekende URL niet. - De bijlage ontbreekt of de status wijkt af: Lees alle genummerde bijlagepagina’s, vergelijk namen exact en controleer de
errorsper ontvanger. Stop bij dubbele namen of als het bericht al is vrijgegeven. - De vrijgave verdwijnt uit de lijst maar komt niet aan: Deze is alleen in de wachtrij geplaatst. Controleer de ontvanger, herhaal de filtering en bekijk het vervolgbewijs van aflevering; geef niet automatisch opnieuw vrij.
Een escalatie moet de API-versie, regionale host zonder aanmeldgegevens, tenant-ID, UTC-tijdvenster, methode en pad, HTTP-status, request/correlation ID en geredigeerde object-ID’s en foutcodes bevatten. Sluit tokens, ondertekende URL’s, ZIP-wachtwoorden, berichttekst en bijlagen uit.