All docs

Docs · Reference

Mail forwarding

re-send inbound mail with EXEC txco://relay

Where txco://sendmail composes a new email, txco://relay forwards an inbound message verbatim — the Unix .forward primitive. It re-sends the original RFC 5322 bytes untouched (the sender’s From:, body, and attachments all survive), only rewriting the SMTP envelope. Because the message isn’t altered, the sender’s original DKIM signature stays valid, so DMARC still aligns to their domain.

Use it in an _mail stack to point a static address at a real inbox:

# Forward matt@ and hello@ to a real mailbox, like a .forward file. Runs BEFORE the
# publication existence check, guarded against loops, and halts (a forward is terminal).
WHEN @lmtp.rcpt.0 =~ /(?i)^(matt|hello)@example\.com$/ && @lmtp.is_bounce == false && @lmtp.msg.headers.auto-submitted == ""
  SET ._relay.to            = "someone@gmail.com",
      ._relay.raw           = @lmtp.msg.raw,
      ._relay.envelope_from = "noreply@example.com",
      ._relay.campaign      = &concat("fwd:", @lmtp.msg.id)
  EXEC "txco://relay"
  EMIT @lmtp.res.code = 250, @lmtp.res.msg = "accepted", @halt = true

The _relay contract

FieldRequiredNotes
rawyesThe message to send, base64 RFC 5322 — normally @lmtp.msg.raw (the full inbound message the LMTP inlet retains). Sent byte-for-byte unchanged — no re-compose, no re-sign.
toyesThe forward recipient (a single address).
envelope_fromyesThe SMTP MAIL FROM / Return-Path to stamp. Its domain must be verified for the tenant (the same anti-spoof check sendmail runs on from). Bounces go here.
campaignnoAt-most-once dedup key (e.g. "fwd:" + @lmtp.msg.id) so an LMTP redelivery doesn’t forward twice.

Result lands under ._relay.result ({status: "sent" | "skipped" | "error", to, envelope_from, reason?}).

Deliverability

A verbatim forward is a good forward, not a broken one:

  • DKIM survives → DMARC passes. The original signature is over the original bytes; we don’t touch them, so it still validates and DMARC aligns to the sender’s domain. (This is precisely what DKIM-survives-forwarding is designed for.)
  • SPF aligns via envelope_from. Stamping a Return-Path on a domain you own (e.g. noreply@example.com) makes SPF pass at the receiver for your domain — avoiding the classic .forward SPF break (where keeping the sender’s envelope-from fails SPF). Bounces land on that address; pair it with a noreply@ sink that eats them.
  • Loop guards. Never forward a bounce or an auto-response — gate on @lmtp.is_bounce == false && @lmtp.msg.headers.auto-submitted == "".

Security — relay is inbound-mail only

txco://relay ships arbitrary bytes out under a verified return-path, so it is more privileged than sendmail (which forces a verified From: and DKIM-signs what it builds). To prevent it being driven into a spam/phishing relay by some other pipeline (a coerced web endpoint feeding attacker-supplied _relay.raw), the op refuses unless the request originated from the LMTP inlet. That check reads the request’s source pinned in trusted context at ingress — not the mutable _txc.src envelope field a rule could forge. A _relay assembled by an HTTP/cron/etc. pipeline is rejected before anything is sent.

Attachments and exact MIME are preserved (unlike sendmail, which has no attachment support). Relay pays normal fuel and appears in traces.

Edit this page · View as markdown