[Python-Dev] Capabilities

Guido van Rossum guido@python.org
Mon, 10 Mar 2003 10:38:28 -0500

> Ben Laurie wrote:
> > BTW, if you would like to explain why you don't think bound methods are
> > the way to go on python-dev, I'd love to hear it.
> Guido van Rossum wrote:
> > Using capabilities, I would have to hand her
> > a bunch of capabilities for various methods: __getitem__, has_key,
> > get, keys, items, values, and many more.  Using proxies I can simply
> > give her a read-only proxy for the object.  So proxies are more
> > powerful.

(Jim surmised that I meant to write "bound methods".  Alas, I don't
get off that easily: at the time I wrote that I really did think that
a capability had to be a single function.)

> There seems to be a persistent confusion here that i would like
> to dispel: a capability is not a single lambda.

I guess, I misunderstood..  I was sure that Ben told me this was so.
Apparently I misread, or you have a different definition of capability
than he does (wouldn't be the first time.)

> Guido's paragraph, above, seems to believe that it is.  In fact,
> the pattern he described is a common and powerful way of using
> capabilities.  A capability is just an unforgeable object reference.
> In a pure capability system, the only thing you can do with a
> capability is to call methods on it (or, if you prefer, all you
> can do is send messages to it).  Interposing an object to expose
> only a subset of another object's API, such as a read-only subset,
> is exactly the power capabilities give you.

So a proxy with a fixed (not depending on the caller) policy about
which methods you can should be considered as equivalent to a
capability -- in fact this would be a way to implement capabilities.

> It seems to me that the "rexec vs. proxy" debate is really about
> a very different question: How do we get from Python's currently
> promiscuous objects to properly restricted objects?
> (Once we have properly restricted objects in either fashion, yes,
> definitely, using proxies to restrict access is a great technique.)
> If i understand correctly, the "proxy" answer is "we create a
> special wrapper object, then the programmer has to individually
> wrap any object they want to be secure".  And the "rexec" answer
> is "we create an interpreter mode in which all objects are secure".

Well, actually, restricted execution as currently implemented does
*not* strive to make all objects secure: untrusted code can still
inspect all attributes of an object unless that object is proxied by a
Bastion, or unless that object is one of a few built-in types
(e.g. bound methods) for which some attributes are privatized.

> I think the latter is far better.  To have any sort of real chance
> at establishing security, you have to start from a place where
> everything is secure, instead of starting from a place where
> everything is insecure and you have to individually secure every
> single object with its own wrapper.

But we don't have the latter.

> The eventual ideal is to have a system where all objects are
> "pure" objects (i.e. non-introspectable capabilities) by default.

That wouldn't be Python.

> Anyone wanting to do introspection would simply have to obtain
> the "introspect" capability from a privileged place (e.g. sys).
> For example,
>     class Foo:
>         pass
>     print Foo.__dict__                  # fails
>     from sys import introspect
>     print introspect(Foo).__dict__      # succeeds
> When running the interpreter in secure mode, "introspect"
> would just be missing from the sys module (again, ideally
> sys.introspect wouldn't exist by default, and a command-line
> option would turn it on, but i realize that's far away).
> This would have the effect of the "introspectable flag" that
> Guido mentioned, but without expending any storage at all,
> until you actually needed to introspect something.

That flag wasn't my idea, it was some one else's (Greg Ewing?).

--Guido van Rossum (home page: http://www.python.org/~guido/)