Hey folks, my name is Daniel Buchner from Microsoft.
I recently engaged Muneeb and Ryan to get involved with blockstack/store, and hopefully, scale the initiative dramatically in the coming months. Let me provide a little background on why I took interest in this:
In 2010 I sketched a similar system on a white board at Mozilla, which led to a high-level document describing a system I called “Web Profile”. I have participated in various W3C Working Groups on a variety of Web standards, most notably, Web Components. As such, I wanted to develop a standard system that User Agents could leverage to sync user data and regulate relationships between users and other entities. I never could realize Web Profile because I lacked the crucial features provided by the blockchain (we tried using torrents and other systems), so it was shelved after a few months of exploration. In 2012 I found the blockchain and jumped into the Bitcoin community. About 18 months ago I had considered trying to revive Web Profile now that the tech was there to do it - then I saw Onename.
Onename and blockstore provide the foundation for what I believe will be the future hub of all manner of interactions between users, apps, organizations, and devices. I would like to submit for consideration my thoughts on how we can build a semantic, standard system/API that can provide for these use-cases. My goal is to develop a standard that we can implement at Microsoft, and take to the W3C for wider implementation across all User Agents.
Daniel, great to see you here! And yes there is a lot of similarities in what you’ve been thinking about and what the passcard and blockstack open-source projects are trying to enable.
Thanks for sharing your doc with everyone. I think the passcard schema v3 is a great place to have discussions about how can we best structure user data:
Awesome @ potential implementation at Microsoft and engaging W3C re standardization. Really excited about this!
Welcome @daniel! Thanks for sharing, that doc was well put together. Each user story made sense. I do have some questions and comments while reading through it; starting from the beginning:
(p. 1) The User Agent initiates a lookup using the entity’s private key to negotiate name resolution on the blockchain.
I do not understand this part, what is the private key being used for here?
(p. 2) To make it possible for a UA to act on an entity’s behalf (even when the entity is offline), the entity can optionally sign a derivative, child key for the UA to hold that allows it to execute all or a subset of the master key’s capabilities.
Where do the policies for these derivative keys live? In the UA? Child keys would likely be application specific, in which case I’m wondering who is enforcing the policies of what each child key is capable of
(p. 3) “handle”: “Neo”,
(p. 3) “connections”: { // keyed by public key of connected entities
Could you clarify what you mean here, “keyed by public key”?
That looks to be a copy/paste mistake, I believe it should read something like: “The User Agent initiates a lookup of the user’s public username on the blockchain to negotiate pointer resolution.”
This was more or less an idea for allowing a UA to modify all (or some) profile values on a user’s behalf when the user is not online to input the required auth factors that complete the UA’s partial/derivative key. Underlying this is the assumption that the UA would never retain the private master key - which highlights a potential issue with the use-case/need to allow the UA to modify profile values without the user online to provide missing auth factors. I am looking for feedback on how to accomplish both, if both are even simultaneously possible.
As far as potential schemes for UAs and what they hold, I was thinking of something like this:
User forms a relationship with a UA, gives them an incomplete key that must be combined with a minimum of 2 other auth factors to be completed (and subsequently used to modify profile values)
User adds a new device and syncs their UA to the client device, which includes transmission of the User’s incomplete key to the device
The UA’s client installation asks once for the second of the three factors, which is computed into a single value and still missing one factor to generated the complete key.
When the User does something that requires the UA to perform an operation, the UA prompts for the 3rd factor (pin, fingerprint, etc.), which allows them to complete the key and use it in the scope of one transaction, deleting it afterward.
I would think the above scheme should be user configurable to add or subtract factors, based on user preference. This still doesn’t solve what I alluded to in the original language: requiring permission/factors for the UA to modify some values, but not others, without risking a breach of the UA that compromises private master keys.
Does this make sense?
“// keyed by public key of connected entities” just means the Connections the Web Profile system makes on behalf of the user are added in the Connections object keyed by the Connected Entity’s public key. I thought that was a good idea for a few reasons:
If you allow friendly names for the top-level keys of the Connections object, there could be collisions.
We need to store the Connected Entity’s public key anyway for use in multi-recipient key signing of the profile values they have access to, why not use them as the keys of the object given they are unique?
I welcome any other ideas/feedback you have on the Connections part of the spec, given it’s the most important aspect of the system.
To the best of my knowledge, there are two options in bitcoin today for accomplishing the specified goals:
Shamir’s Secret Sharing - master key is split into m-of-n pieces, which require a quorum to reassemble the full key. Once the key is reassembled, for all intents and purposes it is no longer secret.
Multisig - script in the bitcoin protocol which requires m-of-n signatures to complete a transaction. This is better, since the keys can remain physically isolated, but if they are ever stored within the same application or even on the same machine, once again, for all intents and purposes, the keys are no longer secret.
In theory, what you want to do can be done, but in practice it would not be very secure since once all the pieces are combined, the UA or the machine the UA runs on will essentially own the user. With a more permissive scripting system (perhaps on a sidechain), you would be able to delegate the ability to perform specific smart contract operations to specific keys while retaining a secret master key that can override or perform any other possible action. Currently, bitcoin’s scripting system is not complex enough to allow for this behavior. That said, if the application logic is stored and executed in the UA and not on chain, then it may be possible to create such a system (@ryan and I have discussed off-chain smart contracts before, maybe he can chime in here?)
Regardless, you do not want to give a UA your whole master key if you value your account. The safest route would be to have your master key actually be a master multisignature account so that even if a minority of keys are compromised, your ID is still secure. Then you could give the UA one key, store two keys yourself on separate devices, and when the UA asks for a 2-of-3 signature needed to update the profile, it will sign once and prompt you for a second signature, you sign the appropriate transaction on your separate device and send the complete signed transaction back to the UA and broadcast it to the bitcoin network.
I can understand why you want to use the public key as the object, but would humbly recommend against it. Rather than relying on a locally stored copy of their connection’s public key, it would be best for a user to check their connection’s profile for an update to the public key field each time they intend to authenticate them or send them an encrypted message (reasons for updating include: compromised key/ device, good key hygiene, etc).
I understand the concern about collisions, but this problem will need to be solved by applications anyways so users do not attempt to contact or authenticate the wrong profile. Therefore, it is required that names be unique - this could mean extending common names to include a salt or some other unique factor e.g. “TLD” type appendage, and it will be up to the namespace creator and the resolvers to decide how to implement this.