I feel a little awkward when answering my question, but I understood the correct solution and consider it correct only to add it here, so it is documented for the future if someone stumbles on this issue.
TL DR :
My custom SecurityManager did not have rights. Since it was in a callstack between the class calling doPrivileged(...) -block and AccessController , privilege intersection was not privilege at all.
Long version
The Java security model works as follows. When the AccessController checks to see if the class is allowed to call the method or not, it looks at the permissions from the top of the call towards the bottom. If each callstack entry has permission, the action is allowed.
Here is an arbitrary example where everything works fine:
+-----------+-------------------+-----------------------+ | Callstack | Class permissions | Permissions in effect | +-----------+-------------------+-----------------------+ | Some | {Read,Write} | {Read} | | Other | {Read} | {Read} | +-----------+-------------------+-----------------------+
Now, in the case of my question, the lower layers in a callstack have no rights at all. Therefore, we get an image like this, where the query at the top, in fact, has no permissions.
+-----------+-------------------+-----------------------+ | Callstack | Class permissions | Permissions in effect | +-----------+-------------------+-----------------------+ | Query | {Read} | {} | | Other | {} | {} | +-----------+-------------------+-----------------------+
This problem occurs when using doPrivileged(...) -block. This allows you to enable stop order search for completion in a record that invokes a privileged action:
+-----------+-------------------+-----------------------+ | Callstack | Class permissions | Permissions in effect | +-----------+-------------------+-----------------------+ | Query | {Read} | {Read} | | Other | {} | {} | +-----------+-------------------+-----------------------+
That's why everything worked fine when I called AccessController.checkPermission(...) from the request. In the end, he had the correct permissions. (Un), fortunately, the Java API (for backward compatibility), always call the SecurityManager . In my case, SecurityManager did not have any privileges. Since it was essentially in a callstack between the request that invoked the privileged call and the AccessController , the net resulting permissions were not:
+-----------------+-------------------+-----------------------+ | Callstack | Class permissions | Permissions in effect | +-----------------+-------------------+-----------------------+ | SecurityManager | {} | {} | | Query | {Read} | {Read} | | Other | {} | {} | +-----------------+-------------------+-----------------------+
Decision
The solution was to give the SecurityManager a basic set of permissions. As a result, the permissions granted by Query were really necessary:
+-----------------+---------------------+-----------------------+ | Callstack | Class permissions | Permissions in effect | +-----------------+---------------------+-----------------------+ | SecurityManager | {Read,Write,Delete} | {Read} | | Query | {Read} | {Read} | | Other | {} | {} | +-----------------+---------------------+-----------------------+
Phew! That was pretty much! Hope this was helpful to someone there :)