Monday 12:10 p.m.–12:40 p.m.
Designing secure systems with Object-Capabilities, Python, and Cap'n Proto
- Audience level:
Object-capability security is a technique for designing systems that lets us apply object-oriented design principles to security policies, reducing cognitive overhead and risk of errors that lead to vulnerabilities. In this talk, I'll explain capabilities, how they work, and what cool things they make possible for your systems, with real-world examples from sandstorm.io.
Object capabilities provide a powerful way to express and compose interfaces, and make it harder to get security properties wrong. **What are capabilities?** Capabilities are handles to things which implement interfaces. It's pretty abstract. More than just an API, capabilities can be transferred between actors, and they can be composed with each other. When used as the sole method to provide access to privileged data or functionality, they can also provide some powerful-yet-intuitive security properties. Capabilities are [widely regarded](http://srl.cs.jhu.edu/pubs/SRL2003-02.pdf) [in the security community](http://www.erights.org/elib/capability/index.html) as superior to static access control lists. However, for various historic reasons, misunderstandings, and implementation limitations, they are less-widely used. I hope that this design pattern will help you make more usable and more secure software. **Why are capabilities great?** Capabilities give you an opportunity to structure your systems' interfaces and privileges. They might require a bit of clear thinking, but result in easier-to-understand systems, which in turn are easier to maintain. They reduce the amount of security-sensitive allow/deny code you write - instead of checking at request time, you design the system to make it impossible for users to express unauthorized requests. Capabilities compose well. Given a capability, you can implement an interface which takes a capability, and returns a capability that utilizes the first one to support some interaction. For example, given a capability that allows access to a full contact book, you could return a capability that allows access to just one contact, or even a capability that allows the consumer to send an email to a contact, without revealing their identity to the program that produces the message to send. It's like having macros and encapsulation for distributed systems. Capabilities also tend to align well with user goals. Users tend to understand how to navigate and interact with nouns, and capabilities are nouns that embody access to the relevant resource at hand. Users easily grasp sharing these nouns with others, which may not be true of whatever complicated ACLs would be needed to implement a comparable policy in a rule-based ACL system. As a bonus, the context that capabilities require of their callers helps protect against "confused deputy" attacks, where an actor with more privileges is tricked into taking a privileged action on behalf of a less-privileged actor. (Think of fooling a system daemon into reading the wrong file, like `/etc/shadow`.) **Capabilities in Python with Cap'n Proto via pycapnp** [Cap'n Proto](https://capnproto.org) is a serialization and RPC framework that implements an object capability system in C++. [pycapnp](http://jparyani.github.io/pycapnp/) is a library which provides Python bindings for Cap'n Proto, making it easy to implement and consume interfaces from Python. This talk will demonstrate implementing a trivial remote 4-function calculator server with pycapnp, and then show how you might implement more complicated services, like the ones we use in [sandstorm.io](https://sandstorm.io) for file access and HTTP.