Pyr8 User's Manual

« Introducing Pyr8 | The JavaScript APIs »

Object Capabilities

To understand pyr8 you should understand object capabilities. Luckily for us, capabilities are significantly easier to understand than what we’ve been doing all these years. Every major operating system in the world uses a security architecture called discretionary access control. Our server, pyr8, uses a security architecture called object capabilities. Discretionary access control is an inferior model that is subject to trojan horses and confused deputy attacks. It’s also more complex and difficult to reason about correctly, so normal users routinely make critical errors when confronted with a security decision.

Object capabilities are further backed up by proven mathematical theory that allows us to confidently deduce the security properties of a large system from its components, helping to ensure that important security requirements get implemented correctly and stay implemented correctly.

What’s the difference?

In the physical world, discretionary access control is implemented with an id badge, while object capabilities are implemented with keys. Suppose all access control for your house, your car, and your safe used a badge; would you hand it over to a valet? Most modern cars have valet keys that only allow parking the car, not opening the glove compartment or the trunk. You can give someone a key to access your garden shed without allowing them to access your house.

A physical key embodies authority to access a particular physical space; to do this with id badges means you have to enroll them into your system and create an id badge for them.

Capabilities also provide a richer notion of delegation than access controls. Suppose the valet at the hotel door needs to drive to a parking garage and hand off the car to an attendant there; because you never interact with the parking garage attendant, there’s never even an opportunity to enroll him in your car’s security system. In a capability system, you simply supply the valet key, which can open the driver’s door and start the vehicle, but can’t open the trunk or glove compartment.

What is an “object capability”?

An object capability is a reference to an object that grants authority. That’s it. If you need to do operation X, then you need a reference to an object on which you can perform object.X(). When you program JavaScript, you obtain references to objects in the usual way, either as the argument to a function or as a variable in your lexical scope. If you need authority to access a file, then either your client must pass it to you or a filesystem object must be in scope.

When you begin programming JavaScript, you have access only to the authority provided by the global program scope, so in pyr8, all security authority is conveyed by binding actual objects into the global scope of some program. The good news is that this makes authority-passing and authority-using very simple.

If I want to fork a new thread with access to the filesystem, I could simply write something like this:

// Perhaps during initialization...
var thread_root_dir = get_root_dir();
var code = get_code();

// And then later...
var x = pyr8.threadpool.fork(code, {fs: thread_root_dir})

In this example, the authority is passed simply by providing the filesystem object to the thread when it is forked and requires no more scaffolding in the system. When the thread begins running its code, it will have authority to perform file system operations, because it was passed a file system. Notably, we didn’t pass any network authority to the thread, so this thread cannot communicate with the network.

An Historical Aside

By the late 1970’s, the United States government recognized the need for widespread deployment of secure computing systems and began to try to standardize what it meant for a computer system to be “secure” for their own purpose. This resulted in a series of books known as the “Rainbow Series,” which specified various mechanisms for ensuring the security of computer systems used by the government.

During the mid-1980’s, the government published the Orange Book which contains information about how to build verified, trusted computer systems. Later, the government published the Neon Orange Book, specifying how to build access control mechanisms into computer operating systems. Nearly every operating system manufacturer in the world implemented the discretionary access control system described in the Neon Orange Book. All major operating systems implement discretionary access controls from Unix to Windows to Apple’s OSX.

If you’re the US military, then access controls probably seem perfectly sensible: you trust the people, not the machines, and you have authority to hold people accountable for their actions. What the General wants to guarantee is that the people who go into the armory are authorized to do so. Once they’re in there, they have a job to get done and physical access to a building or a room gives you physical access to the entire facility. Generals post guards at the doors, who keep a written log of everyone that goes in or out of a facility. World militaries have long used log-based systems for controlling access to their most critical resources (usually weapons) and so they wanted a log-based system for their operating system security, too.

This was a completely terrible design mistake that has plagued us for years.

It should not surprise us to find out that computers don’t operate analogously to military bases. Servers open to the public internet assuredly do not trust the people they interact with, and they do not have authority to hold people accountable for their actions. Therefore, a security model that applies effectively to the physical premises of a military facility shouldn’t be expected to “map well” onto computer software.

In fact, this was well-known even back in the 1980’s. Here’s what the Neon Orange Book has to say about access control lists:

❝Discretionary access control mechanisms restrict access to objects based solely on the identity of subjects who are trying to access them. This basic principle of discretionary access control contains a fundamental flaw that makes it vulnerable to Trojan horses.❞

The object capabilities architecture does not have these problems. Moreover, as you’ve already seen, it’s far simpler to reason about how authority is passed in a computer system than it is to reason about the side-effects of access controls.

« Introducing Pyr8 | The JavaScript APIs »