To block outbound email to block-domain.com, create a trusted System Sieve script and run it during the recipient-processing stage.
For a single domain:
require ["envelope", "reject"];
if envelope :domain :is :comparator "i;ascii-casemap"
"to" "block-domain.com"
{
reject "550 5.7.1 Sending email to this domain is prohibited.";
stop;
}
If you already maintain a list of blocked domains in a Stalwart search list, the script can read that list instead of hard-coding each domain. This makes it easier to manage the policy, since you can add or remove domains without having to modify the script.
The example above assumes that you agree to receive emails from this domain but do not want your users—or certain users (you can adapt this so the script isn’t global, I believe)—to receive them.
Update : Correction made based on the answer below
Stalwart extends Sieve with a set of built-in functions that can be called from expressions inside eval, let, and while instructions. The functions operate on Sieve values (strings, integers, floats, arrays) and on the message being processed: headers, MIME parts, envelope, and environment.
More information : Reference | Stalwart
Conceptually:
require [
"variables",
"envelope",
"reject",
"vnd.stalwart.expressions"
];
let "recipient_domain" "to_lowercase(email_part(envelope.to, 'domain'))";
if eval "key_exists('blocked-domain', recipient_domain)" {
reject "550 5.7.1 Sending email to this domain is prohibited.";
stop;
}
envelope.to, ‘domain’: Only the “domain” part of the email address string is taken
So we have recipient_domain = “block-domain.com”
So it will read the InMemoryKey, which is automatically filled in when you add a domain to the blocked domains list
If you need separate policies—one script for specific email addresses and another for domains—use a main trusted script with include, because a stage’s script expression selects one script name.
require ["include"];
include "block-outbound-addresses";
include "block-outbound-domains";
The main script then calls the individual policy scripts.
Trusted System Sieve scripts, lookup access, SMTP-stage invocation, and include are documented here: