You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-dev@jackrabbit.apache.org by Lukas Eder <lu...@gmail.com> on 2013/03/25 16:09:33 UTC

"Secure realm" of internal APIs to prevent costly access control lookups

Hello,

I'm currently looking into extending Jackrabbit's (not OAK's) access
control management, and I found it easy to see how this area is a
significant performance bottleneck for today's Jackrabbit Content
Repository.

The biggest design and architecture problem, in my opinion, is the
need for a session with associated, hard-coded access control
behaviour. From what I understand so far, there are (possibly
non-exhaustive):

- System sessions
- Admin sessions
- User sessions

In my opinion, in OAK, there should be something like a "secure
realm". Once this realm is entered, executing code should get complete
access to all of the repository through standard internal and external
API. For example, such behaviour could be achieved through setting a
ThreadLocal "monitor" in a local execution context as such:

    // Outside of the "secure realm". JCR access goes through access control
    T result = secure(new Securable<T>() {
        public T run() {
            // Inside of the "secure realm". JCR access
            // would now bypass access control
        }
    });

And this could be the implementation of secure():

    private static final ThreadLocal<Boolean> t = new ThreadLocal<Boolean>();

    // OAK internals could use this to check if access control is needed
    public static boolean isSecured() {
        return t.get() != null;
    }

    public static <T> T secure(Securable<T> s) {
        // Already secured
        if (isSecured()) {
            return s.run();
        }
        else {
            try {
                t.set(true);
                return s.run();
            }
            finally {
                t.remove();
            }
        }
    }

Such use of ThreadLocal is smelly and potentially slow, of course.
This is just to illustrate the idea. More realistic use-cases would
probably expose a shareable system session within the "secure realm".
The important thing is that this system session would also bypass
access control.

Are there any such plans in OAK?

Cheers
Lukas

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Lukas Eder <lu...@gmail.com>.
Hello Angela,

2013/3/26 Angela Schreiber <an...@adobe.com>:
> hi lukas
>
> (moving discussion back to the regular jackrabbit dev list)

Thanks, you're right. Further discussions might be off-topic for oak.

>>> consequently we no longer have the need for (shared) system session.
>>> btw: in jackrabbit-core system sessions already bypasses all kind
>>> of access control evaluation.
>>
>> That's what I would've expected. However, this bypass is implemented
>> explicitly in AccessControlProvider implementations.
>
> that's is not correct.
> i don't know what you are doing but solely configuring the
> custom ac provider in the workspace configuration should be
> sufficient to get the setup right...

I may have been mixing up the various actors that are involved in
access control lookups. Ultimately, however,
AccessControlProvider.compilePermissions() is called, regardless if in
the context of a system/admin session or a regular one. A sample
implementation from the Jackrabbit core:

    public CompiledPermissions compilePermissions(Set<Principal>
principals) throws RepositoryException {
        checkInitialized();
        if (isAdminOrSystem(principals)) {
            return getAdminPermissions();
        } else if (isReadOnly(principals)) {
            return getReadOnlyPermissions();
        } else {
            return new CompiledPermissionsImpl(principals, session,
entryCollector, this, true);
        }
    }

This is what I mean by saying that the relevant bypass for
system/admin sessions is implemented explicitly in
AccessControlProvider implementations.

And it is easy to see how I can get it wrong, if I don't re-implement
the above in my own implementation :-)

> please note that the ac provider interface is *not* part
> of the public jackrabbit API but an internal interface which
> is not meant to be accessed by JCR API consumers.

I know. But my current requirements are quite complex, and as you
remember from our discussion, the ideal way to implement the
additional access control mechanisms is by using Jackrabbit's
internals.

Cheers
Lukas

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Angela Schreiber <an...@adobe.com>.
hi lukas

(moving discussion back to the regular jackrabbit dev list)

>> consequently we no longer have the need for (shared) system session.
>> btw: in jackrabbit-core system sessions already bypasses all kind
>> of access control evaluation.
>
> That's what I would've expected. However, this bypass is implemented
> explicitly in AccessControlProvider implementations.

that's is not correct.
i don't know what you are doing but solely configuring the
custom ac provider in the workspace configuration should be
sufficient to get the setup right...

please note that the ac provider interface is *not* part
of the public jackrabbit API but an internal interface which
is not meant to be accessed by JCR API consumers.

regards
angela

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Lukas Eder <lu...@gmail.com>.
Hi Angela,

> in contrast to jr-core access control mgt and permission evaluation
> will not be built on top of the JCR stack but be located below the
> new "SPI" boundary inside oak-core.

So, in essence, there are means of accessing the OAK-internal
repository representation through this SPI explicitly. It will be
low-level, but it will allow for bypassing access control. That's what
you're saying?

> consequently we no longer have the need for (shared) system session.
> btw: in jackrabbit-core system sessions already bypasses all kind
> of access control evaluation.

That's what I would've expected. However, this bypass is implemented
explicitly in AccessControlProvider implementations. I had missed this
fact at first, when I was implementing my own.

Regards,
Lukas

>
> kind regards
> angela
>
>
> On 3/25/13 4:09 PM, Lukas Eder wrote:
>>
>> Hello,
>>
>> I'm currently looking into extending Jackrabbit's (not OAK's) access
>> control management, and I found it easy to see how this area is a
>> significant performance bottleneck for today's Jackrabbit Content
>> Repository.
>>
>> The biggest design and architecture problem, in my opinion, is the
>> need for a session with associated, hard-coded access control
>> behaviour. From what I understand so far, there are (possibly
>> non-exhaustive):
>>
>> - System sessions
>> - Admin sessions
>> - User sessions
>>
>> In my opinion, in OAK, there should be something like a "secure
>> realm". Once this realm is entered, executing code should get complete
>> access to all of the repository through standard internal and external
>> API. For example, such behaviour could be achieved through setting a
>> ThreadLocal "monitor" in a local execution context as such:
>>
>>      // Outside of the "secure realm". JCR access goes through access
>> control
>>      T result = secure(new Securable<T>() {
>>          public T run() {
>>              // Inside of the "secure realm". JCR access
>>              // would now bypass access control
>>          }
>>      });
>>
>> And this could be the implementation of secure():
>>
>>      private static final ThreadLocal<Boolean>  t = new
>> ThreadLocal<Boolean>();
>>
>>      // OAK internals could use this to check if access control is needed
>>      public static boolean isSecured() {
>>          return t.get() != null;
>>      }
>>
>>      public static<T>  T secure(Securable<T>  s) {
>>          // Already secured
>>          if (isSecured()) {
>>              return s.run();
>>          }
>>          else {
>>              try {
>>                  t.set(true);
>>                  return s.run();
>>              }
>>              finally {
>>                  t.remove();
>>              }
>>          }
>>      }
>>
>> Such use of ThreadLocal is smelly and potentially slow, of course.
>> This is just to illustrate the idea. More realistic use-cases would
>> probably expose a shareable system session within the "secure realm".
>> The important thing is that this system session would also bypass
>> access control.
>>
>> Are there any such plans in OAK?
>>
>> Cheers
>> Lukas

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Angela Schreiber <an...@adobe.com>.
hi lukas

in contrast to jr-core access control mgt and permission evaluation
will not be built on top of the JCR stack but be located below the
new "SPI" boundary inside oak-core.

consequently we no longer have the need for (shared) system session.
btw: in jackrabbit-core system sessions already bypasses all kind
of access control evaluation.

kind regards
angela

On 3/25/13 4:09 PM, Lukas Eder wrote:
> Hello,
>
> I'm currently looking into extending Jackrabbit's (not OAK's) access
> control management, and I found it easy to see how this area is a
> significant performance bottleneck for today's Jackrabbit Content
> Repository.
>
> The biggest design and architecture problem, in my opinion, is the
> need for a session with associated, hard-coded access control
> behaviour. From what I understand so far, there are (possibly
> non-exhaustive):
>
> - System sessions
> - Admin sessions
> - User sessions
>
> In my opinion, in OAK, there should be something like a "secure
> realm". Once this realm is entered, executing code should get complete
> access to all of the repository through standard internal and external
> API. For example, such behaviour could be achieved through setting a
> ThreadLocal "monitor" in a local execution context as such:
>
>      // Outside of the "secure realm". JCR access goes through access control
>      T result = secure(new Securable<T>() {
>          public T run() {
>              // Inside of the "secure realm". JCR access
>              // would now bypass access control
>          }
>      });
>
> And this could be the implementation of secure():
>
>      private static final ThreadLocal<Boolean>  t = new ThreadLocal<Boolean>();
>
>      // OAK internals could use this to check if access control is needed
>      public static boolean isSecured() {
>          return t.get() != null;
>      }
>
>      public static<T>  T secure(Securable<T>  s) {
>          // Already secured
>          if (isSecured()) {
>              return s.run();
>          }
>          else {
>              try {
>                  t.set(true);
>                  return s.run();
>              }
>              finally {
>                  t.remove();
>              }
>          }
>      }
>
> Such use of ThreadLocal is smelly and potentially slow, of course.
> This is just to illustrate the idea. More realistic use-cases would
> probably expose a shareable system session within the "secure realm".
> The important thing is that this system session would also bypass
> access control.
>
> Are there any such plans in OAK?
>
> Cheers
> Lukas

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Lukas Eder <lu...@gmail.com>.
2013/3/25 Jukka Zitting <ju...@gmail.com>:
> Hi,
>
> On Mon, Mar 25, 2013 at 5:36 PM, Lukas Eder <lu...@gmail.com> wrote:
>> Let me put it bluntly. On a Unix system, sudo is so much more useful
>> than going to the hard drive with a magnet and applying some Tesla
>> magic, to bypass access control :-)
>
> It is, but a Unix system does not *implement* access control with sudo.

Exactly. Sudo helps bypassing access control.

> The equivalent to sudo in JCR speak would be Session.impersonate().
> Perhaps that's more in line with what you're seeking?

It probably is (or an explicit login). But as Angela correctly pointed
out, a small but important implementation fact slipped by me in my
real use case.

Thanks for your help
Lukas

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Mon, Mar 25, 2013 at 5:36 PM, Lukas Eder <lu...@gmail.com> wrote:
> Let me put it bluntly. On a Unix system, sudo is so much more useful
> than going to the hard drive with a magnet and applying some Tesla
> magic, to bypass access control :-)

It is, but a Unix system does not *implement* access control with sudo.

The equivalent to sudo in JCR speak would be Session.impersonate().
Perhaps that's more in line with what you're seeking?

BR,

Jukka Zitting

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Lukas Eder <lu...@gmail.com>.
Hi Jukka,

2013/3/25 Jukka Zitting <ju...@gmail.com>:
> Hi Lukas,
>
> On Mon, Mar 25, 2013 at 5:09 PM, Lukas Eder <lu...@gmail.com> wrote:
>> Are there any such plans in OAK?
>
> Yes, but not exactly as you outline.
>
> Instead of having a special "secure realm" or other special modes that
> allows things like JCR API calls without access restrictions, we've
> built Oak using a set of layers with with different responsibilities
> and limitations. The lowest ones of these levels, the NodeState model
> [1] and the underlying MicroKernel, offer an unrestricted view on the
> content stored in the repository. Access controls are currently built
> into the next level that consists of the TreeImpl class and other
> components that make up the Oak API [2].
>
> Just recently we've been discussion about whether access control
> checks should be pushed even further down the stack into the NodeState
> level. See [3] for the relevant (and ongoing) thread.

The immediate feeling I have with this approach is the fact that
low-level API access and access-control bypassing are two orthogonal
things. The purpose of high-level APIs is not restricted to adding
access-control. There are a lot of other useful features added, by
abstracting what you called NodeState / MicroKernel.

Let me put it bluntly. On a Unix system, sudo is so much more useful
than going to the hard drive with a magnet and applying some Tesla
magic, to bypass access control :-)

> It would be great if you could take a look at those layers and the
> recent discussion to see whether they address the issues you've
> encountered with Jackrabbit's access control model.

Yes, thank you for those links. I will read through them and probably
join the other discussion, rather than spawning a new one here.

Cheers
Lukas

Re: "Secure realm" of internal APIs to prevent costly access control lookups

Posted by Jukka Zitting <ju...@gmail.com>.
Hi Lukas,

On Mon, Mar 25, 2013 at 5:09 PM, Lukas Eder <lu...@gmail.com> wrote:
> Are there any such plans in OAK?

Yes, but not exactly as you outline.

Instead of having a special "secure realm" or other special modes that
allows things like JCR API calls without access restrictions, we've
built Oak using a set of layers with with different responsibilities
and limitations. The lowest ones of these levels, the NodeState model
[1] and the underlying MicroKernel, offer an unrestricted view on the
content stored in the repository. Access controls are currently built
into the next level that consists of the TreeImpl class and other
components that make up the Oak API [2].

Just recently we've been discussion about whether access control
checks should be pushed even further down the stack into the NodeState
level. See [3] for the relevant (and ongoing) thread.

It would be great if you could take a look at those layers and the
recent discussion to see whether they address the issues you've
encountered with Jackrabbit's access control model.

[1] https://github.com/apache/jackrabbit-oak/blob/trunk/doc/nodestate.md
[2] https://github.com/apache/jackrabbit-oak/blob/trunk/oak-core/README.md
[3] http://markmail.org/message/a4vviwtddoajx4ua

BR,

Jukka Zitting