Reference
Verification and results
Verification is stateless and O(1) per connection, with no verifier-initiated fetch to attacker-named endpoints beyond DNS.
Result values
| Result | Cause |
|---|---|
pass | All verification checks passed. |
none | No v=SWORN1 record, NXDOMAIN, an unimplemented k=, or — in Mode 1 — no confirming operator found. |
fail | Signature failure, off-prefix, expired, or not yet valid. |
permerror | Malformed token or record, bad headers, non-canonical or out-of-range prefix, ineligible source, bad unit, bad validity (exp <= iat), lifetime over cap, bad role, non-conforming kid or operator domain, missing required key, duplicate key, crit present, or untagged COSE. |
temperror | DNS timeout or SERVFAIL, or — in Mode 1 — the discovery query budget exhausted. |
Results are reported in an Authentication-Results field. The policy.mode property is dns for Mode 1 and token for Mode 2.
Authentication-Results: mx.example.net;
sworn=pass policy.op=mailer.example.comReputation semantics
These are the rules that make the protocol safe to deploy. They are the part most likely to be got wrong by an implementer optimising for the obvious.
On pass
Key reputation on the tuple (operator domain, containing unit prefix). Abusive traffic from an attested prefix should affect the reputation of that entire attested prefix, and may affect the operator domain across all of its attested prefixes. That is the point: the prefix, not the address, is the accountable thing.
On fail, temperror and permerror
A failed verification identifies no accountable party. Receivers and reputation services must not attribute a failed result to the operator domain named in the token. Anyone can put any domain in a token they made up; treating a failure as evidence against that domain would make SwornMail a weapon against the operators it exists to serve.
None of these results may be treated as worse than none for reputation or delivery. Absence of attestation must not worsen treatment relative to the receiver’s existing unattested-IPv6 policy. This is design goal 1 — fail-open — and it is what makes deploying SwornMail risk-free for a sender and safe for a receiver to enable.
Why temperror is not none
A DNS timeout means the question was not answered, not that the answer was “no attestation”. Collapsing the two would let anyone who can disrupt DNS erase an operator’s standing. Implementations must keep them distinct, and reputation services must not record a temporary failure as an absence.
The trust boundary
An inbound sworn= result is trivially spoofable — it is just a header field. Per RFC 8601 §5, an ADMD border MTA must delete or rename any pre-existing Authentication-Results field claiming its own authserv-id. A result must not survive the trust boundary unexamined.
The reference Postfix milter strips inbound AR fields at the boundary for exactly this reason.
Mode 1: DNS-only discovery
The receiver has a connecting address and needs to find who, if anyone, is accountable for it.
- Look for a reverse-tree pointer naming an operator domain. Failing that, take the connecting host’s forward-confirmed PTR.
- Fetch that operator’s policy record.
- Confirm the connecting address falls inside one of the prefixes the operator actually attested. This containment check is the whole anti-squatting mechanism — a claim is worth nothing without it.
Discovery runs under a hard query budget. Exhausting it yields temperror, never none — an attacker must not be able to convert “expensive to answer” into “not attested”.
Mode 2: signed token
A compact COSE_Sign1 token presented over an SMTP extension, verified statelessly at connection time. All checks must pass for sworn=pass: the token is well-formed and tagged, the signature verifies against the key named by kid under the operator domain, the validity window is sane and within the lifetime cap, and the connecting address falls inside the attested prefix.
A stolen key alone buys nothing. The attestation is bound to the address space it was issued for, so a captured token replayed from anywhere else produces sworn=fail. Key compromise on its own must not enable off-prefix impersonation — that is design goal 4.
The algorithm comes from the key record’s k= tag, not from the token: a verifier must take the expected algorithm from the record and reject a token that disagrees, rather than letting the token choose how it is checked.