-
-
Notifications
You must be signed in to change notification settings - Fork 0
Inbound Delivery
Cloudflare Email Routing invokes the Worker's email() handler with the raw RFC 822 message and envelope addresses. The handler:
- Captures the envelope sender, recipient, original sender IP when available, and receipt time.
- Generates a random 256-bit AES data key and 96-bit GCM IV.
- Encrypts the JSON envelope using AES-256-GCM.
- Wraps the data key with
MAILBRIDGE_PUBLIC_KEY_PEMusing RSA-OAEP SHA-256. - Writes only the encrypted envelope to the
MAIL_STORER2 bucket. - Sends
{ objectKey, encryptionVersion }toMAIL_QUEUE.
The Worker logs object identifiers and sizes, not raw mail contents.
The Worker's queue() handler processes each object reference independently:
- Load the encrypted object from R2.
- POST
{ encryptedPayload }toNODE_APP_URLwithX-Webhook-Secret. - On a successful HTTP response, delete the R2 object and acknowledge the Queue message.
- Retry HTTP
429,5xx, fetch failures, and R2 deletion failures with backoff. - Treat other
4xxresponses as permanent, delete the stored object, and acknowledge the Queue message.
If an object is already missing, the message is acknowledged because there is nothing left to deliver.
Mailbridge exposes:
POST /api/webhook/email
The endpoint requires the shared X-Webhook-Secret, rejects malformed mail fields, and decrypts v1 envelopes with the private key at MAILBRIDGE_PRIVATE_KEY_PATH. Supported encryption metadata is:
version: v1
algorithm: RSA-OAEP-256+A256GCM
Unsupported versions, algorithms, authentication failures, and malformed plaintext are rejected. The decrypted original sender IP is used for reputation checks; the Cloudflare request IP is not mistaken for the SMTP sender.
After decryption Mailbridge:
- Checks optional Spamhaus reputation data.
- Runs SpamAssassin locally or through Postmark SpamCheck.
- Optionally invokes AI for questionable messages or as a filter fallback.
- Detects the GTUBE test signature.
- Builds Exchange-friendly spam headers and optionally tags the subject.
- Delivers the raw message through Nodemailer to
LOCAL_MAIL_HOST:LOCAL_MAIL_PORT.
For TLS configuration and filter decisions, see Configuration Reference and Spam and Reputation Filtering.
- A local SMTP
5xxresponse is permanent and returned to the Worker. - Timeouts, connection failures, and temporary SMTP failures are stored in the encrypted local retry queue.
- If all spam filters are unavailable, Mailbridge returns
503unlessSPAMC_FAIL_OPEN=truewas explicitly configured. - Queue messages exceeding
QUEUE_MAX_ATTEMPTSare removed after an audit event records the drop.
Copyright (c) 2026 Voxvey Research LLC, a Helio company.