[E-Lang] cap-based design question

Karp, Alan alan_karp@hp.com
Thu, 6 Sep 2001 14:31:56 -0700


> -----Original Message-----
> From: Jonathan S. Shapiro [mailto:shap@eros-os.org]
> Sent: Thursday, September 06, 2001 8:02 AM
> To: Karp, Alan; E Language Discussions
> Subject: Re: [E-Lang] cap-based design question
> 
> 
> > Assume there is exactly one capability per branch.  When a 
> user logs in,
> > start a proxy that is the only way the user's process can 
> talk to the
> > system.  This proxy can have a table mapping between the 
> name of a branch
> > and the capability needed for access....
> 
> Unless I have misunderstood, you seem to be proposing a 
> somewhat convoluted
> implementation of ACLs. The problem I am wrestling with is 
> not "How do I
> think of this in capability terms?". Rather, the problem I am 
> wrestling with
> is "Is this really a case where the ACL *model* is the best 
> we can do, and
> if so, what might that say about the usability of capability 
> systems in
> real, multiuser applications?"

I think we are using different definitions of the term "ACL".  To me an ACL
associates a client with a set of permissions for a each resource.  There
are two implications.  First of all, every request carries the full
authority of the client.  Secondly, either every object must know the
identity of each client, or some proxy for the object must understand the
semantics of requests.  

A capability, to my mind, is a token that grants an access right to any
client presenting it.  A client can choose to submit a subset of its tokens
with a specific request and can pass a token to someone else, thereby
delegating the associated permissions.

> 
> Your proposal seems to be similar in spirit to what MarkM 
> came up with. He
> proposed a two-capability system, in which the user (for user, read
> throughout "client") holds a capability to a proxy that 
> embeds unforgeably
> within its encoding the name of the branch. The proxy in turn 
> is trusted
> code, and holds a mapping from these branch names to true branch
> capabilities. While we talked over several variations on the 
> theme, in the
> end the proxy implemented ACLs. Unless I have misunderstood you, the
> distinction between the two proposals, as I see it, lies in 
> the user holding
> a name vs. the user holding a capability.

Yes, but the real difference between MarkM's proposal and mine is the
mapping to permissions.  I'll describe it in terms of what we did in
e-speak, because I'm afraid I'll bollix up the translation to E/EROS.  I'll
also use the word "key" (not an encryption key) to represent the token the
client is given and the term "capability" to denote what is passed to the
object.  

The proxy keeps a hash table with an entry for each resource.  Each entry
has mappings, each associating a key with a capability.  A single key can
appear in the entries for many resources and can be associated with more
than one capability for a specific resource.  When a client is granted an
access right to a resource or set of resources, a clone of the appropriate
key is given to the client.  The  proxy keeps track of the key each clone
was cloned from.  When a request comes in, the proxy looks up the clone to
find the base key it maps to, then it looks up the resource being referenced
to see what capabilities are to be granted.  The proxy then forwards the
request with these capabilities.  

Discretionary, multilevel security is one example I like to use.  Each
resource has a read (R) and a write (W) capability, and there is one base
key for each security level, say confidential (C), secret (S), and top
secret (T).  Every secret resource has an entry containing (C,W), (S,R),
(S,W), (T,R), with similar pairs for other levels.  A client with secret
clearance is given a clone of S, call it S'.  The mapping for resource S'
lists S as its base key.  A request for a secret resource accompanied by S'
gets forwarded with the R and W capabilities because S is associated with
these capabilities.  A request that comes in with C', a clone of the
confidential base key, gets forwarded with only the W capability.  If the
client's security level is changed, S' is revoked by removing it from the
clone-key mapping table, and the client is issued a new key, say T'.  In
this way, one revocation and one issue operation change the client's
permissions to any number of resources.

I don't think this approach is anything at all like ACLs, at least as I
think of them.  In particular, there is no mapping between clients and
permissions.

> 
> MarkM seems to favor encoding the branch name unforgeably within the
> capability because this facilitates selective delegation. At 
> the moment, my
> sense is that MarkM's proposal (per-branch capabilities vs. per-branch
> names) doesn't actually change things, because the user still 
> needs a means
> to enumerate the branches available to them, and at that point the
> protections of unforgeability and selective delegation are 
> erased by the
> ability to enumerate.

With what I propose, there's no need to keep the branch name unforgeable,
since permission is granted depending on the keys submitted.  Selective
delegation can be done by allowing clients to modify the mapping table entry
for a resource to have a new (key,capability) pair.  Of course, a client can
only add such a pair if it has a key that is associated with that
permission, and the key must be a clone of one the client submits.  That
way, revoking a client's privileges revokes all those it delegated.

> 
> Because the number of branches and working groups grows 
> quickly, I don't see
> an alternative to enumeration. We could introduce a level of 
> indirection
> through namespaces (each namespace corresponding to a group), 
> but this only
> pushes the need for enumeration back one level -- the set of 
> namespaces
> itself will change quickly.

I agree that groups are only a stopgap measure.

> 
> Further, we need selective revocation, so in the end, all 
> capabilities must
> *logically* point to a proxy. At the moment, the best 
> mechanism I can see
> for such selective revocation is to use ACLs (based on crypto 
> keys rather
> than user ids, but still ACLs).

Do you mean "selective" in the sense that all rights of a specific client
are revoked or do you mean that the client loses access to some of its
branches?

Removing a client from the system is a simple as deleting from the clone-key
mapping table the keys it was given.  Revoking a client's access to a
specific resource is a simple as adding an entry to the resource's mapping
entry.  For example, if a client granted clone S' is to have access to all
secret resources except one, then we add (S',-W), (S',-R) to that resource's
table entry.  Negative permissions take precedence over positive ones, so
the proxy forwards the request with no capabilities.

I like to separate the mechanism that determines what access rights a client
is granted from the mechanism used to decide whether to honor a request.
When a user joins the system, how do you know what capabilities to issue?
An ACL.  When a user leaves the system, how do you know which ones to
revoke?  An ACL.  When a user makes a request of an object, how do you know
if the request should be honored?  A capability.

> 
> > Auditing is an issue I prefer to separate from 
> capabilities.  In e-speak,
> we
> > had the core (TCB) publish an event on each access to an 
> object.  This
> event
> > allowed us to track the protection domain (not quite the user) that
> > originated the request.  We also allowed the object to use 
> a per-client
> > encryption key if it wanted to do its own auditing.  (Actually, we
> couldn't
> > stop it if we'd wanted to.)
> 
> I think that I may have used the term "auditing" in an 
> unfortunate way. For
> the moment, it does not appear that our server needs to ever 
> run unconfined
> active content, so every transaction on the server runs end 
> to end as part
> of a single mutating operation. The rationale for recording the
> (cryptographic) identity under which the mutate occurred is 
> to provide a
> means of post-hoc recovery from compromised keys.
> 

Gotcha.  With what I propose, you can have an "identity" permission in the
mapping table and give each client a distinct clone.  Thus, each entry would
contain a field (I,id).  The proxy could reject any request that did not
come with a key cloned from I.  In this case, the key submitted, I' say,
provides adequate identification of the client.  With this approach, a user
can be removed from the system by removing the entry for its clone of I from
the table.

> 
> Still, I'm stuck with my puzzle: surely there is a better 
> tool than ACLs for
> approaching this task!  Also, does somebody have a better model than
> enumeration?
> 
> 
> Jonathan
> 
> _______________________________________________
> e-lang mailing list
> e-lang@mail.eros-os.org
> http://www.eros-os.org/mailman/listinfo/e-lang
> 

_________________________
Alan Karp
Principal Scientist
Decision Technology Department
Hewlett-Packard Laboratories MS 1U-3
1501 Page Mill Road
Palo Alto, CA 94304
(650) 857-3967, fax (650) 857-6278
https://ecardfile.com/id/Alan_Karp
http://www.hpl.hp.com/personal/Alan_Karp/