Skip to main content
Before it answers 250 to a message, the box reads every attachment and applies a policy on file types (ADR-155). It is a policy, not a malware scanner: there is no signature engine, no database of hashes, and the judgement opens no connection. The public page /postmaster?p=AttachmentPolicy is what a sender whose message was refused reads.

Where it applies

The rules

Every name a part declares is judged, not only the one a mail client shows.

Configuration

A new box starts in observe: a message a rule would refuse is delivered, and a log line plus the counter oximail_attachment_verdicts_total{reason, door, action="would_refuse"} record it. Arm the rules one by one once the counters show what they touch: executables first, archives and macros next, unreadable containers and MIME anomalies last. An unknown rule name or a list entry that is not canonical refuses the boot. A tenant can override attachment_policy.mode and attachment_policy.refuse_encrypted_archives with oximail config set-override. A message to several tenants follows the strictest of them. There are no exceptions per sender.

Checking

  • oximail doctor (check attachment_policy) reports the mode, the per-rule modes, the list version and its SHA-256, and the tenant overrides. A backup MX must carry the same list as its primary: compare the two SHA-256.
  • oximail attachment check --file <path> [--name <name>] or --eml <path> reproduces the box’s verdict on a file or on a message a sender forwarded, with no server and no network. Exit code 0: nothing found; 2: something the policy refuses (--json says whether the box enforces it or only observes); 3: the input could not be read.

What it does not check

  • Malware as such: documents that carry an exploit without macros, and anything that carries a link or a QR code (PDF, HTML, SVG, Office documents).
  • Mail encrypted end to end (S/MIME, OpenPGP), which is delivered unchecked.
  • A second level of archive, and the content of 7z: both are not-inspectable.
Workstations keep their own protection. The trace of a refusal holds the part’s SHA-256, size and type, never its content and never the raw name.