[Python-Dev] Capabilities in Python

Ka-Ping Yee ping@zesty.ca
Fri, 31 Jan 2003 15:19:03 -0600 (CST)


Wow, how did this topic end up crossing over to this list while
i wasn't looking?  :0

Ben Laurie wrote:
> I'll admit to being that person. A capability is, in essence, an
> opaque bound method. Of course, for them to be much use, you
> want the system to provide some other stuff, like not being able
> to recreate capabilities (i.e. you get hold of them from on
> high, and that's the _only_ way to get them).

Jeremy Hylton wrote:
> That seems like a funny defintion of a capability.

A better definition of "capabilitiy" is "object reference".

"Bound method" isn't enough, because a capability should be able
to have state, and your system should have the flexibility to
represent capabilities that share state with other capabilities,
or ones that don't.  The simple, straightforward way to model this
is to just equate the word "capability" with "object reference".

> A capability system must have some rules for creating and copying
> capabilities, but there is more than one way to realize those rules in
> a programming language.

I suppose there could be, but there is really only one obvious way:
creating a capability is equivalent to creating an object --
which you can only do if you hold the constructor.  A capability
is copied into another object (for the security folks, "object"
== "protection domain") when it is transmitted as an argument to a
method call.

To build a capability system, all you need to do is to constrain
the transfer of object references such that they can only be
transmitted along other object references.  That's all.

The problem for Python, as Jeremy explained, is that there are so
many other ways of crawling into objects and pulling out bits of
their internals.

Off the top of my head, i only see two things that would have to
be fixed to turn Python into a capability-secure system:

  1. Access to each object is limited to its declared exposed
     interface; no introspection allowed.

  2. No global namespace of modules (sys.modules etc.).

If there is willingness to consider a "secure mode" for Python
in which these two things are enforced, i would be interested
in making it happen.

> The problem, which rexec solves after a fashion, is to prevent
> unauthorized copying of the capabilities, or more specifically of the
> access rights contained in the capability.

No, this isn't necessary.  There's no point in restricting copying.
The real problem is the unlimited introspective access ("there is no
private").

> In Python, there is no private.

Side note (probably irrelevant): in some sense there is, but nobody
uses it.  Scopes are private.  If you were to implement classes
and objects using lambdas with message dispatch (i.e. the Scheme way,
instead of having a separate "class" keyword), then the scoping would
take care of all the private-ness for you.

> The Zope proxy approach seems a little more promising, because it
> centralizes all the security machinery in one object, a security
> proxy.  A proxy for an object can appear virtually indistinguishable
> for the object itself, except that type(proxy) !=
> type(object_being_proxied).  The proxy guarantees that any object
> returned through the proxy is wrapped in its own proxy, except for
> simple immutable objects like ints or strings.

The proxy mechanism is interesting, but not for this purpose.
A proxy is how you implement revocation of capabilities: if you
insert a proxy in front of an object and grant access to that
proxy, then you can revoke the access just by telling the proxy
to stop responding.

The mechanism by which the proxy also proxies objects passing
through is what we capability-nerds call a "membrane", and it's
a way of doing more powerful revocation.



-- ?!ng