[E-Lang] E FAQ

David Wagner daw@cs.berkeley.edu
Sun, 14 Oct 2001 23:47:48 -0700


[Forwarded with permission.  --MarkM]

> How does A provide some of its authority to B, such that B can exercise it 
> other than while called by A?

A must explicitly pass a closure or a proxy to B.  This requires
changes to B's interface, and syntactically it's a little less
convenient for A in Java compared to languages where higher-order
functions and closures are basic primitives, but maybe it's not
too bad if you don't have to do it on every function call.
I guess you end up using similar "proxy" patterns in E, too,
from time to time.

I find this an interesting design question.  In this sort of scenario,
would we prefer to allow B to "capture" and store A's authority without
asking A?  Or, should we require A to explicitly agree to this before
B may "capture" A's authority?  The advantage of the former is that
this is transparent to A, which might better support data abstraction;
the advantage of the latter is that it gives better control to A,
I guess.

(In the basic Java system, authority is conveyed on the stack for a
time limited by the lifetime of the corresponding activation record.
By "capturing" authority, I mean the possibility that B might be able
to "extract" the authority from its callee's activation record and
store it on the heap so that B can later use this authority at some
later time, after that activation record has disappeared.)

It seems that E-like capability systems take the stance that, by
default, B can capture authority from A and use it later.  If A wants
to prevent this, A must take an explicit action: namely, rather than
passing B a capability, pass B a revocable proxy (and revoke after
the call to B returns).  This is not transparent, but maybe it's
good enough.

In Java, it appears that, by default, B cannot capture authority from
A for later use.  If A wants to allow B to do this, A must take an
explicit action: namely, rather than calling enablePrivilege(p),
instead pass B a long-lived proxy that will call enablePrivilege(p)
and do some action whenever B asks.  This is a little clumsy, but
maybe it's good enough.

I suppose that we could extend Java to support both models more
directly, if that seemed valuable.  For instance:
   void enablePrivilege(Privilege p, boolean capturable);
   CapturedPrivilege capturePrivilege(Privilege p);
   void enableCapturedPrivilege(CapturedPrivilege cp);
B would be allowed to call capturePrivilege(p) only if A has
called enablePrivilege(p, true).  It would not be too hard to
implement this interface as an extension to the basic stack
introspection mechanism, I think, and then the caller could choose
which model it prefers.

Do have you any thoughts on when to prefer capturable vs.
non-capturable privileges?  How can we tell which model is better
suited to specific application needs?  Do you think this question
even matters?

> Now, having been clear on the extent of my confusion and uncertainty about 
> Java's security model, here's why I say that it's Principal-oriented.

Oh, I absolutely agree.

> >Many Java apps do not
> >run with least privilege.  However, the possibility is there in the
> >architecture to do much better in this regard.  If apps normally ran
> >with all privileges disabled, and bracketed only those areas where they
> >need privilege P with enablePrivilege(P); ...; disablePrivileged(P),
> >this would be a big step towards least privilege, wouldn't it?
> 
> It would certainly be an improvement.  But how fine grained can P be?  Can 
> it be as fine grained as a capability (even ignoring the difference between 
> objects and ClassLoader-based aggregate entities)?  See below.

In principle, I suppose P can be fine-grained, but in practice,
that's a misleading answer.  In practice, fine-grained privileges
are likely to be much more unwieldy in Java than in E.  In a E-like
capability system where object references also play double-duty as
conveying authority, you can afford to get much finer-grained,
because you don't have to write down as many annotations explicitly
specifying what you want to allow.

-- David