Every master download goes through digitalobject/viewAction, which does QubitAcl::check($obj, 'readMaster') → forward404() if denied, then serves the file via nginx X-Accel-Redirect to an internal /private/… location. So an anonymous user with no readMaster should get a 404 - provided the request goes through the app.
Most likely cause after the migration: the web server is serving the digital-object files statically, so anonymous users fetch the master PDF by its raw /uploads/… URL and skip the ACL check entirely. Classic result of a regenerated nginx config during the upgrade.
The 2-minute test (logged out): does the raw
https://site/uploads/r/…/file.pdf URL download?
- If yes → web server is the problem → fix the nginx config (restore the internal /private/ location and stop serving masters directly).
- If no but the PDF still shows on the page → no reference derivative exists, so the viewer is showing the master itself →
do if No: php symfony digitalobject:regen-derivatives.