[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