> What should happen technically is that Postfix connects to the milter, > the milter uses spamc to communicate with SpamAssassin/spamd, and > finally the milter will add the new headers it receives from > SpamAssassin.
To expand a little bit on this, the crucial thing is that all components can communicate properly via sockets. That is, for every component you must configure where it can reach the next component. And make sure user/permissions match, too. My setup on Ubuntu 20.04 looks something like this: Postfix ⇅ SpamAssassin Milter (https://crates.io/crates/spamassassin-milter) /var/spool/postfix/spamassassin/spamassassin-milter.sock ⇅ spamc spamd (SpamAssassin) /run/spamassassin/spamd.sock