Zarządzanie kwarantanną Sophos Email przez API
Email Quarantine API przetwarza wiadomości, które Sophos Email przeniósł do zwykłej kwarantanny bezpieczeństwa poczty przed dostarczeniem. Bezpieczny proces polega na precyzyjnym wyszukiwaniu, ocenie każdej strony, zapisaniu X-Sophos-Email-ID i odbiorcy, sprawdzeniu treści, wykonaniu zmiany o ograniczonym zakresie oraz zweryfikowaniu wyniku dla każdego odbiorcy.
Ten artykuł używa wyłącznie ścieżek pod /email/v1/quarantine. Podobnie nazwana Post-Delivery Quarantine dotyczy wiadomości, które zostały już dostarczone, a następnie wycofane, i ma własną rodzinę endpointów. Nie należy mieszać jej ścieżek, identyfikatorów ani stanów z tym procesem.
Przygotowanie wymagań i zmiennych
Najpierw należy zapoznać się z wprowadzeniem do Sophos Email Management API. Planowany poradnik Uwierzytelnianie Sophos Email API i kierowanie żądań do tenanta dokładniej opisuje Service Principal, ustalanie tenanta i minimalne uprawnienia. Poniższe wartości muszą już być bezpiecznie ustalone:
SOPHOS_ACCESS_TOKEN: krótkotrwały token bearer OAuth2;SOPHOS_TENANT_ID: UUID docelowego tenanta;SOPHOS_API_HOST: regionalny host API tego tenanta;- uprawnienie Email Quarantine przypisane do Service Principal.
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"
Tokeny, adresy URL pobierania, hasła ZIP, nagłówki MIME i tekst wiadomości są tajemnicami lub danymi osobowymi. Nie mogą trafiać do historii powłoki, argumentów procesów, wyników CI ani zgłoszeń. Poniższe bloki JSON są celowo przykładami dokumentacyjnymi; klienty produkcyjne zapisują payloady w chronionych plikach tymczasowych lub przekazują je przez standardowe wejście.
Opisane kontrakty sprawdzono z Email Management API v1.4.0. Przed wdrożeniem należy ponownie sprawdzić metodę, ścieżkę, schemat, uprawnienie i limity w aktualnej specyfikacji.
Precyzyjne wyszukiwanie i pobieranie wszystkich stron
POST /quarantine/messages/search wymaga beginDate i endDate jako znaczników czasu ISO 8601. Filtry są opcjonalne. Przykład ogranicza przypadek przychodzącego złośliwego oprogramowania do jednego odbiorcy i żąda 100 rekordów, czyli udokumentowanego maksimum na stronę wyszukiwania:
{
"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"]
}
}
Kontrakt filtra obejmuje id, fromContains, toContains, subjectContains, attachmentNameContains, hasAnyAttachment, sizeInMBGreaterThan, sizeInMBLowerThan, direction (inbound lub outbound), productType (mailflow, gateway lub ems) i reason. Udokumentowane pola sortowania to from, forRecipient i quarantinedAt. Za pomocą fields można zażądać odpowiedzi częściowej; klient nie może interpretować pominiętych pól jako pustych wartości.
Odpowiedź zawiera items i pages. Aby pobrać kolejną stronę, należy skopiować pages.nextKey bez zmian jako ciąg znaków do pageFromKey w następnym ciele POST. Pętlę należy zakończyć dopiero wtedy, gdy nie ma nextKey, i dodatkowo zabezpieczyć ją limitami liczby stron i czasu działania oraz wykrywaniem powtórzonych kluczy. pages.size opisuje wyłącznie bieżącą stronę. Pełna lub pusta pierwsza strona nie dowodzi więc kompletności ani braku dalszych wyników.
Dla każdego wyniku należy zapisać co najmniej id, forRecipient, reason, quarantinedAt, direction i planowaną operację. id to UUID z nagłówka MIME X-Sophos-Email-ID; mimeMessageId to zwykły nagłówek Message-ID i nie zastępuje go w ścieżce API ani ciele operacji zbiorczej. Ta sama wiadomość może mieć wyniki zależne od odbiorcy.
Sprawdzanie wiadomości, adresów URL i załączników
Wszystkie trzy operacje odczytu używają zakodowanego dla URL id w ścieżce:
GET /quarantine/messages/{id}/preview
GET /quarantine/messages/{id}/urls?pageSize=50&page=1
GET /quarantine/messages/{id}/attachments?pageSize=50&page=1
Podgląd zwraca headers, htmlBody i textBody. HTML należy traktować jako wrogą treść: nie renderować go bezpośrednio w przeglądarce ani portalu administracyjnym, nie ładować zewnętrznych zasobów i nie otwierać zawartych linków. Do analizy lepiej używać tekstu i wybranych nagłówków.
Listy adresów URL i załączników używają numerowanych stron, począwszy od 1. Domyślna wartość pageSize wynosi 50; odpowiedź podaje dozwolone maksimum w pages.maxSize i zgodnie ze sprawdzonym schematem może zawierać do 500 elementów. Należy kontynuować do chwili, gdy pages.current osiągnie ostatnią zgłoszoną stronę albo pojawi się pusta strona. Nie wolno używać tutaj modelu klucza wyszukiwania (nextKey).
Rekord URL jest znaleziskiem, a nie werdyktem bezpieczeństwa. Rekord załącznika zawiera name, sizeInBytes, fileType i stripped. Operacje wskazują załączniki przez ich udokumentowaną nazwę, a nie wymyślony UUID załącznika. Jeśli nazwy się powtarzają lub lista jest nieoczekiwana, nie należy zgadywać — przypadek trzeba wyjaśnić ręcznie.
Pobieranie, usuwanie lub ponowne dołączanie załączników
Pobieranie jest asynchroniczne i ma dwa etapy. Najpierw należy uruchomić zadanie dla jednej wiadomości. Jeśli attachments zostanie pominięte, zadanie obejmie wszystkie załączniki; jawna lista jest bezpieczniejsza w kontrolowanym przypadku:
POST /quarantine/messages/{id}/attachments/download
{
"attachments": ["sample.zip"]
}
Odpowiedź zawiera co najmniej id i status zadania. Identyfikator zadania staje się downloadId w ścieżce stanu i nie może być mylony z identyfikatorem wiadomości:
GET /quarantine/downloads/{downloadId}/status
Stan należy odpytywać z ograniczonym backoffem, aż status przyjmie wartość completed lub failed. Przy completed mogą pojawić się attachments, podpisany url i password do chronionego pliku ZIP. URL jest krótkotrwałym materiałem dostępowym: należy go szybko pobrać wyłącznie do izolowanego, zatwierdzonego środowiska analizy, nigdy nie logować i po wygaśnięciu użyć stanu zadania albo nowego autoryzowanego zadania pobierania. Przy failed trzeba ocenić error; klient nie może uruchamiać nieskończonej serii nowych zadań.
Strip i reattach zmieniają stan załącznika dla poszczególnych odbiorców:
POST /quarantine/messages/{id}/attachments/strip
POST /quarantine/messages/{id}/attachments/reattach
{
"attachments": ["sample.zip"],
"forRecipients": ["analyst@example.test"]
}
forRecipients ogranicza zmianę. Bez tego ograniczenia operacja może wpłynąć na innych odbiorców wiadomości. Odpowiedź należy zawsze podzielić na udane items i nieudane errors. Następnie trzeba ponownie pobrać listę załączników i sprawdzić stripped dla zamierzonej nazwy. Reattach nie zwalnia wiadomości i nie dowodzi, że załącznik jest bezpieczny.
Kontrolowane zwalnianie lub usuwanie wiadomości
Release i delete przyjmują najwyżej 50 rekordów w jednym żądaniu. Każdy rekord wymaga X-Sophos-Email-ID; forRecipients jest opcjonalne, ale stanowi bezpieczne ograniczenie dla operacji dotyczącej konkretnego odbiorcy.
POST /quarantine/messages/release
POST /quarantine/messages/delete
Ściśle ograniczone zwolnienie wygląda następująco:
{
"items": [
{
"id": "11111111-1111-4111-8111-111111111111",
"forRecipients": ["analyst@example.test"],
"stripAttachments": ["sample.zip"]
}
],
"allowSender": false,
"enforceSenderAuthentication": false,
"submitMessageToLabs": false
}
Release zwraca HTTP 202: wiadomość została przyjęta i umieszczona w kolejce do zwolnienia, ale nie ma dowodu jej dostarczenia. allowSender i enforceSenderAuthentication pozostają domyślnie false. Nadawcę można dopuścić dopiero po odrębnej akceptacji bezpieczeństwa; jeśli allowSender zostanie świadomie włączone, uwierzytelnianie nadawcy nie powinno przez pomyłkę pozostać wyłączone. submitMessageToLabs dotyczy wyłącznie wiadomości spamowych i wirusowych. stripAttachments działa dla poszczególnych rekordów zwolnienia.
Usunięcie należy zlecić oddzielnie i bez niejawnego blokowania nadawcy:
{
"items": [
{
"id": "11111111-1111-4111-8111-111111111111",
"forRecipients": ["analyst@example.test"]
}
],
"blockSender": false
}
Delete zwraca HTTP 200 po powodzeniu. blockSender jest dodatkową, szerszą zmianą zasad i pozostaje false bez zatwierdzonego zlecenia blokady. Nie należy automatycznie ponawiać release ani delete po przekroczeniu limitu czasu: serwer mógł już przyjąć pierwsze żądanie.
Obie odpowiedzi zbiorcze mogą jednocześnie zawierać items i errors. Sukces HTTP nie oznacza więc powodzenia każdej pary ID/odbiorca. Każdą żądaną parę należy dokładnie raz dopasować do obu tablic; brakujące, powtórzone lub sprzeczne wyniki muszą zablokować automatyczne potwierdzenie powodzenia.
Weryfikacja wyniku
Dla każdej zmiany należy wykonać następujące kontrole:
- Zapisać request ID lub correlation ID, stan HTTP, czas, tenant i zredagowaną listę par ID/odbiorca; nie przechowywać treści ani tajemnic.
- Po strip/reattach ponownie wyświetlić załączniki i sprawdzić
strippeddla każdej nazwy. - Po release ocenić wszystkie
itemsierrors, powtórzyć tę samą kwerendę kwarantanny i potwierdzić faktyczne dostarczenie za pomocą przewidzianego dowodu operacyjnego. Sam kod202nie wystarcza. - Po delete ocenić wszystkie
itemsierrorsi powtórzyć tę samą kwerendę. Brak rekordu uznać za dowód tylko razem z pozytywną odpowiedzią zbiorczą, ponieważ przedziały czasu i filtry również mogą ukrywać wyniki. - Przy pobieraniu dopasować
downloadId, stan końcowy i żądane nazwy plików; po zakończeniu usunąć URL i hasło z pamięci oraz pamięci tymczasowej.
Rozwiązywanie częściowych błędów, wygasłych zadań i problemów z uprawnieniami
- Część operacji zbiorczej kończy się błędem: Ocenić
errorswedługid,recipientierror. Nie wysyłać ponownie udanych par. W nowym żądaniu przetworzyć tylko te pary z błędem, które nadal istnieją i zostały ponownie zatwierdzone. 400 Bad Request: Sprawdzić typy JSON, wymagane pola, znaczniki czasu ISO, UUID, wartości enum, model paginacji i odpowiednie limity 50 lub 100.pageFromKeyjest ciągiem znaków, a nie numerem strony.401lub403: Odnowić token w zwykłym przepływie OAuth2 albo sprawdzić przypisanie Service Principal, uprawnienie Email Quarantine i tenanta. Nie przełączać się na innego tenanta ani host.404lub nieprawidłowy ID: Upewnić się, że UUID pochodzi zX-Sophos-Email-ID, nadal istnieje w zwykłej kwarantannie i należy do tenanta. Nie używaćmimeMessageId,downloadIdani identyfikatora Post-Delivery Quarantine.- Pobieranie pozostaje w stanie
processing: Ograniczyć interwał i całkowity czas odpytywania, sprawdzić ID zadania oraz tenanta i eskalować z request/correlation ID. Nie uruchamiać ciągle nowych zadań równolegle. - Pobieranie ma stan
failedlub URL wygasł: Zachowaćerror, ponownie sprawdzić stan i rozpocząć nowe pobieranie tylko wtedy, gdy zlecenie jest nadal ważne. Nie modyfikować ani nie używać ponownie podpisanego URL. - Brak załącznika lub jego stan jest inny: Odczytać wszystkie numerowane strony załączników, dokładnie porównać nazwy i sprawdzić
errorswedług odbiorcy. Zatrzymać się przy powtórzonych nazwach lub jeśli wiadomość została już zwolniona. - Zwolnienie znika z listy, ale wiadomość nie dociera: Zostało tylko umieszczone w kolejce. Sprawdzić odbiorcę, powtórzyć filtrowanie i zbadać późniejsze dowody dostarczenia; nie zwalniać automatycznie ponownie.
Eskalacja powinna zawierać wersję API, regionalny host bez danych uwierzytelniających, ID tenanta, przedział UTC, metodę i ścieżkę, stan HTTP, request/correlation ID oraz zredagowane ID obiektów i kody błędów. Należy wykluczyć tokeny, podpisane URL-e, hasła ZIP, tekst wiadomości i załączniki.