Since macOS Mojave it has been possible to bind to privileged ports without root on macOS. For example running the following shows nc binding to port 81 without issue.
However binding to a port on a specific interface still requires root.
This makes binding a process to a single interface like a WireGuard network or localhost impossible without root permissions.
It’s possible to work around the above restriction by using launchd socket activation instead. Instead of having a process bind to ports itself, launchd will bind to those ports and pass those file descriptors to the process. For example I have the following plist to run Python’s HTTPServer module listening on localhost only.
The key part of this plist is the Sockets key which specifies the interface and port for launchd to bind to.
Then in the program being run it needs to receive the socket from launchd by calling the launch_activate_socket API. Once the sockets are obtained they can be used like any other socket. For example my startpage.py script looks like this.
Once the plist above is placed into ~/Library/LaunchAgents it works like any other launch agent. When activated the process will be listening on the specific interface and port but no root permissions were required.