Object Capabilities for Linked Data (OCAP-LD for short) provides a secure way for linked data systems to grant and express authority utilizing the object capability model. Capabilities are represented as linked data objects which are signed with Linked Data Signatures. OCAP-LD supports delegating authority to other entities on the network by chaining together capability documents. "Caveats" may be attached to capability documents which may be used to restrict the scope of their use, for example to restrict the actions which may be used or providing a mechanism by which the capability may be later revoked.

This specification is currently being drafted to be considered as a work item for the Community Credentials Group.

Introduction

This document is being based off of a paper from Rebooting Web of Trust. In the early stages of this document some ideas may be better described in that paper than yet in this specification.

This document does not cover a specific method for delivering OCAP-LD invocations to an object, though something like the inbox property and associated delivery mechanisms from Linked Data Notifications and ActivityPub is one possible system. However there is nothing about OCAP-LD that is specific to HTTP; for example, both capabilities and invocations could be stored on a blockchain or a distributed hash table.

Capabilities vs. Access Control Lists

One of the first questions that is usually asked about using Object Capabilities for authorization is: "How are Capabilities different from Access Control Lists?". Fundamentally, Access Control Lists are about authority by identity whereas Object Capabilities are about authority by possession.

Authority by identity is the process of giving access to a resource to a specific entity based on their identity. These processes typically ask the question: "Who are you?"

Authority by possession is the process of giving access to a resource to any entity that possesses something, like a key. These processes typically ask the question: "Do you have a key that fits this lock?"

This document doesn't explain why Access Control Lists lead to a variety of security issues or why Object Capabilities provide stronger security guarantees. For those that would like to learn more about these topics, Capability Myths Demolished and ACLs Don't provide a deeper exploration into the benefits of Object Capabilities.

OCAP-LD by Example

Much of modern computing security infrastructure relies on "who is doing something" using access control lists. For example, our friend Alyssa P. Hacker has a car, and she would like to drive it In the access control list world, the car itself may scan Alyssa's face, determine that Alyssa is the driver, and say "Welcome Alyssa, you are now free to drive." Talking cars are appealing and fun, but Alyssa may run into challenges when she would like to allow others to drive her car.

Fortunately, there is another paradigm that is even more familiar to the car scenario, but less familiar in the context of computing, despite providing some superior properties and a greater degree of safety: object capabilities. Object capabilities focus not on "who" is performing an action, but upon "what" source of authority permits an action to occur. As it turns out, Alyssa does not have a talking and face-scanning car, she has a car that accepts a car key. The car may have no memory of Alyssa whatsoever, but as long as Alyssa holds the kind of key that enables her to drive the car, she can drive the car. Capabilities are very similar to this car metaphor, and we can encode this same idea in OCAP-LD. The following document delegates authority from the car (who always has authority over itself) to Alyssa so that she may drive:

    {"@context": ["https://example.org/ocap/v1",
                  "https://autopower.example/"],
     "id": "https://whatacar.example/a-fancy-car/proc/7a397d7b",

     // Since this is the first delegated capability, the parentCapability
     // points to the target this capability will operate against
     // (in this case, Alyssa's Car)
     "parentCapability": "https://whatacar.example/a-fancy-car",

     // We are granting authority specifically to one of Alyssa's
     // cryptographic keys (not to be confused with the car
     // key metaphor!)
     "invoker": "https://social.example/alyssa/#key-for-car",

     // Finally we sign this object with cryptographic material from
     // Alyssa's Car's capabilityDelegation field, and using the
     // capabilityDelegation proofPurpose.
     "proof": {
        "type": "RsaSignature2016",
        "proofPurpose": "capabilityDelegation",
        "created": "2016-02-08T16:02:20Z",
        "creator": "https://whatacar.example/a-fancy-car#key-1",
        "signatureValue": "IOmA4R7TfhkYTYW8...CBMq2/gi25s="}}
        

Turning on this car and driving into the sunset is as easy as invoking the capability to do so:

    {"@context": ["https://example.org/ocap/v1",
                  "https://autopower.example/"],
     "id": "urn:uuid:ad86cb2c-e9db-434a-beae-71b82120a8a4",
     "action": "Drive",
     "proof": {
        "type": "RsaSignature2016",
        // A linked data document can be an invocation if it has a
        // proofPurpose of capabilityInvocation and links to the capability
        // chain it is invoking
        "proofPurpose": "capabilityInvocation",
        "capability": "https://whatacar.example/a-fancy-car/proc/7a397d7b",
        "created": "2016-02-08T17:13:48Z",
        "creator": "https://social.example/alyssa/#key-for-car",
        "signatureValue": "..."}}
        

Alyssa lives with her roommate and long-time friend Ben Bitdiddle. While they're living together, she'd like that he be able to drive her car too. Capabilities support delegation, so she could delegate a new capability to Ben giving him full authority, not unlike going to the hardware store and having them copy the car key. But Alyssa knows that she and Ben will probably not be roommates forever, and she feels no need for him to be able to drive her car once they are not, so she would like to have the option to revoke his authority. In the world of object capabilities, this is entirely possible by adding a "caveat" that permits future revocation. We can imagine this to be like a new car key that has a remote destruction mechanism: Alyssa can press a button that she has, a wire burns out inside the car key, and the car key will not be usable anymore. Alyssa generates a new capability document that points at the capability she has, adding the caveat:

    {"@context": ["https://example.org/ocap/v1",
                  "https://autopower.example/"],
     "id": "https://social.example/alyssa/caps#79795d78",

     // Pointing up the chain at the capability from which Alyssa was
     // initially gained authority
     "parentCapability": "https://whatacar.example/a-fancy-car/proc/7a397d7b",

     // Alyssa grants authority specifically to one of Ben's
     // cryptographic keys
     "invoker": "https://chatty.example/ben/#key-33",

     // Alyssa adds a caveat: Ben can drive her car, unless she flips
     // the bit at this url
     "caveat": [
       {"type": "ValidWhileTrue",
        "uri": "https://social.example/alyssa/ben-can-still-drive"}],

     // Finally Alyssa signs this object with the key she was granted
     // authority with
     "proof": {
        "type": "RsaSignature2016",
        "proofPurpose": "capabilityDelegation",
        "created": "2017-03-28T06:01:25Z",
        "creator": "https://social.example/alyssa/#key-for-car",
        "signatureValue": "..."}}
        

Alyssa hands the car key to Ben, and Ben marks the car key in such a way that reminds him that it's specifically to drive Alyssa's car. Several months pass and Ben receives a message from Alyssa asking if he might enjoy joining her at an award ceremony her university is holding. Alyssa is already at the university and is getting a ride to the venue, so she suggests Ben drive her car and meet her there. Ben invokes his capability, the car performs all relevant checks on the capability (including that the proof/signature is valid and applicable, and that the caveat is still valid), and off Ben drives.

Ben arrives at the fancy award venue, where there is valet parking. The Valet approaches wearing the nametag "Lem E. Driveit" and asks for a key to park the car. Ben remembers he has heard some stories about valets going on joyrides and isn't sure if they're true, but decides there's no need to take the risk: he can use his capability to create a new, further restricted capability which he can delegate to Lem. This new car key has the caveat that it can be used to drive up to 5 kilometers, but no more:

    {"@context": ["https://example.org/ocap/v1",
                  "https://autopower.example/"],
     "id": "https://chatty.example/ben/caps#2cdea8c1",
     "parentCapability": "https://social.example/alyssa/caps#79795d78",
     "invoker": "https://lem.example/#key-bf36",

     // Ben adds this caveat: this capability can be used to drive the
     // car, but not for more than 5 kilometers
     "caveat": [
       {"type": "DriveNoMoreThan",
        // Alyssa's gauge currently says 123854 kilometers driven,
        // so this is only 5 km more than the current value
        "kilometers": 123859}],

     // Finally Ben signs this object with the key he was granted
     // authority with
     "proof": {
        "type": "RsaSignature2016",
        "proofPurpose": "capabilityDelegation",
        "created": "2017-06-13T19:15:03Z",
        "creator": "https://chatty.example/ben/#key-33",
        "signatureValue": "..."}}
        

(It probably doesn't matter to this scenario, but since it is derived from the car key that Ben holds, it also has the same caveat that it will also be remote destructed by Alyssa along with Ben's car key should she press the relevant button.)

Capabilities Are Safer

We can see from the above example that by using an object capability system such as OCAP-LD can give us some additional power around delegating and restricting the scope of capabilities. But object capabilities provide improved safety characteristics over Access Control Lists which may make them frequently better choices (for more details, see the paper ACLs Don't). Object capability systems are in general more robust against:

Object capabilities are less vulnerable to these kinds of attacks because capabilities are an encoding of "the principle of least authority" in software development practice. OCAP-LD helps bring the power of capabilities to the web, providing specific and directed grants of authority.

Terminology

capability
Authority which may be invoked to perform some operation upon a (linked data) object.
target
The entity that will be acted upon when the capability is invoked.
capability chain
A chain of capability documents which may be used to delegate authority to other entities in the system. Each capability document in the chain inherits the caveats of previous capabilities in the chain and may only be granted by entities which have existing authority within the chain.
caveat
Also known as "attenuation" within object capability literature, a "caveat" may be attached to a capability as a restriction on how that capability may be used. Delegated capabilities will preserve caveats and may be themselves may be further restricted by adding more caveats.
invocation
The "activation" of a capability, represented as a linked data document which is signed in such a way that matches authority granted through a prior capability. An invocation may have arguments, similar to how a procedure call may have arguments.
action
An argument of an invocation which directs what particular functionality of the object is being used. For example, an invocation against a file storage service may specify either a write action or a read action. (Actions are the same as what are frequently called "methods" in computer programming.)
parentCapability
The previous capability document on the chain, which is granting authority to this invocation document. In the case of the first delegated capability document, this points at the target.
capabilityDelegation
This term serves two purposes:
  • As a property from which the target supplies the "initial source of authority" on the chain. This is holds cryptographic material which it may use to initially delegate on the chain (and in some cases which it may use to invoke itself as a capability).
  • As the value of a proof's proofPurpose to indicate that this proof is intended to grant authority to the invoker entities on the capability.

Capabilities

OCAP-LD capabilities are encoded through a chain of linked data documents, granting authority to a target, possibly restricted through "caveats". Authority starts with the target (which always has authority to invoke itself) and extends to further invoker entities along the chain. Each capability document granting authority must be signed off with a proof by an entity which has previously been granted authority on the chain. Any caveat applied by a parent in the chain applies to its descendants.

The target's json-ld document is a kind of "special" capability document implicitly granting authority to itself. But why? Surely in most protocols, such as when objects are sending invocations over HTTP POST requests, any target that wants to self-modify could do so internally without an explicit invocation process. But in some systems such as blockchains, there is no "internal" state, so explicitly doing an invocation to change behavior is still useful.

Another reason is that it simplifies the invocation algorithm: as we delegate authority to the first non-target entity, we do so using the target's cryptographic authority. If this authority can be used to grant capabilities, it may as well be able to be used to invoke them as well.

Every capability document, except for the target, MUST have:

Every capability document, except for the target, MAY have:

Why don't all child capabilities require a invoker property? The reason is that it is perfectly reasonable for an entity which has authority to a capability to give an attenuated capability to itself to be used in a specific context.

Capabilities are not structured around "who has access" to something but rather holding onto a capability for a particular use, and in order to avoid confused deputy and ambient authority problems, in general objects should not hold on to a "bucket" of capabilities which grant them authority, but hold on to them within specific contexts for specific purposes. In general, when an object is granted a capability, it is important that it know for what specific purpose it has been granted that capability so that it does not become confused and use it in the wrong scenario. This is not unlike how in computer programs a procedure called with specific arguments understands for what the meaning of those arguments are and for what they may be used.

Delegation through Capability Chains

A capability document that is not the target MUST also have a parentCapability property which either points at the target or another capability document. A series of capability chained together in this way is called a "capability chain" and is how delegation of capabilities are handled in OCAP-LD. New keys MAY be granted authority to use this capability through the associated invoker property.

Caveats

Every capability document MAY add restrictions on the way the capability may be used by adding to the caveat property. Capabilities inherit the restrictions from all caveat properties of their parents, and MAY add new caveats in addition to those of their parents.

The meaning of caveats are determined by their type and whatever other properties they have. Due to the way they are interpreted at invocation type by the target, some mutual understanding of terminology must be understood between the entity adding a caveat and the target evaluating (or any other parties observing) the invocation.

Invocation

A capability may be enacted through the process of invocation. In the context of OCAP-LD, an invocation consists of a linked data object which MUST have a proof property with a value containing:

An invocation SHOULD have an id (which may also serve as a nonce). Any other properties are considered arguments to the invocation.

Each capability document accrues granted authority in the chain, which is used to both authorize further capability delegation and may be used to invoke the capability chain. The capability document that is invoked's chain is recursively traversed up along the previousCapability document until the target is found (the root document that has no previousCapability property). The target's capabilityDelegation cryptographic material is marked in the initial set of authority. The capability chain is then traversed from this root target back down through each delegated capability all the way to the invoked capability document leaf, validating and accruing authority:

  • At this point, the invocation is considered valid and any relevant action may be performed. (This does not guarantee that a specific result will occur, merely that the invocation itself is valid; a invocationTarget could in evaluating the invocation encounter invalid input and return or raise an error, for instance.)

    Since invocations are themselves linked data documents, it is possible for an invocation to refer to an invocation as an argument. For this reason it is critical that mechanisms for accepting invocations be sure which invocation is being performed. For example, a mechanism that accepts OCAP-LD capabilities as JSON-LD documents will likely have no trouble telling which invocation is being performed since that will be the "top" of the framed document. However, a mechanism which accepted N-Quads would need additional information supplied perhaps in the headers in order to be able to determine the "root" of the invocation.

    Actions

    Actions are a common way to direct behavior of an invocation. Targets are free to choose their own mechanisms for directing behavior, but MAY support the action property on invocations as one common behavioral direction technique. The action property points to a URI as a form of vocabulary to determine which action is being performed. For example, a capability to a file storage system may allow for both reading and writing files, and a user could choose to set the action to https://datastore.example/WriteFile as an argument on their invocation.

    Relationship to Verifiable Credentials

    The Verifiable Credentials Data Model provides a powerful vocabulary for correlating information and presenting correlated information in a secure way. This can be used to make claims about some subject, to present credential certifying you are qualified to do some thing, or so on. This is useful for gathering and presenting information that can be reasoned about. Indeed, this maps nicely to "the real world", as humans tend to be "correlation/reasoning machines". For example, Eva Lu Ator is hoping to hire a system administrator and may check for a college diploma, past work history, or recommendations from known entities considered qualified to judge competency to fulfill the role, and all of these can be modeled nicely with the Verifiable Credentials Data Model.

    Thus it may be tempting to design a system in which a credential is presented in order to permit or forbid access to some resource. Unfortunately, associating "who is authorized to do what" leads us back to all the problems of access control lists, which we would like to avoid. When returning to our hiring a system administrator example it is easy to imagine how, upon hiring Alice as as a system administrator, Eva would hand Alice a capability to begin administrating her systems. But in considering the previous step where Eva contemplates whether or not to hand Alice that capability seems to pull us right back to correlating information about Alice's identity. (What is Alice's educational background? What is Alice's prior work experience?)

    We seem to be in a conundrum. Claims and credentials are forms of correlation that allow us to reason about an entity in our squishy human world, but are unsafe when used as mechanisms to authorize some event to occur within a system. Capabilities are a safe mechanism to model the flow of authority through a system, but there are times when capabilities have not been granted and we need to make a "judgement call" by correlating information about that entity. What should we do?

    To pose the question is to see the answer: the right approach is to use each system for what it does best. Use correlation (Verifiable Credentials) in a reasoning system (most commonly human reasoning) as a path to make judgements about whether to hand an entity a specific set of initial capabilities. Use capabilities (OCAP-LD) as the mechanism to grant and exercise authority through computing systems. To return to our system administrator example, when Alice applies for the job, she submits a series of credentials about her prior work history and degree, and Eva is able to verify that it is Alice's former employers and university which have made these claims. Deciding that Alice is fit for the job, Eva hands Alice her initial capability which grants her authority to administrate the systems in question (with a caveat that allows Eva to revoke that authority at a future date, if appropriate). Alice uses that capability as the initial entry point into administrating the system.

    Handling abuse

    The previous section discussed cases in which correlation (particularly through Verifiable Credentials) is used to grant an initial set of capabilities. This section discusses how correlation may be used to revoke capabilities under certain circumstances, and steps that should be taken to ensure this is done safely.

    Capability systems focus on what authority grants that an operation may be performed, not on who is performing the action. In some object capability systems (such as many object capability programming languages) it is not even possible to see what entity is invoking a capability. In the case of OCAP-LD, it is always possible to inspect an invocation to check which authentication material authorized to invoke the capability is being used in the invocation, and this may permit checking a certain amount of "who" is performing the action, but to focus on the "who" rather than the source of authority would bring us back to the dangers of Access Control Lists.

    Nonetheless, there comes a time when correlating information about usage of a resource becomes critical, and this is in mitigating abuse. Even traditional capability systems, in developing solutions to this problem, develop techniques for correlating information about "who" has performed an action. (For example, Horton is one such system for E, though as previously stated, such information can be cleaned already by looking at the invocation and capability chain documents in OCAP-LD.) The key to permit detecting and mitigating abuse safely in a capability based environment is to treat correlation of who is using a service not as something that is used per-invocation, but as something to be reasoned about to possibly revoke authority. (Astute readers may observe that between the previous section and this section we have defined safe ways to use correlation in conjunction with capabilities: as the entry point and possible termination point, with capabilities powering the machine in-between.)

    For example, Alice has granted capabilities (with caveats that permit revocation) to a number of users access to run programs on the systems she is administrating, but someone is using their capability to abuse the system. The system itself performs the invocations as the users call them, but Alice, or a program Alice runs, is able to analyze a log of past invocations called. Having finished the analysis, Alice realizes that the abuse is coming from the invocation of a capability granted to some of Mallet's authentication material, and Alyssa revokes that capability.