Zbudowaliśmy bramkę mailową, która NIGDY nie blokuje
Firmowa poczta na Cloudflare, sześć aliasów, worker — i maile, które nie docierały. Winna była jedna kropka. Z tej lekcji powstała zasada, której nie negocjujemy: bramka, która nigdy nie blokuje. Nawet jak się zepsuje.
Nasza poczta nie docierała. A winna była kropka.
Pod koniec lipca 2026 stawialiśmy firmową pocztę: sześć aliasów na @byit.pl (info, kontakt, biuro, faktury, ksiegowosc, admin), Cloudflare Email Routing, dalej worker, dalej skrzynka w Gmailu. Cała nasza komunikacja — z klientami, z biurem rachunkowym, z urzędami — miała iść tą jedną rurą.
Nie szła.
Powód? Adres docelowy wpisany bez kropki. Gmail traktuje „jan.kowalski@gmail.com" i „jankowalski@gmail.com" jak jedną skrzynkę — kropki w nazwie są mu obojętne. Cloudflare weryfikuje adres co do znaku. Nie ma kropki, nie ma weryfikacji, nie ma przekazania dalej. [do uzupełnienia przez Kamila: jak to wyłapaliście — testową wiadomością? ile czasu to zajęło?]
Jedna kropka. Cała poczta.
W poprzednim artykule obiecałem, że ta historia ma drugie dno. Ma. I chyba właśnie ta kropka przesądziła o decyzji, która została z nami do dziś: nasza bramka mailowa nigdy nie blokuje.
Co to znaczy „nigdy"
Fail-open. Po polsku: system, który w razie awarii zostaje otwarty, a nie zatrzaskuje się.
Zanim to zmieniliśmy, bramka działała jak klasyczny strażnik: coś podejrzanego — odrzuć. Błąd — odrzuć. Worker padł — odrzuć. Logiczne, prawda? Tylko że „odrzuć" w przypadku poczty znaczy: wiadomość znika. Nadawca dostaje błąd, a Ty nie dostajesz nic. Nie masz nawet szansy zobaczyć, że coś Cię ominęło.
Odwróciliśmy to. Cała filozofia mieści się w jednej linijce konfiguracji: REJECT_ON_BLOCK=false.
Teraz „zablokowany" mail nie wraca do nadawcy. Idzie do skrzynki — z metką. Spam (próg 0,75)? Dostaniesz go, z nagłówkiem „to wygląda na spam". Coś, co nie przeszło bramki compliance (próg 0,70)? Też dotrze, oznaczone. Worker się wysypie, klasyfikacja padnie, model nie odpowie? Mail idzie dalej, surowy, z adnotacją, co się stało. Jedyny przypadek, w którym wiadomość nie dochodzi, to taki, w którym fizycznie nie da się jej wysłać.
Dlaczego tak, a nie inaczej
Policzcie sobie koszty.
Spam kosztuje pięć sekund: skasować. Zgubiona faktura kosztuje termin, karę, klienta. Czasem wszystkie trzy naraz. Mała firma nie tonie w spamie — tonie w strachu przed spamem, który każe jej blokować wszystko po kolei. A potem okazuje się, że zablokowała coś, co miało znaczenie. Sortowanie można powtórzyć. Zgubienie — nie.
Jedno miejsce, w którym jednak blokujemy
Byłbym nieuczciwy, pisząc, że nie odrzucamy niczego. Odrzucamy: catch-all jest ustawiony na drop. Mail na adres, który nie istnieje — literówka, bot zgadujący nazwy skrzynek — znika.
Ale to jest decyzja, nie tryb awaryjny. Wąska, świadoma, odwracalna. Blokada jest w porządku, jeśli jest decyzją, a nie domyślnym zachowaniem systemu, który się boi. Różnica jest taka: decyzję można zmienić w godzinę. Strach — nie.
System, który milczy
Do tego pilnujemy workera od zewnątrz: co 30 minut pukamy w endpoint /health i pytamy „żyjesz?". Jak odpowiada — cisza. Jak nie — alarm. [do uzupełnienia przez Kamila: czy watchdog coś już wyłapał od lipca?]
To niby detal, a to chyba sedno. System, który krzyczy bez powodu, przestaje być słuchany. Potem krzyczy, gdy naprawdę trzeba — i nikt nie reaguje. Cisza jest częścią projektu, nie brakiem.
Czego nas to nauczyło
Przestaliśmy pytać „czy to bezpieczne?". Zaczęliśmy pytać „co się stanie, jak to padnie?". I to pytanie zmienia wszystko. Bezpieczeństwo przestaje być murem, a staje się gwarancją, że nic ważnego nie zniknie. Mur zatrzymuje też to, co ma znaczenie. Gwarancja — nie.
Nie jestem pewien, czy to podejście ma sens w każdej firmie. Przy skrzynce, do której wpada tysiąc wiadomości dziennie, pewnie potrzebujecie ostrzejszych progów i filtrów po stronie odbiorcy. Ale kierunek chyba zostaje: projektuj system tak, żeby awaria kosztowała najmniej. Nie tak, żeby jej nie było — bo będzie.
W przyszłym tygodniu: nasz deadline manager milczy, gdy nie ma nic do roboty. Bo system, który krzyczy bez powodu… no wiecie.