-
v0.46.0 Stable
released this
2026-08-25 15:57:11 -05:00 | 71 commits to main since this releaseMail arriving at a single-purpose alias is now legible as such. An alias has
an expected sender, so an origin it has never seen is a signal on its own —
independent of authentication, and independent of any brand claim. That is the
attacker shape the rest of the hygiene checks miss: authenticate a throwaway
domain, impersonate nobody, and every existing check passes.Added
-
mail/aliases.py— which alias a message was delivered to, what that
alias has received before, and two flags. Shared by both tenants.There is no database, and that is the interesting part. The design called
for a persisted per-alias store plus a one-time backfill. Two measurements
replaced it. An MCP server only sees a message when the model asks about one,
so a store fed from the request path learns from a tiny biased sample and
would flag nearly everything. And the mailbox already is the history:
fetching four trimmed headers across the whole 4,603-message account takes
6.9 seconds, so the index is built on demand and cached
(MAIL_ALIAS_INDEX_TTL, default 1800s,0disables). No volume, no
migration, no backfill step, and no cold start in which every sender is new.
A restart costs one rebuild rather than a lost store.IMAP SEARCHcannot narrow the sweep — Gmail indexes neither
X-SimpleLogin-Envelope-Tonordeliveredto:for relayed mail. All three
search forms return zero hits against an alias with 35 messages present. -
alias_intent_mismatch— the alias name implies a brand the origin is
not. Blocking, because it contradicts a claim. It reuses the_BRAND_DOMAINS
map and_domain_is_the_brandsfrom 0.44.2 rather than matching loosely, and
it needs no history at all, so it works on the first message an alias ever
receives. -
alias_origin_unrecognized— first message this alias has had from this
registered domain. Non-blocking, and that is a measurement, not a
preference. 14 of 83 aliases sampled — 16% — have legitimately received mail
from more than one registered origin, every case in the sample benign: one
brand on several domains (statefarm.com,statefarmservice.com,
sfauthentication.com), an ESP, a franchise's marketing agency, a second
signup on the same alias. The design asked for a refusal here; that would have
refused all of them.Held-out check: trained on the older 155 relayed messages, replayed the newer
104. Two flagged — 1.9% —mlbemail.comon anmlb.*alias that knew
mlb.com, and a franchise agency on amcdonalds.*alias. Both benign, both
correctly ranked as a note rather than an alarm.The honest consequence: an attacker who authenticates a throwaway domain
and impersonates nobody is surfaced with evidence, not blocked. Blocking that
shape costs a refusal on one alias in six, and a flag that cries wolf at that
rate is one the reader learns to skip. -
alias_contextinget_message_security— which alias, which origin,
what that alias has seen before, and why it tripped. Evidence with no
recommendation attached, because the decision about a leaked alias is made
outside this server. Absent entirely when no alias is identifiable, so an
ordinary mailbox does not acquire a signal that means nothing there. -
hygiene.inspect(extra_flags=...)— observations computed outside the
module, merged into the result. The alias checks need an IMAP sweep and
hygieneis network-free by construction, so the IO stays in the client and
the finished flags arrive here. That property is what makes everything else in
the module fixture-testable.
Fixed
- The account holder's alias username was in a docstring, shipped in 0.45.0.
test_no_piiscans tracked files, andmail/origin.pywas untracked when
that release was gated — so the gate could not see it until the commit landed,
and caught it on the next run. Worth recording as the gate's second real
catch, and as the reason a new file deserves one gate run after staging.
Changed
- Alias identification prefers the relay's
X-SimpleLogin-Envelope-To, then
Delivered-To/X-Original-To, then a recipient at a known alias domain. That
order is measured: the envelope header identifies 278 of 281 relayed messages,
To/Cccatches 3 more, and the alias is usually not inToat all. Reading
To[0]would have named the group on a group message and asked every
subsequent question about the wrong address.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-