Open Attachment Gateway

Govern how files leave your organization by email.

Attachra is a self-hosted policy engine for outbound email attachments. It is not a mail server — it sits next to Postfix and handles what your MTA and your spam/AV stack don't.

v0.2.2·AGPL-3.0·single static binary·amd64 + arm64

Rspamd solved it for spam. ClamAV solved it for viruses.
Attachra solves it for attachments.

The problem

An unsolved governance gap

If you run your own mail infrastructure (Postfix, Mailcow, iRedMail, grommunio…), outbound attachments are an unsolved governance gap:

No control over what leaves

Anyone can attach anything to anyone — any size, any sensitivity. There is no policy layer between “user hits send” and “file is gone.”

Large attachments break email

You either reject them at the MTA, or let people paste links to cloud-drive shares you don't manage and can't audit.

No revocation

Once an attachment is sent, it's sent. Shared by mistake, employee left, recipient mailbox compromised — there is nothing you can do.

No audit trail

Who sent what, to whom, when, and who downloaded it — answering that today means grepping mail logs, if you log bodies at all (you shouldn't).

SaaS DLP products “solve” this by routing your mail through a third party. If you self-host your mail specifically to avoid that, they aren't an option.

How it works

A milter, a policy engine, your storage

Attachra intercepts outbound mail via a Postfix milter, evaluates each attachment against your policies, and — where policy says so — replaces the attachment with a link to a file held in your own S3-compatible storage. The recipient gets a normal-looking email with a download link instead of a payload. You get a policy engine, an audit trail, and the ability to revoke access after the fact.

The core policy, storage, link and audit logic knows nothing about Postfix — other mail transports (SMTP proxy, Exim, Stalwart…) can be added as adapters without touching the core.

REST API

Sent by mistake? Revoke it.

Everything the CLI does goes through the same documented REST API — scriptable from your existing tooling. One call, and the recipient's download link is dead:

Request

LINK=9f3a1c2e8b4d6f01a7c5e392d84b6f10

curl -s -X POST \
  -H "Authorization: Bearer $ATTACHRA_TOKEN" \
  http://127.0.0.1:18080/api/v1/links/$LINK/revoke

Response

{
  "id": "9f3a1c2e8b4d6f01a7c5e392d84b6f10",
  "message_id": "b41d0aa8c3f2e967",
  "attachment_id": "5c77d2091b3e4af8",
  "recipient": "partner@example.net",
  "expires_at": "2026-08-14T09:12:44Z",
  "max_downloads": 3,
  "downloads": 1,
  "status": "revoked",
  "hold": false,
  "created_at": "2026-07-15T09:12:44Z"
}

Bearer-token auth with three roles (admin / viewer / auditor), deny by default. The API listens on localhost — it is never exposed to the internet. The full surface is described by openapi.yaml — the spec is the source of truth, linted in CI.

Features

Built for people who run their own mail

Declarative policy engine

Match on sender, recipient, size, type and more. Hot reload and a dry-run mode: decisions are logged, no mail is modified until you flip the switch.

Revocable download links

Per-recipient signed links with TTL and download limits. Revoke a file after sending — or place it under legal hold.

Your storage, not ours

S3-compatible backends (AWS S3, MinIO, Ceph) or plain local filesystem. Files never leave your infrastructure.

Audit trail

Tamper-evident log of who sent and who downloaded what, and when — with streaming export.

REST API + CLI

Manage policies, links, tokens and stats via the API (admin / viewer / auditor roles) or the attachractl CLI.

Built for operators

Prometheus metrics, health endpoints, structured logs, systemd-hardened Debian package.

Mail is never lost

Every failure resolves to a configured decision: fail-open (deliver unmodified) or fail-closed (tempfail). Your call, per policy.

Single static binary

One cross-compiled binary for linux amd64 and arm64. No runtime dependencies. SQLite out of the box.

Quickstart

Two ways in

Debian package (real host)

curl -fsSL https://attachra.org/install | sudo bash
sudo attachra setup   # interactive wizard, recommends dry-run
sudo postconf -e 'smtpd_milters = <existing milters>, inet:127.0.0.1:6785'
sudo systemctl start attachra

The installer only downloads the signed release .deb, verifies checksums and runs apt — read it first. Prefer doing it by hand? Grab the .deb from GitHub Releases. Works alongside your existing milter chain (rspamd first).

Docker Compose (try it locally)

git clone https://github.com/302-digital/attachra
cd attachra/deploy/dev
docker compose up --build

Brings up Postfix, MinIO and Attachra wired together with a “replace everything” dev policy. A prebuilt multi-arch image is also published as ghcr.io/302-digital/attachra.

Full quickstart and grommunio walk-through in the README →

Where the project is

v0.2.2 is released. The full pipeline — milter → MIME parsing → policy engine → storage → personal download link → MIME rewrite → audit trail — works end to end and has been tested in production on a live grommunio (Postfix-based) mail deployment. Release artifacts are signed (Sigstore keyless). This release adds tamper-evident audit verification (attachra audit verify), audit-log retention with legal-hold guarantees, and a binary attachment integrity fix on the milter path. It's usable today, at your own risk: config, policy-file and API formats may still change before v1.0.0, where format stability becomes guaranteed (SemVer).

Changelog  ·  Roadmap

Self-hosting your mail? Take control of what leaves it.

View on GitHub