Skip to content

Latest commit

 

History

History
121 lines (103 loc) · 8.25 KB

File metadata and controls

121 lines (103 loc) · 8.25 KB

TFEP Gateway — Build Checklist

Phase 1: Core Protocol Library (pkg/tfep/)

  • TFEP envelope schema + JSON serialization (pkg/tfep/envelope.go)
  • Ed25519 signing over canonical SHA-256 of the envelope (pkg/tfep/sign.go)
  • Signature verification (message + public key → bool)
  • X25519 ECDH key exchange + NaCl secretbox encrypt/decrypt (pkg/tfep/crypto.go)
  • Hashcash proof-of-work generator and validator (pkg/tfep/pow.go)
  • Unit tests: sign/verify, encrypt/decrypt, PoW round-trips — 8/8 passing

Phase 2: Identity Layer (internal/identity/)

  • LookupCapability(domain) — parse _tfep DNS TXT record
  • ResolveDID(did) — fetch did:web document, extract Ed25519 + X25519 keys
  • TTL-aware cache for DNS + DID results
  • Unit tests with stubbed DNS/HTTP — 3/3 passing

Phase 3: Permission Token System (internal/trust/permits.go)

  • IssuePermit(issuer, grantee, expiry) → signed JWT
  • ValidatePermit(token, issuerPublicKey) → bool
  • IssueRelationshipToken for transactional senders
  • Auto-issue permit wired in queue release CLI command

Phase 4: SMTP Inbound Server (internal/smtp/server.go)

  • go-smtp backend, configurable port (default 2525)
  • Per-message pipeline: identity lookup → tier → type check → permit check → queue
  • 554 reject for marketing with no opt-in permit
  • X-TFEP-Spoof-Warning + tier downgrade for display-name mismatch
  • Transactional relationship token check → Unknown tier if missing

Phase 5: SMTP Outbound Relay (internal/smtp/client.go)

  • Compute PoW if required
  • Sign envelope, encrypt body (if recipient has X25519 key)
  • Construct MIME with application/tfep+json + application/tfep-proof parts
  • Relay to recipient MX; embed X-TFEP-Proof header

Phase 6: Trust & Reputation Engine (internal/trust/)

  • AssignTier(senderInfo) Tier (internal/trust/tier.go)
  • IssueReputationToken — legacy SMTP→TFEP bootstrap JWT (internal/trust/reputation.go)
  • DecayScore — exponential decay with configurable half-life
  • IsSpoofedDisplayName — brand-name phishing detection
  • MessageTypeRule — enforces permit/relationship-token requirements

Phase 7: SQLite Store (internal/store/store.go)

  • Schema: messages, permits, reputation_tokens tables
  • Migration runner (no ORM)
  • CRUD helpers: Insert/Get/List/Update messages; Upsert/Get/List/Delete permits
  • Thread query via ListMessages(threadID=...)

Phase 8: Gateway Orchestrator (internal/gateway/)

  • Config struct + LoadConfig from config.yaml + env overrides
  • Server.Start() wires SMTP server, identity resolver, store
  • Graceful shutdown on SIGINT/SIGTERM with drain

Phase 9: CLI (cmd/tfep-gateway/main.go)

  • tfep-gateway serve
  • tfep-gateway keygen --domain — generates Ed25519/X25519 keys, DID doc, DNS TXT record
  • tfep-gateway send --to --type --subject --body
  • tfep-gateway queue list [--tier] [--type] [--thread]
  • tfep-gateway queue release <id> — promotes + auto-issues permit
  • tfep-gateway permits list|revoke

Phase 10: Deployment Artifacts

  • Dockerfile — multi-stage, distroless final image
  • docker-compose.yml — single service with volumes
  • tfep-gateway.service — systemd unit with hardening flags
  • config.yaml — annotated defaults

Phase A: Security Hardening

  • A1 TLS/STARTTLS — internal/smtp/server.go (NewServer + NewSubmissionServer), separate MTA port (:25) and submission port (:587), tls.Config from cert+key files
  • A2 Rate limiting — internal/ratelimit/ratelimit.go, token bucket per IP (connections/min) and per sender DID (messages/hour), 1-hour temporary block at 3× burst
  • A3 Replay attack prevention — internal/smtp/server.go process(), rejects messages with timestamp older than trust.max_message_age (default 5m) or too far in the future (trust.clock_skew)
  • A4 Encrypted key storage — internal/keystore/keystore.go, AES-256-GCM + PBKDF2-SHA256, passphrase from CLI flag or TFEP_KEY_PASSPHRASE env var
  • A5 DNSSEC validation — internal/identity/capability.go, checks DNS AD bit, warns if not set, hard-rejects if identity.require_dnssec: true

Phase B: REST API + Web UI

  • B1 REST API — internal/api/server.go, 18 endpoints (messages, permits, contacts, stats, well-known permit/unsubscribe), Bearer token auth
  • B2 Prometheus metrics — internal/metrics/metrics.go, counters for received/rejected messages, queue depth gauges, relay results, cache hits
  • B3 Structured logging — internal/logger/logger.go, log/slog with JSON or text handler, log level from config
  • B4 Minimal web UI — internal/api/static/index.html, vanilla JS SPA, inbox + held queue + permits + contacts, go:embed

Phase C: Protocol Completeness

  • C1 Key rotation — tfep-gateway rotate-key, new keys written to *.new.pem, notBefore timestamp in DID document; identity resolver skips revoked: true and future-dated keys
  • C2 DKIM signing — internal/smtp/client.go dkimSign(), github.com/emersion/go-msgauth/dkim, config fields identity.dkim_selector + identity.dkim_key_file
  • C3 Delivery receipts/NDR — pkg/tfep/envelope.go TypeReceipt/TypeBounce + BouncedMessageID/BounceReason/BounceCode fields; SendBounce() in internal/smtp/client.go
  • C4 Protocol version negotiation — caps= field in _tfep DNS record, parsed into Capability.Caps, set in outbound envelope RecipientCaps; version field in envelope
  • C5 Multi-recipient support — Envelope.Recipients []RecipientEntry with per-recipient EphemeralKey + WrappedContentKey fields

Phase D: Operational

  • D1 Message retention/cleanup — store.DeleteMessagesBefore(), background hourly goroutine in gateway.Server, tfep-gateway store vacuum CLI command, configurable per-tier TTLs
  • D2 Multi-domain config structure — Config expanded to support identities[] list (foundation); keygen and rotate-key output documents ready for multiple domains

Phase E: Ecosystem

  • E1 Federated reputation — internal/trust/federated.go, DNS TXT query _tfep-rep.<domain>.<resolver>, returns score + report count; disabled by default (trust.federated_reputation.enabled: false)
  • E2 Contact book — store.Contact + InsertContact/ListContacts/DeleteContact, contacts SQLite table, REST API endpoints GET/POST/DELETE /api/v1/contacts

Protocol Specification

  • PROTOCOL.md — 15-section formal spec covering identity model, DNS records, envelope schema, message types, trust tiers, permits, encryption, PoW, anti-phishing, reputation, version negotiation, migration path, security considerations

Verification Checklist

  • Unit tests pass: go test ./...11/11 passing
  • go build ./... — clean compile, zero errors
  • Integration: two local gateways exchange personal message (Verified queue, decryptable)
  • Marketing with no permit → 554 rejection
  • Permit issued → marketing reaches Verified queue
  • Anti-phishing: display-name mismatch → X-TFEP-Spoof-Warning + Unknown tier
  • Anti-phishing: transactional with no relationship token → Unknown tier
  • Anti-phishing: forged signature → 550 rejection
  • SMTP → TFEP: plain SMTP injection → Unknown queue
  • TFEP → SMTP: sent message has X-TFEP-Proof header + application/tfep-proof part
  • PoW: gateway rejects messages missing required proof
  • TLS: submission server (:587) requires STARTTLS
  • Rate limit: connection flood → 421 rejection; message flood → 451 rejection
  • Key rotation: rotate-key produces updated DID document with notBefore
  • Encrypted keys: keygen --passphrase → gateway loads with TFEP_KEY_PASSPHRASE
  • REST API: GET /api/v1/messages, POST /api/v1/messages/{id}/release, GET /healthz
  • Web UI: loads at http://localhost:8080/, shows inbox and held queue
  • Retention: store vacuum deletes old messages according to tier TTLs
  • Binary: go build && ./tfep-gateway serve works without Docker
  • Docker: docker compose up runs correctly