← Back to Research

Status: implementation guide for the current embedded Starlark policy engine. It is not a claim of complete RFC 5228 compatibility.

MailScript runs an evaluate() function for each AMP envelope. Policies can inspect unencrypted envelope fields only: sender DID, recipient DID, message ID, previous hop, and blockchain-proof presence. The gateway does not decrypt message payloads before policy evaluation, so Subject, MIME From, body text, and attachments are not available to the current built-ins.

Working core actions

def evaluate():
    if regex_match(".*spammer.*", get_sender_did()):
        reject("sender blocked by policy")
    else:
        accept()
Sieve intent Current MailScript support
Keep/accept accept()
Silent discard discard()
Reject reject("reason")
Envelope matching get_sender_did(), get_recipient_did(), get_header() for documented AMP envelope fields, regex_match() and address_matches()
Mapping lookup lookup_map() for access, MX, and virtual-alias lookups

fileinto, redirect, vacation, and flag actions can be returned by the Starlark engine, but the shared delivery pipeline currently only enforces accept, discard, and reject. Do not rely on the other actions for mailbox routing or outbound mail.

Migration example

An old Sieve rule that checks an encrypted SMTP subject cannot be translated safely at the gateway. Prefer a policy based on an authenticated sender DID or recipient DID:

def evaluate():
    if get_sender_did() == "did:aftersmtp:example.com:billing":
        accept()
    else:
        discard()

Use sieve2mailscript.py only as a starting point. Review every generated rule for unsupported content inspection and actions that the pipeline does not yet execute.