Four screens for open roadmap items, all built from existing components: Inbound > Filter lists (allow / deny, where the maps go) and an adjusted Inbound > Log (client, decision, engine and reason, Allow / Deny sender) for inbound-antispam-panel; Inbound > Quarantine, list and held message with Release beside a danger-zone Discard, for inbound-quarantine; and Server > Preflight, a verdict postmark over a table of checks with a "what to do" column and a test e-mail form, for preflight. A mockup is the target look, not a decision to build: each item keeps its status, and quarantine's open questions stay open - the mockup only assumes answers to them. The paths join the plan's Routes table, the quarantine and preflight plans link their mockups, and the components page maps the quarantine decision to a tag. 33 screens; lint clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
3.3 KiB
Plan: inbound-quarantine
Status: candidate — design TBD; needs explicit agreement before any code
Version: TBD (1.x MINOR if opt-in and backward-compatible; may warrant 2.x
if it changes inbound storage or backup contract).
Goal (draft)
Let the operator hold suspicious inbound mail instead of only accept/reject at the milter — review in the panel, then release to the configured upstream, delete, or add sender to allow/deny lists.
This is a product boundary question, not a settled design. The item exists so we can compare approaches before committing.
Why it is separate from inbound-antispam-panel
inbound-antispam-panel.md covers metadata
(journal + lists). Quarantine implies storing message bodies (or a durable
reference to them) under /data, retention, release workflow, and a wider
attack/backup surface — closer to "mini-mailbox" than pure relay.
Mockup
A target look is drawn — list and detail — in-quarantine, in-quarantine-message — under the design contract of panel-redesign.md. It assumes answers to the questions below (SelfPost holds the mail, release goes to the upstream, 14 days, headers only in the panel); it does not settle them.
Open questions (to decide before a checklist)
- Where mail lives
- SelfPost store under
/data/quarantine/(panel owns lifecycle), or - delegate to rspamd/Redis and panel only proxies release (less storage in SelfPost, tighter rspamd coupling).
- SelfPost store under
- What "release" means
- inject into Postfix as a new delivery to the domain's upstream transport;
- or manual download only (no automatic forward).
- Retention and caps
- max age, max total bytes, per-domain limits; interaction with backup size.
- RBAC
- global admin only vs domain-admin for assigned inbound domains.
- Threat model
- malware in stored MIME, path traversal on extract, quota DoS on busy MX.
- Product fit
- does this violate product.md "no mailboxes" if we only hold spam suspects briefly? Explicit product decision required.
Context (as-built)
- Inbound relay forwards or rejects; no local delivery (architecture.md § Mail path).
- Optional
INBOUND_ANTISPAM_MILTER— external rspamd may quarantine on its own today, without panel integration. - DMARC
p=quarantineis unrelated (outbound policy for receivers).
Likely out of scope (until revisited)
- IMAP/webmail for quarantined mail.
- End-user self-service quarantine (non-admin recipients).
- Outbound quarantine.
Dependencies
- Inbound relay, shipped in
[1.4.0]— as built in architecture.md § Mail path. - Sensible to decide after or alongside inbound-antispam-panel.md (journal/lists), but not blocked on it for design discussion.
Done when (placeholder)
TBD once approach is chosen. Minimum bar would include: opt-in flag, panel list/detail, release or discard action, retention, backup inclusion documented, security review.
Implementation checklist
None yet — expand this plan after the open questions above are answered.