Capability Delegation

Problem

An agent wants to maintain control over a resource but also wants to delegate their agency to another agent.

Examples

  • Alice is a CEO. She hires a ghost writer to publish blog articles in her name.
  • Bob controls the credit limit on a community currency. He’s going on a year-long sailing trip and wants Carol to manage that credit limit in his stead.

Solution

Use capability-based security and call_remote to allow an agent to delegate the power to ‘call’ the zome functions in her DNA instance.

Implementation

Holochain uses capability-based security to secure access to zome functions. Using call_remote, one agent can call another agent’s functions over the DNA’s peer-to-peer network.

Choose the zome functions in your DNA that can be delegated to other agents. For each of these functions, create a flow that lets one agent ask another agent for permission to call the function in their DNA instance. Here’s an example using a blog article posting function and call_remote to handle the initial requesting and granting of the capability:

  1. Bob wants to ghost-write for Alice, so he calls a zome function request_ghost_post_capability(alice_id).
  2. Within request_ghost_post_capability Bob’s cell call’s a zome function handle_ghost_post_capability_request(bob_id) in Alice’s cell. This function notifies Alice’s UI that Bob wants to post on her behalf.
  3. Alice decides to approve this request. She calls the zome function grant_ghost_post_capability(bob_id), which a capability grant, assigned to Bob, for the zome function create_post.
  4. Within grant_ghost_post_capability, Alice’s cell call’s the zome function handle_ghost_post_capability_grant(capability_secret) in Bob’s cell.
  5. Within handle_ghost_post_capability_grant, Bob’s cell stores the capability secret Alice has given to him, along with a memo of what the grant is for.
  6. Now it’s time for Bob to write an article. He composes it, then calls the ghost_post(title, content, alice_id) zome function.
  7. Within ghost_post, Bob’s cell brings up the capability secret Alice gave him, then calls the zome function handle_ghost_post(title, content, capability_secret) in Alice’s cell.
  8. Alice’s cell writes the new post in her source chain, then publishes it to the DHT. It looks like she has written the post, because it’s got her signature on it.

Variations

  • Partial grant: Alice might choose to place limits on his grant, like the ability to only post until a certain date or under a certain category. Currently this would have to be checked using extra metadata written to Alice’s source chain, but in the future we intend to bring partial application to capability grants.
  • Transferable vs assigned: Holochain’s capability grants let you specify whether it can be used by anyone who holds the token (transferable) or a certain set of agents by public key (assigned).
  • Chained delegation: Bob might want to let Charlie ghost-write for Alice by giving Charlie a capability grant for his ghost_post function.
  • Asynchronous: If agents aren’t guaranteed to be online at the same time, use the Mailbox pattern rather than call_remote. If necessary, protect communications using Asynchronous Private Messaging.

Warnings

  • Think hard about the possible conditions to be placed on a grant. Agents can’t revoke a capability unless your DNA and UI code give them a way to do it.
  • Once a transferable token has been leaked, anyone can use it. Agents should keep grants and claims secret!
  • Chained delegation could get pretty hairy pretty quickly.

Related patterns

Capability-based security is for giving access to resources under one agent’s control, which in Holochain means one agent’s cell and source chain. It isn’t appropriate for controlling access to public data on the DHT. Use these patterns instead:

6 Likes

Hi Paul,

Thanks for the great write-up and the sharing of the patterns. I really like the 'problem > solution > implementation ’ format and the names of the patterns. It really helps with understanding the framework better and learning to think ‘the Holochain’-way.

Two remarks/questions:

  • “You’d normally use node-to-node messaging to request/grant a token or make a claim, but this only works when both agents are offline” - Shouldn’t this be online?
  • “When Alice wants to use the capability Bob granted him, he calls a delegated_post() zome” - Should be her/she, right?
1 Like

ha, thanks for the catch! I’ll fix those now.

use MAC’s with OTS required for each pull request, I think you can maybe set time windows therefore would only need a single OTS per hour or per day etc

I wonder if somehow files could be read only and another person’s ‘edit’ would be more like a suggestion, that then the owner would have to approve in order to commit

1 Like

NOTE: I’ve edited this to update it for Holochain RSM.

Node-to-node messaging is no more; RSM has call_remote instead, which automatically enforces checks for the validity of a capability secret. However, it doesn’t allow you to do programmatic checks; e.g., “this grant is only valid for an hour” or “this grant is only valid for certain call parameters”.

@pqcdev in the future Holochain will have a scheduler so you can automate deletion of capability grants, and call parameters will likely be enforced via currying/partial application (e.g., you can specify that this grant to call the post_blog_entry function is only for the “Cooking” category.)

What you’re exploring here is another good pattern that might be more appropriate for other situations. You could probably use the built-in CRUD actions to facilitate this — updates no longer clobber the original; they’re just metadata that says “person A and person B both published their own updates to element X”, and then in the future there’ll also be ‘canonical’ updates, which a given app might only allow the original author to do.

Lots of fertile territory for useful and interesting application patterns!

1 Like