There may well be situations where I trust particular code C to access X if it cannot access y and also to access Y if it cannot access x. The point is that objects, not code need to be authorized to access data and other objects.
In the case above the following situation is perfectly safe. Object Cx has access to both X and x while object Cy has access to Y and y. Both Cx and Cy obey the code C. Code C need not be trusted not to separate X from Y.
Notice that Java, with its static variables that are shared between instances of the same class, cannot provide this separation short of examining the code (or byte code) for references to such shared variables. Notice too that programming languages can at best deliver across trust boundaries functions and that the these functions are not manifestly free of side effects. There is not a general way for the recipient to know whether the function is in a position to abscond with the secrets within arguments to that function.
There is hope, however. Scheme's R5RS clarifies the semantics of eval to make it clear that the invoker of eval can be assured that the resulting value will have no ability to cause side-effects beyond those provided by the environ argument to eval. The first argument to eval need not be vetted to insure this. Java's class loader may be analogous to eval in this respect but I have not been able to learn enough about it to convince myself.
The Keykos factory goes further and provides a double blind facility where the user of a functionality is assured of lack of side-effects at the same time that the provider of the functionality retains proprietary control over the code that implements the functionality.
I think that programming languages have generally not reified constructs such as pure code except perhaps in Scheme's eval and Java's class loader. As far as I know some such primitive function is necessary to provide the separation required here. Other primitive functions have been proposed but not implemented, I think.