A Cloudflare email worker providing configurable email subaddressing (o.k.a. subaddress extension [RFC 5233]; a.k.a. detailed addressing, plus addresses, tagged addresses, mail extension, etc.)
Cloudflare Email Routing does not support subaddressing
and treats +
as a normal character. Cloudflare recommends
a catch-all solution, but that only works for a single
recipient and exposes the destination address to potential spam. This email
worker enables configuring the catch-all solution to limit users for which email
is accepted, control how it is delivered, and selectively respond to failures.
- limits users for which email is accepted
- limits subaddresses for which email is accepted (globally or per user)
- fails with a message or fail-forwards to a destination address (globally or per user)
- adds email header for filtering forwarded messages in destination email client
- allows customized subaddress separator
- supports KV for unlimited* user-to-destination combinations (with global fallbacks)
-
Cloudflare only forwards to verified destination addresses!
-
Email workers introduce limits that may not otherwise exist with built-in, one-to-one routes (rules).
Cloudflare Email Routing limits routes (rules) and destination addresses. But KV allows unlimited keys per namespace, which theoretically provides a workaround to these limitations. However, workers have request limits (on the free tier) and KV has read limits, among others (also on the free tier).
Caution
The default configuration rejects all email, effectively disabling email routing! Configure at least one user and destination to ensure email delivery.
- Log in to the Cloudflare dashboard
- Navigate to Workers & Pages
- Click the Create button
- Click the Create Worker button
- Give the worker a Name
HINT: Multiple email domains may require multiple email workers. A name likeemail-subaddressing
works for a single email domain or a single configuration shared across multiple domains, but a domain-oriented name likedomain-com-email
orat-domain-com
is better suited for per-domain configurations. - Click the Deploy button
- Click the Edit code button
- Replace the existing code in the already-opened
worker.js
tab with the contents of the worker script - Click the Deploy button
- Click the Save and deploy button on the confirmation
- Click the link above the
worker.js
tab (with the same name from step five) - Configure environment variables for scenarios involving
one-or-few users and one destination address.
OR
Create a KV for scenarios involving few-or-many users or more than one destination address.
- Navigate to Workers & Pages
- Select KV
- Click the Create a namespace button
- Give the KV a Namespace Name
HINT: KV names are only relevant when viewing the list of KVs and when binding the KV to an email worker. All KVs should be bound to the email worker asMAP
, so the KV name itself is less important. - Click the Add button
Given the email addresses [email protected] and [email protected] with a forwarding destination of any@email.com and a fail behavior of either 1) reject with message or 2) fail-forward to any+spam@email.com ...
Tip
Environment variables are configured in the worker's settings (Workers &
Pages > worker > Settings > Variables > Add variable under Environment
Variables). KVs are configured directly (Workers & Pages > KV > View in
kv's row) and bound (as MAP
) to workers (Workers & Pages > worker >
Settings > Variables > Add binding under KV Namespace Bindings)
- as the value of the
USERS
environment variable
OR - as one of several comma-separated users in the
USERS
environment variable
OR - as the value of the
@USERS
key in theMAP
-bound KV
OR - as one of several comma-separated users in the
@USERS
key in theMAP
- bound KV
OR - as a key in the
MAP
-bound KV
Note
Setting the USERS
environment variable to *
accepts email for all users
(subject to SUBADDRESSES
restrictions).
- as comma-separated values in the
SUBADDRESSES
environment variable (applied to all users)
OR - as comma-separated values in the
@SUBADDRESSES
key in theMAP
-bound KV (applied to all users)
OR - as comma-separated values in the
user+
key in theMAP
-bound KV (applies only to user)
Note
Setting shared values (i.e. options 1 and 2) to *
(the default) accepts
email with any subaddress (subject to USERS
restrictions).
- as the value of the
DESTINATION
environment variable (applied to all users)
OR - as the value of the
@DESTINATION
key in theMAP
-bound KV (applied to all users)
OR - as the value of the user's key in the
MAP
-bound KV (applies only to user)
Tip
Setting shared values (i.e. options 1 and 2) to a domain (e.g. @domain.com) enables multi-user destinations (accepted emails will be forwarded to the same user at the specified domain).
- as the value of the
FAILURE
environment variable (applied to all users)
OR - as the value of the
@FAILURE
key in theMAP
-bound KV (applied to all users)
OR - as the second, comma-separated value of the user's key in the
MAP
-bound KV (applies only to user)
Tip
Setting shared values (i.e. options 1 and 2) to a subaddress and domain (e.g. +spam@domain.com) enables multi-user failure destinations (rejected emails will be fail-forwarded to the same user at the specified domain with the specified subaddress).
Configure a catch-all address to use the newly installed and configured worker. From the Cloudflare dashboard ...
- Select the website for which email should be received
- Navigate to Email
- Click the Routing rules tab
- Set the Action field to "Send to a Worker"
- Set the Destination field to the name of the worker from installation step five
- Click the Disabled-labeled switch to enable catch-all
Contributions are welcome and are not limited to pull requests. Feel free to open an issue or start a discussion.
All works herein are licensed under MIT.