Skip to content

Latest commit

 

History

History
399 lines (269 loc) · 14.9 KB

File metadata and controls

399 lines (269 loc) · 14.9 KB

TFEP — Trust-First Email Protocol

Version 1.0 — Draft Specification


1. Introduction

The Trust-First Email Protocol (TFEP) is a backward-compatible extension to the existing SMTP email infrastructure. It addresses the fundamental trust gaps of SMTP — sender identity spoofing, spam, phishing, and the lack of verifiable authorization for different categories of mail — without requiring the replacement of existing infrastructure.

TFEP operates as a dual-stack overlay: TFEP-capable gateways speak both TFEP and SMTP, translating between the two and preserving trust proofs across protocol boundaries.

1.1 Goals

  • Cryptographically verifiable sender identity
  • Protocol-level spam prevention through declared message intent + cryptographic permits
  • Phishing prevention through undeniable sender DID verification
  • Native end-to-end encryption (optional, graceful fallback)
  • Full backward compatibility with SMTP; no flag-day migration

1.2 Non-Goals

  • Replacing SMTP for all traffic immediately
  • Centralized identity registry or blockchain dependency
  • Content filtering (TFEP prevents identity fraud, not content-based deception)

2. Identity Model

2.1 Sender Identity

Every TFEP sender is identified by a DID (Decentralized Identifier) anchored to a domain:

did:web:example.com

The DID document is published at:

https://example.com/.well-known/did.json

The DID document MUST contain at minimum:

  • One Ed25519VerificationKey2020 verification method (for message signing)
  • One X25519KeyAgreementKey2020 key agreement method (for encryption)

2.2 DNS Capability Advertisement

Domains publish TFEP capability via a DNS TXT record:

_tfep.example.com TXT "v=TFEP1; did=did:web:example.com; policy=bridge; pow=0; caps=v1,enc,pow"
Field Required Description
v Yes Protocol version (TFEP1)
did Yes The domain's DID
policy No bridge (default) or strict
pow No Required proof-of-work difficulty (0 = disabled)
caps No Comma-separated feature tags: v1, enc, pow

2.3 Key Rotation

When rotating keys, the old key MUST be marked "revoked": true in the DID document OR removed. New keys SHOULD include a notBefore timestamp. Gateways MUST NOT verify signatures using revoked keys.


3. Message Format

TFEP messages are transported as standard MIME multipart emails with additional parts.

3.1 MIME Structure

Content-Type: multipart/mixed
├── text/plain                  Human-readable fallback (required)
├── application/tfep+json       TFEP envelope (required)
└── application/tfep-proof      Base64-encoded Ed25519 signature (required)

The X-TFEP-Proof header MUST also be set to the base64url-encoded signature for quick gateway validation without full MIME parsing.

3.2 Envelope Schema

{
  "version": "1",
  "message_id": "<uuid-v4-or-v7>",
  "thread_id":  "<uuid-v4-or-v7>",
  "message_type": "<see §4>",
  "sender_did": "did:web:sender.example",
  "recipient_did": "did:web:recipient.example",
  "recipients": [],
  "timestamp": "2025-01-01T12:00:00Z",
  "subject": "Hello",
  "body_hash": "<hex SHA-256 of plaintext body>",
  "permit_token": "<JWT or omitted>",
  "pow_proof": "<hashcash string or omitted>",
  "encrypted": false,
  "encryption_ephemeral_key": "<base64url X25519 pubkey or omitted>",
  "bounced_message_id": "<omitted unless type=bounce>",
  "bounce_reason": "<omitted unless type=bounce>",
  "bounce_code": 0,
  "recipient_caps": ["v1", "enc"]
}

3.3 Canonical Signature Input

The envelope is canonically serialized to JSON (with pow_proof zeroed out) and the Ed25519 signature is computed over its SHA-256 hash.


4. Message Types

Senders MUST declare a message_type. Gateways enforce authorization rules based on this declaration.

Type Description Authorization Required
personal Human-to-human message Permit OR verified contact
transactional Business → customer (receipts, notifications) Relationship token
marketing Newsletter, promotional Opt-in permit issued by recipient
automated System alert, notification Same as transactional
receipt Delivery acknowledgment None (sent by gateway)
bounce NDR / permanent failure None (sent by gateway)

Marketing enforcement: A marketing message without a valid opt-in permit MUST be rejected with SMTP code 554 at the gateway level. This is a protocol-level rejection, not a spam filter decision.


5. Trust Tiers

Inbound messages are assigned a trust tier by the receiving gateway:

Tier Condition
verified Valid TFEP DNS record + valid DID document + valid Ed25519 signature
identified DKIM/SPF/DMARC pass but no TFEP
unknown No verifiable authentication
blocked Local or federated blocklist match

Tier determines default inbox routing. Recipients may configure custom routing rules.


6. Permission Tokens (Send Permits)

A send permit is a short-lived Ed25519-signed JWT issued by a recipient granting a specific sender inbox access.

6.1 Permit JWT Claims

{
  "iss": "did:web:recipient.example",
  "sub": "did:web:sender.example",
  "aud": ["tfep:permit:v1"],
  "iat": 1700000000,
  "exp": 1731536000,
  "iss_did": "did:web:recipient.example",
  "grantee_did": "did:web:sender.example"
}

Signed with the issuer's Ed25519 private key.

6.2 Permit Exchange

Senders may request a permit via the recipient's well-known endpoint:

POST https://recipient.example/.well-known/tfep/permit-request
Content-Type: application/json

{"sender_did": "did:web:sender.example", "message_type": "transactional"}

Response: 201 with {"permit_token": "..."} (auto-approved) or 202 with {"request_id": "..."} (pending review).

6.3 Unsubscribe

Recipients may withdraw a permit:

POST https://recipient.example/.well-known/tfep/unsubscribe
Content-Type: application/json

{"permit_token": "...", "sender_did": "did:web:newsletter.example"}

7. End-to-End Encryption

When both sender and recipient have published X25519 keys in their DID documents, TFEP messages SHOULD be encrypted.

7.1 Single-Recipient Encryption

  1. Sender generates an ephemeral X25519 keypair
  2. ECDH shared secret = X25519(sender_ephemeral_private, recipient_X25519_public)
  3. Body is encrypted with NaCl secretbox using the shared secret
  4. envelope.encrypted = true
  5. envelope.encryption_ephemeral_key = base64url of the ephemeral public key
  6. Encrypted body replaces plaintext body in the MIME structure

The text/plain fallback part MUST contain a human-readable notice that the message is encrypted.

7.2 Multi-Recipient Encryption

For messages to multiple recipients:

  1. Generate a random 32-byte content key (AES-256)
  2. Encrypt body with content key
  3. For each recipient: ECDH-wrap the content key with their X25519 public key
  4. Each recipient's wrapped key is stored in envelope.recipients[].wrapped_content_key

8. Proof-of-Work

Recipient domains may require a computational proof-of-work from senders without a valid permit.

The PoW format is Hashcash-style over:

v=1;bits=<n>;resource=<senderDID>+<recipientDID>;ts=<unix>;nonce=<n>

Valid PoW: SHA-256(token) has at least n leading zero bits.

Senders with valid permits are exempt from PoW requirements.


9. Anti-Phishing Enforcement

Receiving gateways MUST enforce:

  1. Signature validation: Invalid or missing signature → SMTP 550 reject
  2. Display-name mismatch: If the RFC 5322 From display name contains a known brand string that does not match the verified sender_did domain → downgrade to unknown tier + attach X-TFEP-Spoof-Warning: display-name-mismatch header
  3. Transactional relationship check: transactional messages without a relationship token → downgrade to unknown tier
  4. Marketing permit enforcement: marketing without valid permit → SMTP 554 reject
  5. Replay prevention: Messages with timestamp older than max_message_age (default 5 minutes) → SMTP 550 reject

10. Reputation Tokens (SMTP Bootstrap)

When a TFEP sender delivers to an SMTP-only recipient, the sending gateway issues a reputation token (signed JWT) as a receipt. When the SMTP recipient later adopts TFEP, they may present historical tokens to bootstrap their trust score.

Tokens decay over time using an exponential decay function with a configurable half-life.


11. Federated Reputation

Gateways MAY query a community-maintained DNS reputation zone:

_tfep-rep.<senderDomain>.<resolver> TXT "score=0.8;reports=42"
  • score: float [0.0, 1.0]. Values < 0.3 indicate community-flagged bad actor.
  • reports: integer report count.

Federated reputation is a secondary signal. Local trust decisions (permits, tiers) take precedence.


12. Protocol Version Negotiation (C4)

The _tfep DNS record includes a caps= field advertising supported features. Senders SHOULD check recipient caps before sending.

Cap Tag Meaning
v1 TFEP version 1 supported
enc X25519 encryption supported
pow Proof-of-work supported

If the sender uses a feature not in the recipient's caps, it SHOULD gracefully omit that feature.


13. Gateway REST API

TFEP gateways SHOULD expose an authenticated REST API for administrative access. See the implementation for the full OpenAPI-compatible endpoint list.

Authentication: Authorization: Bearer <api_key> header.


14. Security Considerations

  • Key compromise: Rotate keys immediately using tfep-gateway rotate-key. The old key should be marked "revoked": true in the DID document.
  • DNS spoofing: Enable DNSSEC validation (identity.require_dnssec: true) in high-security environments. The AD bit in DNS responses is checked.
  • Replay attacks: Gateways enforce a max_message_age window (default 5 minutes) and a clock_skew tolerance (default 1 minute).
  • Rate limiting: Token bucket limits per IP (connections/minute) and per sender DID (messages/hour) are enforced.
  • Key storage: Private keys SHOULD be stored passphrase-encrypted. The keystore uses AES-256-GCM with PBKDF2-SHA256 (100,000 iterations).

15. Migration Path

TFEP is designed for incremental adoption following the STARTTLS precedent:

Phase Description
0: Opt-in Early adopters install TFEP gateways; SMTP users receive normal email with embedded proof
1: Hybrid Major providers add TFEP support; DNS capability records proliferate
2: Reputation Cross-protocol reputation tokens become standard; pure-SMTP spam increasingly quarantined
3: Default New accounts default to TFEP; SMTP is a legacy compatibility mode

16. Domain Registry

The TFEP Domain Registry is an optional extension that provides a human-readable namespace for TFEP identities. Registry operators serve the .tpt top-level domain (or any configured TLD) as an authoritative DNS zone.

16.1 Purpose

DIDs (did:web:example.com) are cryptographically verifiable but not human-memorable. The registry maps short names (alice) to DIDs, enabling email addresses like alice@alice.tpt that are both recognizable and cryptographically rooted.

16.2 Name Rules

  • Format: ^[a-z0-9][a-z0-9-]{0,62}$ — lowercase alphanumeric + hyphens, starting with a letter or digit.
  • Registration: One-time, no renewals. First-come, first-served.
  • TLD: Configured per deployment; the reference TLD is .tpt.

16.3 DNS Bridge

The DNS bridge runs alongside the gateway and serves synthetic DNS records for registered names:

Query Response
TXT alice.tpt v=TFEP1; did=<did>; policy=bridge; caps=v1,enc
TXT _tfep.alice.tpt Same as above (capability lookup format)
A alice.tpt Configured gateway_ip (IPv4)
AAAA alice.tpt Configured gateway_ipv6 (IPv6)
SOA tpt. Zone SOA record
NS tpt. Configured nameserver hostname
Unregistered name NXDOMAIN + SOA in authority
Non-registry query Forwarded to upstream resolver (default 1.1.1.1:53)

The bridge also supports DNS-over-TLS (DoT) on a configurable port (default :853), using the gateway's TLS certificate.

16.4 Registration Flow

Client                Registry API             DNS Bridge
  |                       |                        |
  |-- POST /register ---→ |                        |
  |   { name, did,        |                        |
  |     owner_pubkey,     |-- INSERT registry_domains
  |     fee_tx }          |                        |
  |←-- 201 { record } --- |                        |
  |                       |                        |
  |-- Deploy DID doc -------------------------→ (HTTPS at did:web endpoint)
  |                       |                        |
  |-- Query TXT alice.tpt --------------------→ |
  |←-- v=TFEP1; did=... ---------------------  |

16.5 Ownership Transfer

Transfers are cryptographically verified. The current owner signs:

transfer:<name>:<new_did>:<new_owner_pubkey>:<unix_timestamp>

with their Ed25519 private key. The registry verifies the signature against the stored owner_pubkey before updating the record and appending a registry_transfers audit entry.

16.6 Dormant Names

A name is marked dormant: true if no valid DID document is found at https://<name>.<tld>/.well-known/did.json after registry.dormant_days days (default 90). Dormant names remain registered and are not available for re-registration.

16.7 Metadata

Owners may attach arbitrary JSON metadata to their name (bio, URL, avatar, etc.) by signing:

metadata:<name>:<sha256-hex-of-metadata-json>

Metadata is stored in the registry and returned in resolution responses. It is public and unverified by the protocol — treat it as self-asserted.

16.8 Public Profile Pages

Gateways with the registry enabled serve human-readable HTML profile pages at /p/<name>, showing the name's DID, pubkey, registration date, metadata, and transfer history. These pages are suitable for linking in email footers or social profiles.

16.9 Security Considerations

  • Name squatting: The registry is first-come, first-served. Deployments MAY add fee validation or manual review to deter squatting.
  • Key loss: There is no key recovery mechanism. Lost owner keys mean the name cannot be transferred. Recommend keeping key backups.
  • DNS hijacking: The DNS bridge is not a replacement for DNSSEC. Clients SHOULD validate DNSSEC where available. Registry names are additionally protected by the DID document's cryptographic binding.
  • Fee proof replay: Fee transaction proofs (fee_tx) SHOULD be single-use. Implementations MUST track redeemed proofs to prevent double-registration.

This specification is a living document. Implementations should track the version field in the DNS TXT record.