The problem was that WordPress Rest API was not getting the HTTP basic auth information in the request. In this RunCloud setup there is first Nginx, which proxies to Apache, which proxies to FastCGI, which runs PHP ( I suppose the only reason Apache is there is to support .htaccess files).
First I suspected Nginx, because I’ve recently had issues with Nginx not always forwarding request headers to upstream host. I added
proxy_pass_request_headers on there, but it made no difference.
I created a test script that prints out the Authorization header, and indeed it was not getting all the way to PHP. Some other headers, like User-Agent were getting through.
I checked the Apache access logs, and the username was not getting printed there, so I thought that Apache is not getting the header. I tried making the request directly to Apache, bypassing Nginx, but my test script still wasn’t getting the header. That lead me to suspect either Apache or PHP.
Finally I managed to find a Stack Overflow answer that lead me to the solution. I added
CGIPassAuth On to .htaccess and bingo! Problem solved.