Files
openmail/docs/adr/0005-oracle-cloud.md
T
Karti TripathiandClaude Opus 5 36b15ddcaf Rewrite as a Rust, Apache-2.0 workspace
Supersedes the Go + embed-Mox design. The Go tree is removed; its
architecture doc is preserved at docs/archive/ARCHITECTURE-go-embed-mox.md
because its competitive analysis and data model still hold.

Five decisions recorded as ADRs:

  0001  Rust, not Go — accepting ~5,500 lines of protocol code that Mox
        would have given us free, to get the first permissively licensed
        Rust mail server. Costs stated plainly.
  0002  Apache-2.0, not MIT or AGPL — patent grant, trademark, CLA-free
        contribution. Public on GitHub; Gitea stays as the private fallback.
  0003  Stalwart's primitive crates (Apache-2.0/MIT) yes; its AGPL server
        crates never. DANE and MTA-STS sit on the AGPL side of that line,
        which is why we write our own.
  0004  Milestones, reordered: embedded inbound is required at launch.
  0005  Oracle Cloud blocks outbound :25, so direct-to-MX is impossible on
        the launch host. Split delivery is mandatory, not an on-ramp.

Twelve crates in three tiers. Tier 1 (mail-dane, mail-mta-sts, mail-dsn)
is standalone and publishable — no `dane` or `mta-sts` crate exists on
crates.io at all today.

openmail-relay ships the provider table as data, with SES and Oracle from
the start. Oracle's and Resend's SPF includes are deliberately None: a
guessed include turns the DNS check green against a mechanism the provider
does not honour, and mail still fails SPF silently.

cargo check/test/clippy/fmt all green; unsafe_code is forbidden workspace
wide; cargo-deny enforces the licence policy in CI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JkyvfNJGTshJNE9FtwPLk7
2026-09-02 13:08:05 -07:00

1.8 KiB

ADR 0005 — Oracle Cloud as the launch host, and what it forbids

Status: Accepted, 2026-09-02.

The constraint

OCI blocks outbound TCP/25 for every tenancy created after 2021-06-23. Exemption is a service-limit request, routinely refused for free tier. Inbound :25 is not blocked.

On OCI
Receive on :25 works — openmail-smtpd is fine
Relay out on 587 works (verify: see below)
Direct-to-MX impossible. mail-dane and mail-mta-sts can never run there

Decision

Launch on OCI in split delivery: receive directly, relay outbound. Support Oracle Cloud Email Delivery and SES as relay providers from day one — two providers at launch forces the provider abstraction to be genuinely data-driven instead of an SES-shaped if.

Direct-to-MX (v0.4) is developed and tested on a host without the block.

Consequences

  • Embedded inbound moves from "milestone 4, later" to required at launch.
  • The relay path is not a temporary on-ramp; on our own launch host it is the only outbound path that exists.
  • Oracle's SPF include is region-scoped (rp / eu.rp / ap.rp .oracleemaildelivery.com), so providers.rs deliberately stores None and makes the operator paste theirs. A guessed include turns the DNS check green against a mechanism the provider does not honour and mail still fails SPF — silently. Same for Resend.

⚠️ Open — verify before committing to the host

Oracle's docs name only port 25. Mailcow community reports claim 587 and 2525 are also blocked outbound on free tier, which would make OCI unable to relay either, and would change the host choice entirely.

Test on a free instance before building on this. It is a 20-minute check and it invalidates this ADR if the reports are right.