Summary

We’ve been deep into our developer retreat this week, but we’re still cranking out new functionality and refining existing code! The most exciting new feature to land is the other half of capability grants — committing a capability claim to your source chain!

Highlights

  1. Developer Retreat: Planning, Design, and Bus Factor Improvements
  2. API/Security: `commit_capability_claim()`, The Other Half of Capability-Based Security
  3. API/Breaking Change: `receive()` Callback Accepts Sender ID
  4. Key Management: Get Public Key from Keystore
  5. Signals: Improved Signal Serialization
  6. Admin/Testing: New Admin API Function for Adding Test Agents
  7. Holochain 101: Capability Grants and Claims

Details

Holochain Dev Pulse May 6–May 13, 2019

1. Developer Retreat: Planning, Design, and Bus Factor Improvements

If you’ve been following the Dev Pulse for a while you’ll know that we like to occasionally come together IRL to break bread, hack, plan, and design. This helps us craft our vision, come to decisions rapidly, and gel as a team.

This past week, members from across dev teams and disciplines got together in Colorado, USA to flesh out the global roadmap. We had many great discussions about the networking layer, overlaps between Holochain and Holo Host, maintaining high code quality, developer experience, key components of Closed Alpha, and many other things.

Don’t worry though — we haven’t stopped shipping! Important pull requests are still getting merged and we’re sticking to our weekly release schedule.

Speaking of which, we’re training each other on the release process and making sure every core dev gets a turn in the rotation. This increase in shared capacity will improve our bus factor considerably, ensuring that releases continue to be predictable through holidays, illnesses, and other life events.

2. API/Security: `commit_capability_claim()`, The Other Half of Capability-Based Security

We landed the rest of the needed functionality to create fine-grained control over access to zome functions in your app. `hdk::commit_capability_claim()` lets an agent store a capability grant they’ve received from someone else to retrieve and use it at a later date. This is a very exciting feature, but it’s also quite complex. See item number seven in this Dev Pulse if you want to know more!

Breaking change: `hdk::grant_capability()`, which was announced last week, has been changed to `hdk::commit_capability_grant()` to mirror the name of its new counterpart. This is an immediate change without a deprecation period.

3. API/Breaking Change: `receive()` Callback Accepts Sender ID

In order to determine who sent you a message, all `receive()` callbacks now receive the sender’s address as their first parameter, which bumps the message contents to the second parameter. Make sure to update all your receive callbacks if you’re using node-to-node messaging! You can see this in action in our example source code — which also shows you how to implement ‘typed’ messages and check the validity of a capability claim using the sender address.

4. Key Management: Get Public Key from Keystore

We’ve added one new function to the keystore API: `hdk::keystore_get_public_key()` allows you to get the public portion of a secret. This is primarily to support the creation of DPKI implementations, but you may find it useful, for performing cryptographic handshakes too.

Cryptographic Handshake

5. Signals: Improved Signal Serialization

We have improved signal serialization, which changes the format of the JSON-formatted signal being sent over the wire. Prior to this the signals were debug-formatted Rust, which is difficult to handle in Javascript. The internal redux actions were just printed into a string that was the payload of the signal.

This changes them to fully formed JSON and required implementing ‘Serialize’ on all structs that can compose an ‘Action,’ as well as adding the ‘serde_support’ feature to snowflake.

We know many app developers are looking forward to this continuation of our signals work.

App-defined signals aren’t supported yet, so for now you’ll only see this change if you’re one of the rare developers who are listening to system-generated tracing/debugging signals over the admin API WebSocket interface.

6. Admin/Testing: New Admin API Function for Adding Test Agents

We’ve added `test/agent/add`, a new admin API RPC function. This is mostly an internal feature that allows us to test the conductor itself without having to create a keystore.

7. Holochain 101: Capability Grants and Claims

Holochain’s capability grants and claims are based on the capability-based security model. They are used internally to allow GUIs and bridged applications to access an agent’s running DNA instances. You can also create grants in your application that let you write functions that empower an agent to delegate privileges to other agents. You can use them for things like:

  • Granting a ‘ghostwriter’ temporary permission to publish a blog entry in your name
  • Giving a doctor access to a private source chain entry that contains sensitive data
  • Permitting a small group of people with changing membership to modify a global variable on the DHT

An agent grants a capability by writing a special capability grant entry to their source chain. It can then be shared with other agents, who store it to their own source chains as a capability claim entry. When they want to use the privileges represented by the grant, they retrieve it from their source chain and present it to the grantor.

A grant has one of three levels of applicability. It can be set to:Public — everyone may make claims against the grant.
Transferable — any agents who hold the grant token may make claims against it (which is similar to an OAuth bearer token).
Assigned — only specific agents who hold the grant token and can demonstrate ownership over one of the key pairs to which the grant was assigned may make claims against it.

Here’s an illustration of the ‘ghostwriter’ scenario, using node-to-node messaging to negotiate:

  1. Alice is the CEO of a company. She hires Bob to write articles for her on the company blog, but wants him to write under her name. In order to do this, she needs to give him permission to commit entries to her source chain.
  2. Alice creates a “can_post” capability grant as a private entry on her source chain, including Bob’s public key as the assignee.
  3. Alice shares the hash of the capability grant with Bob over node-to-node messaging. Bob can now use this hash as a ‘capability token,’ which will allow him to make a claim against her grant.
  4. Bob saves a capability claim in his own source chain, which contains the token, along with Alice’s public key and the “can_post” tag so that his app instance knows the token’s purpose.
  5. It’s time for Bob to write an article. He drafts the post and sends it to Alice via node-to-node messaging along with the capability token and a signature on the article text that proves he’s in control of his private key.
  6. Alice receives the message. She retrieves the grant using the token Bob supplied, checks that Bob’s public key is on the grant, and that his signature is there showing that he created the article.
  7. When she’s satisfied, she calls the `publish_post` function, which publishes Bob’s article on her own source chain.

Alice and Bob could negotiate this publishing process through email, a special feature in the blog app’s GUI, or even pigeon post. The advantage of capabilities, however, is that once Alice has issued the grant to Bob, Holochain can handle the permission management without any intervention from either party. If Bob leaves the company for a job at a prestigious in-flight magazine, Alice can revoke the grant.

You could roll your own capability-based security using these principles, but we’re already using it at lower levels and believe it will be such a useful pattern that we’ve exposed it in the API for you to use.

For a code example of the blog scenario above, read through the example source code in our repo (hint: search through the file for the word ‘claim’). In the future, we’ll have helper functions to make this process easier.

Development Status: