An agent wants to maintain control over a resource but also wants to delegate their agency to another agent.
- 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.
Use capability-based security to allow an agent to delegate the power to ‘call’ the zome functions in her DNA instance. In reality she is still calling the functions, but she’s doing it on behalf of her delegate.
Holochain already uses capability-based security to secure local access to zome functions between zomes, bridged DNAs, and the RPC interface. You can build the basis of this pattern using the HDK functions
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:
- Alice wants to ghost-write for Bob, so she calls a zome function
request_post_capability()that takes Bob’s agent ID.
- This function uses a messaging technique, like node-to-node messaging, to ask Bob for permission to
post()on his behalf.
- Bob decides whether to grant this permission to Alice, then commits a capability grant to his source chain detailing the terms of the grant.
- Bob sends the hash of the capability grant back to Alice; this hash is her capability token.
- Alice commits a capability claim to her source chain. It contains the token and a label that reminds her that Bob granted it for ghost-writing privileges.
When Alice wants to use the capability Bob granted her, she calls a
delegated_post() zome function that’s similar to the original
post function but takes an argument that lets her retrieve the capability claim from her source chain. This function doesn’t perform any local operations; it just uses a messaging mechanism to pass the function parameters and the capability token to Bob.
On the remote end, Bob uses the claim token to retrieve the grant from his source chain, makes sure the grant matches what Alices is trying to do, and calls his own
post() function on her behalf. He passes the return value back to Alice.
- Partial grant: Bob might choose to place limits on his grant, like the ability to only post until a certain date or under a certain category. Some of these can be enforced at grant-checking time; others may be mixed into the zome function call using partial application.
- 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: Alice might want to let Charlie ghost-write for Bob by giving Charlie a capability grant for her
- Asynchronous: If agents aren’t guaranteed to be online at the same time, use the Mailbox pattern rather than node-to-node messaging. If necessary, protect communications using Asynchronous Private Messaging.
- Think hard about the possible conditions to be placed on a grant. Agents can’t revoke a capability unless you give them a way to do it.
- 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 online. You could use the Mailbox pattern to negotiate these flows asynchronously, but watch out for privacy leaks as the data is on the DHT.
- Once a transferable token has been leaked, anyone can use it. Agents should keep grants and claims secret!
- Chained delegation can get pretty hairy pretty quickly.
This pattern isn’t appropriate for controlling access to public data on the DHT. Use these patterns instead: