Skip to content

Posthorn

v1.2.0 Feature

This release adds 3 notable features for engineering teams evaluating rollout.

Published 22d Communication & Email
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

docker email email-gateway go self-hosted mail-gateway
+3 more
postmark smtp-relay transactional-email

Affected surfaces

auth

Summary

AI summary

Adds three opt‑in content‑agnostic spam checks: reputation lookup, proof‑of‑browser challenge, and Cloudflare Turnstile captcha.

Full changelog

Spam-protection minor. Adds three content-agnostic checks that target automated contact-form spam — the kind that fills valid-looking fields, varies its wording and language, and reuses throwaway sender addresses, so there's no content signature to match. All are opt-in, form-mode only, and backwards-compatible; existing configs are unaffected.

Added

  • Reputation check (#44). Optional [endpoints.reputation] — a StopForumSpam lookup on the submitter email and/or IP before send, blocking known form-spam identities regardless of message content or language. Bounded LRU result cache; fails open by default so a provider outage never blocks real mail (fail-open events increment posthorn_check_failed_open_total{check="reputation"}). Sends email+IP to a third party — opt-in.
  • Proof-of-browser check (#45, ADR-18). Optional [endpoints.proof_of_browser] — Posthorn serves a challenge token from a GET on the endpoint that only page JavaScript can fetch and inject as _pob_token, blocking bots that POST the form directly. An optional min_age time-trap rejects impossibly-fast submissions. No third party; works on static sites.
  • Captcha check (#33). Optional [endpoints.captcha] — Cloudflare Turnstile verification, the escalation tier for bots that render a real browser. Byte-identical silent 200 on a rejected token; fails closed by default on a provider outage.
  • New posthorn_check_failed_open_total{endpoint,check} metric and spam_blocked kinds reputation / proof_of_browser / captcha.

Changed

  • The three spam checks (origin, honeypot, CSRF) were refactored into a two-phase pipeline (#60): header checks pre-parse, form checks post-parse, each producing a spam.Verdict the handler renders through one mapping. No behavior change — the extraction is what let the three new checks land as small additions rather than more inline blocks.

Fixed

  • The SMTP ingress was constructed with a nil metrics recorder, so posthorn_submissions_sent_total{endpoint="smtp_listener"} and its failure counter never emitted. The registry and recorder are now shared with the HTTP mux, and the real send latency is recorded (was hardcoded 0). (#57)
  • posthorn validate now builds the SMTP ingress, so a listener config with a semantic error (e.g. require_tls with no tls_cert) is caught at validate time instead of failing at boot. (#58)

Recipes

  • Added Authentik and Mastodon SMTP-listener recipes to the docs site.

Image: ghcr.io/craigmccaskill/posthorn:1.2.0 (multi-arch, cosign-signed, SBOM + provenance attested). Validated via v1.2.0-rc.1 before GA.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track Posthorn

Get notified when new releases ship.

Sign up free

About Posthorn

All releases →

Related context

Related tools

Beta — feedback welcome: [email protected]