w3c-ccg / did-method-v1

WORK ITEM: Veres One Decentralized Identifier Method Specification
https://w3c-ccg.github.io/did-method-v1
Other
3 stars 3 forks source link

"Proof of Authorization to Update" vs "Proof of Control" #1

Open kimdhamilton opened 7 years ago

kimdhamilton commented 7 years ago

This is more of a question, and likely something we will address in the coming weeks.

In the BTCR hackathon, we observed we needed more fine-grained categories than "Proof of Ownership" vs "Proof of Control". This is described here and (I think) some other issues.

What's called "Proof of Authorization to Update" here appears to match the definition of "Proof of Control" from the DID spec -- i.e. ability to update the DDO. And "Proof of Control" here seems to match the definition of "Proof of Ownership" in the DID Spec.

To clarify, this is my understanding of how the words are used in the DID Spec vs Veres 1 Spec:

Concept DID Spec Veres One
able to update DDO Proof Of Control Proof of Authorization to Update
control DDO Proof Of Ownership Proof of Control

I'm opening this issue not as a bug, but instead to track these terms as we decide the right names and categories for key/proof types.

"Proof of Control" from the DID spec has caused a lot of confusion -- i.e. without context, it's not clear how it differs from proof of ownership. I prefer something precise, like "Proof of Authorization to Update" used here.

dlongley commented 7 years ago

I think we need a list of clear, concise, concrete use cases that explain why "control", "ownership", "authentication", and/or "authorization to update" are necessary (and what they actually mean in a sensible context).

It seems to me that we're also potentially conflating:

  1. metadata that augments a change to the DDO that authenticates the change author, and
  2. information in the DDO that indicates which entities are permitted to do things (including make such changes) with the DDO or with the DID.

I have a lot of thoughts on the matter, but I'd really like to see the core use cases that are important to people to cover.

The most clear use case for me is when a user visits a website where they want to authenticate as a particular entity. The purpose for this authentication is to obtain credentials or to present them so that the user can gain authorization to something else.

This use case presents at least two requirements:

  1. The ability of the user to authenticate as the entity identified by a DID. This involves creating and presenting some kind of proof to the website.
  2. The ability of the user to delegate creating this proof to a third party, i.e. a digital wallet provider.

There is likely a third requirement that falls out of the second one (or that could be used as an alternative to the second one):

  1. The ability of the user to delegate the delegation of creating such proofs. Or put another way that gets into implementation details a bit too much: allowing a third party, such as a digital wallet, to add/remove keys for the user that can be used to authenticate them as the entity identified by the DID.
dlongley commented 7 years ago

The "proof" sections in the example DDO should probably contain the proof(s) themselves (the proofs used to demonstrate a change to the DDO by particular author(s) is permissible). So that would mean we'd have something like this:

authorization: [
  {capability: "x", entity: [a, b, z], permittedProofType: [proofTypeX, proofTypeY]},
  {capability: "y", entity: [a, c, f], permittedProofType: [proofTypeX]}
],
proof: [{
  type: "<one of the permitted proof types>",
  creator: "<one of the authorized entities>",
  ...
}]

Other formulations are acceptable obviously, but it seems like this would approach would make the names more appropriately match the relationship semantics -- and we'd get better differentiation on the concepts. We may need to combine proof types with entities in the authorization list for things like "multisig proof" to properly indicate which entities need to participate in the multisig.

Again, figuring out what capabilities are needed requires articulating some concise use cases.

msporny commented 7 years ago

@dlongley and I talked about this in the office this morning and as a result, I'm going to try to elaborate on all of the use cases in the Veres One DID Method spec by including examples here. If folks think this is a good direction, then I'll integrate them into the spec. Examples to follow...

msporny commented 7 years ago

This DID Object expresses that any entity that submits a proof containing an RSA Signature with the key .../keys/2 is allowed to authenticate as did:v1:215cb1dc-1f44-4695-a07f-97649cad9938.


{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938",
  "authenticationCredential": [{
    // this key can be used to authenticate as DID ...9938
    "id": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938/keys/1",
    "type": "RsaCryptographicKey",
    "owner": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938",
    "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
  }]
}
msporny commented 7 years ago

This DID Object expresses three ways in which the writeAuthorization field may be used to update specific fields in the DDO

  1. An entity authenticating as ...9938 can update any field in the DDO.
  2. An entity authenticating as ...5b2a using a 2017 RSA Signature can update the authenticationCredential field in the DDO.
  3. Any entity authenticating using a multi-signature proof that contains signatures by 3 specific keys can update both the authenticationCredential and writeAuthorization field.

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938",
  "writeAuthorization": [{
    // this entity may update any field in this DDO using any authentication mechanism 
    // understood by the ledger
    "entity": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938"
  }, {
    // this entity may update the authenticationCredential field in this DDO as long as they 
    // authenticate with RsaSignature2017
    "entity": "did:v1:b5f8c320-f7ca-4869-85e6-a1bcbf825b2a",
    "field": ["authenticationCredential"],
    "permittedProofType": [{
      "proofType": "RsaSignature2017"
    }]
  }, {
    // anyone may update the authenticationCredential and writeAuthorization
    // fields as long as they provide a specific multi-signature proof
    "field": ["authenticationCredential", "writeAuthorization"],
    "permittedProofType": [{
      "proofType": "RsaSignature2017", 
      "minimumSignatures": 3,
      "authenticationCredential": [{
        "id": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941/keys/123",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }, {
        "id": "did:v1:0f22346a-a360-4f3e-9b42-3366e348e941/keys/foo",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:0f22346a-a360-4f3e-9b42-3366e348e941",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }, {
        "id": "did:v1:a8d00377-e9f1-44df-a1b9-55072e13262a/keys/abc",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:a8d00377-e9f1-44df-a1b9-55072e13262a",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }],
    }],
    "authenticationCredential": [...]
}
mikelodder7 commented 7 years ago

Let me give you some examples where proof of authorization is needed. Suppose I want to delegate authority to an entity (software, devices) to act on my behalf. A device with authorization shows that I have allowed it to be used by me. I can also revoke my authorization which is handy when a device is stolen. The same can be true for software programs. I authorize a software program to receive claims on my behalf but if that program begins to function in a way I disagree with then I can revoke its authorization. You can also tie authorization to epochs or access control. The concept is simple but very powerful and useful if we expect adoption.

Here we are authorizing something or someone writeAccess to the DDO. We are using this to prove authenticity in the changes as well. Without it, the security and integrity of the system could be in jeopardy.

msporny commented 7 years ago

Without it, the security and integrity of the system could be in jeopardy.

Hey @mikelodder7, I agree with everything you said, which means I'm confused now. Are you saying we don't support what you're saying is important? Or were you just further reinforcing the points we were making via the data model above?

mikelodder7 commented 7 years ago

I'm reinforcing your points by giving more examples of authorization. I think it should just be proof of authorization. I may need to do more than update. I may choose to allow delegates to do anything with the stipulation that I can revoke it later. Proof to update is a single use case where someone or something needs to update the DDO but what if you wanted them to have power of attorney or something else. No need to limit it to just updating. You're model is good for this particular use case.

msporny commented 7 years ago

You're model is good for this particular use case.

Got it, thanks for clarifying @mikelodder7. Pay particular attention to the "field": ["authenticationCredential"] in the writeAuthorization entries, where you can be very specific about which fields the entity can update. For example, you could do "field": ["education"] to enable your university to write education credentials to the 'education' field in your DDO (a bit of a stretch of a use case, I admit, but it demonstrates the flexibility of the approach).

This approach also allows us to add other fields to the DDO, such as powerOfAttorneyAuthorization or guardianAuthorization, which could follow the model we have for writeAuthorization (or use something completely different). This enables different ledgers that support new authorization mechanisms (like Sovrin's guardianship + key sharding) to add their own authorization capabilities w/o having to convince all the other ledgers to do the same. So, it's flexible both from an engineering standpoint as well as from a standardization process standpoint.

brentzundel commented 7 years ago

I think that everyone has made good points, but there seem to be at least two issues in discussion here.

The first is about semantics, i.e. what should we call these DDO properties? The second is about usage, and this is further subdivided into usage of the DDO and usage within the DDO. By this I mean: In the first case we use the DDO to do things, in the second, we do things to the DDO. I believe I'm reiterating here what @dlongley said above.

I don't think we can have a reasonable discussion about semantics until we've clarified usage.

To use the terms from the [DID-Spec](https://w3c-ccg.github.io/did-spec/#dids-(decentralized-identifiers): "Proof of ownership" allows me to use the DID, it is a way of proving that this DID is a part of my identity. I own it. I could use my proof of ownership to authorize another entity to act on my behalf. I have not transferred ownership, I have used it to delegate authority. I like the term "proof of ownership" because to me it captures the usage. "Proof of Control" allows someone to change the DDO. Any entity that can supply proof of control can make changes to the DDO. The use case from the DID-Spec is about key rotation to allow identity recovery. I don't like "proof of control" I do not think it captures the usage. At the same time, I dislike "proof of authorization to update" because it is a bit pedantic. We might as well call it "proof of authority to make changes to the DDO just in case the identity owner can no longer supply proof of ownership and make their own changes, but hopefully that never happens, but just in case." I recognize that criticism is only truly constructive if I make my own suggestion here, but I don't have a good one. "Proof of authorization" is brief, and perhaps fitting, but too easily confused with other, more fitting uses outside of the DDO. Maybe just "proof of authority?"

agropper commented 7 years ago

I find it useful to adopt a strict definition of "owner" as the entity that can take something off-line or effectively delete it. In the DID / DDO context, that would suggest that anyone who can take a DDO off-line effectively owns it. Making changes to a DDO does not imply ownership since the changes can affect only a subset of the DDO.

Ownership of a DID is a different matter. It's not possible to delete or take off-line a blockchain transaction but it is possible to "spend" it. By my suggested definition, nobody owns a DID. The entity that can modify a DID by "spending" it is not an owner of the DID, it's a controller, delegate, or trust, I guess.

msporny commented 7 years ago

@brentzundel wrote:

Maybe just "proof of authority?"

Thanks for the feedback @brentzundel - from what you wrote, I think we agree on the purpose of the fields in the DDO, now it's just a "simple" matter of naming them (naming being one of the hardest things to do in Computer Science). :)

If folks agree with the general premise of needing to separate how an entity authenticates itself as a particular DID from what they can do once they authenticate, then we basically have two MVP things that we need to name here:

  1. What do we call the field that specifies how an entity authenticates itself as a particular DID, and
  2. What do we call the field that specifies which entities are allowed to change which fields in a DDO (along with additional authentication information, if necessary).

We've considered naming things "proofOfXYZ" before and the strongest arguments against that path were:

  1. A proof is what you provide to authenticate to do something, and therefore it would be strange to put "proofOfXYZ" in a DDO.
  2. A generalized DDO model should really specify statements that define the particular types of proofs entities can use to authenticate themselves to the ledger. So, things like "you can use an RSASignature, or your can use a Bitcoin multi-sig, or you can use a ZKP with these properties".

You can use #1 to authenticate w/ the ledger (e.g. update the DDO) AND to authenticate w/ systems external to the ledger (e.g. login). You use #2 to primarily do things w/ the ledger (e.g. update the DDO, rotate keys as a guardian, etc.).

Based on that line of thinking, we named #1 "authenticationCredential" because it's effectively a list of credentials (keys, pseudonymous biometric templates, ZKPs) that you can use to authenticate as the DID.

We named #2 "writeAuthorization" because it's effectively a list of mechanisms (e.g. proof types) that, if fulfilled by a proof submitted to the ledger, are authorized to make updates to specific fields in the DDO.

Hopefully that gives you more background on the logical progression of our thinking. We're not married to the names yet, so there is still time to change them (and even if we get them wrong, JSON-LD allows us to change them in the future even after the spec has shipped... but really, we don't want to do that and would like to nail these names down in the next month or so).

msporny commented 7 years ago

@agropper wrote:

I find it useful to adopt a strict definition of "owner" as the entity that can take something off-line or effectively delete it.

When we discussed (internally) using something like "owner", the following points were raised against its use:

  1. The word "owner" is not specific enough, which leads people to create analogies that conflate "authentication" vs. "authorization", and that harms ones ability to grasp what the field in the data model actually does.
  2. Using highly specific terms and functions enable us to build a system that is more composable, which results in a more adaptable system as time goes on. Owner doesn't not easily enable extensibility as there is a hard line drawn "either you're the owner, or you're not". However, moving to a model where you talk about capabilities that entities have (a capabilities model) leads to an easier ability to delegate and compose security in the system. That is, you want to be nuanced in how you use various authentication mechanisms to work in concert with statements on which entities are authorized to do what... and the concept of "owner" unnecessarily conflates those two distinct concepts.

By my suggested definition, nobody owns a DID.

I would argue that nobody owns a DDO either. A ledger "owns" a DID /and/ a DDO. A DDO specifies what types of proofs are required to authenticate, and what types of entities + optional proofs are required to modify certain fields in the DDO.

The entity that can modify a DID by "spending" it is not an owner of the DID, it's a controller, delegate, or trust, I guess.

This presumes a ledger with a cryptocurrency, and two of the ledgers that we're talking about (Sovrin and Veres One) don't need a cryptocurrency to provide DID/DDO functionality. We should stop talking about "spending" as a thing as it's very specific to Bitcoin and Ethereum based solutions.

We also need to be careful with "controller", "delegate", and "trust" as those can be slightly different concepts as well (and again, are more broad than they need to be). We need to be able to compose the low level security primitives we've created ("authentication" and "authorization to write to DDO") into these higher level concepts of "delegate", "guardian", and "trustees".

Hope that helps clarify our thinking on this @agropper, let me know if there are parts that still don't gel or make sense with you.

agropper commented 7 years ago

I'm ok with never using the word owner for anything. It's just that it comes up so very often that I feel compelled to argue for a definition. That said, let me react to some of the issues below.

inline...

On Thu, Aug 31, 2017 at 10:08 AM, Manu Sporny notifications@github.com wrote:

@agropper https://github.com/agropper wrote:

I find it useful to adopt a strict definition of "owner" as the entity that can take something off-line or effectively delete it.

When we discussed (internally) using something like "owner", the following points were raised against its use:

  1. The word "owner" is not specific enough, which leads people to create analogies that conflate "authentication" vs. "authorization", and that harms ones ability to grasp what the field in the data model actually does.
  2. Using highly specific terms and functions enable us to build a system that is more composable, which results in a more adaptable system as time goes on. Owner doesn't not easily enable extensibility as there is a hard line drawn "either you're the owner, or you're not". However, moving to a model where you talk about capabilities that entities have (a capabilities model) leads to an easier ability to delegate and compose security in the system. That is, you want to be nuanced in how you use various authentication mechanisms to work in concert with statements on which entities are authorized to do what... and the concept of "owner" unnecessarily conflates those two distinct concepts.

By my suggested definition, nobody owns a DID.

I would argue that nobody owns a DDO either. A ledger "owns" a DID /and/ a DDO. A DDO specifies what types of proofs are required to authenticate, and what types of entities + optional proofs are required to modify certain fields in the DDO.

There's no doubt as to whether something can be taken off-line or not. If there's a pointer on a public ledger (e.g.: an IP address or URL) and that pointer goes dark, then whatever was there is gone. Content-addressable routing is a special case of pointers where obviously the content cannot be taken down under normal circumstances.

The entity that can modify a DID by "spending" it is not an owner of the DID, it's a controller, delegate, or trust, I guess.

This presumes a ledger with a cryptocurrency, and two of the ledgers that we're talking about (Sovrin and Veres One) don't need a cryptocurrency to provide DID/DDO functionality. We should stop talking about "spending" as a thing as it's very specific to Bitcoin and Ethereum based solutions.

I completely agree. I used "" around spend to stand-in for various schemes that enable key rotation and recovery around public ledgers. Sorry for the confusion.

We also need to be careful with "controller", "delegate", and "trust" as those can be slightly different concepts as well (and again, are more broad than they need to be). We need to be able to compose the low level security primitives we've created ("authentication" and "authorization to write to DDO") into these higher level concepts of "delegate", "guardian", and "trustees".

I agree here as well. I'm involved in numerous standards groups that struggle with this delegation issue for many years. That includes a couple of groups in Kantara as well as OpenID/HEART and even IEEE. Lawyers are often involved, They come and go. I'm not aware of progress in this area.

Hope that helps clarify our thinking on this @agropper https://github.com/agropper, let me know if there are parts that still don't gel or make sense with you.

The EU regulatory distinction between "controller" and "processor" is potentially useful. It tends to be missing in the US regulatory context which complicates things a lot.

The state-of-the art, IMHO, is this recent 494-page drop from NIST https://www.nist.gov/news-events/news/2017/08/nist-crafts-next-generation-safeguards-information-systems-and-internet The Glossary alone is 24 pages. It makes me want to move to a deserted island.

Can we scope what we're doing relative to the broader 494-page picture in the US and whatever the equivalent might be in the EU? Unfortunately, that's a very big job.

Adrian

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/w3c-ccg/didm-veres-one/issues/1#issuecomment-326306564, or mute the thread https://github.com/notifications/unsubscribe-auth/AAIeYXTrPNeetDaYDP2N2S8WpwoqSSpPks5sdr5OgaJpZM4PD3SP .

--

Adrian Gropper MD

PROTECT YOUR FUTURE - RESTORE Health Privacy! HELP us fight for the right to control personal health data.

peacekeeper commented 7 years ago

From the early days of DID/DDO design I think I remember that originally we assumed the keys for ledger transactions would be completely independent from the keys for the DID/DDO. Therefore we needed something like the "control" block, where any external observer could determine if a new DDO on the ledger is valid and therefore correctly supersedes the previous DDO on the ledger or not.

Now instead we have a situation where in the common methods so far (btcr, sov, uport) the keys for ledger transactions are more or less directly linked to (or even the same as?) the keys for the DID/DDO. Doesn't this mean that the ledger itself and its method-specific resolution logic determine the rules according to which a DDO can be changed, and what types of proofs are supported? So if all this is enforced internally by the method anyway, why include a "control" block in the DDO at all, can't we just omit it? Same for "guardian".

Take uport for example, "control" of DDO is basically determined by an Ethereum smart contract. Do you now want to define an RDF/JSON-LD vocabulary that captures the full expressiveness of that smart contract logic, just so you can include it in the DDO's "control" (or "writeAuthorization" or whatever) block?

I think this means that "control", "guardian" etc. are only needed for logic that's not already inherent in the ledger-specific method anyway?

msporny commented 7 years ago

From the early days of DID/DDO design I think I remember that originally we assumed the keys for ledger transactions would be completely independent from the keys for the DID/DDO.

Keep in mind that "originally" and "early days" is 2014 to a number of us... :) (or earlier if you count the WebID TLS and Mozilla Persona days):

http://manu.sporny.org/2014/identity-credentials/

There was a time where much of what we are working with today was based on DHTs and Telehash and in that world, keys for updating the DDO were an integral part of the DDO.

Even today, there are implementations, such as Veres One, where we specify the keys that are capable of modifying the DDO in the DDO. I do realize that others like BTCR and at least one of the Ethereum implementations, since those ledgers aren't specifically designed for DIDs and DDOs, have a more complicated mechanism for ensuring proper updating of the DDO and those keys often live outside of the DDO.

Just level setting in order to address some of the other comments you've made. Originally we assumed keys for "ledger" transactions were part of the DID/DDO.

Therefore we needed something like the "control" block, where any external observer could determine if a new DDO on the ledger is valid and therefore correctly supersedes the previous DDO on the ledger or not.

Yes, and in some cases, a fit-for-purpose ledger (like Veres One) expects that information to be in the DDO. I'd argue that it's a much simpler design, but understand that not all DID Methods can do this (some Bitcoin (BTCR) and Ethereum-based solutions, for example).

Now instead we have a situation where in the common methods so far (btcr, sov, uport) the keys for ledger transactions are more or less directly linked to (or even the same as?) the keys for the DID/DDO.

What you say is true, but I don't know if this is always going to hold. For example, one could imagine a solution where you specifically want to keep a set of keys for managing any DDO separate (for example: keys used by a regulator or employer to override anything the DDO says for ledgers that are not self-sovereign).

Doesn't this mean that the ledger itself and its method-specific resolution logic determine the rules according to which a DDO can be changed, and what types of proofs are supported? So if all this is enforced internally by the method anyway, why include a "control" block in the DDO at all, can't we just omit it? Same for "guardian".

A few thoughts, some of which may be less compelling than others:

  1. It may be beneficial to make the DDO self-contained, so you don't have to go anywhere else to understand everything about the DDO, even if it means repeating yourself.
  2. The external "ledger provided" mechanisms may be just one part of DDO control, where one needs more than just the ledger provided keys to do things (like multisig using ledger keys + keys external to the ledger for some guardian-related activities).
  3. In some cases, DDO "control" and the logic the ledger executes may be one and the same.
  4. If we strip out "control", "guardian", and a few other things from the DDO, there isn't much left to standardize (which is fine), but then we might want to question the value of having a standard in the first place for DDOs if everyone is going to implement things differently. A partial counter to this is point #1... where we decide that we do want to be declarative, even if it means repeating ourselves in some cases. 5. Keep in mind that the smart contracts that control some DDOs may change from time to time, and we may not want to publish an entirely new spec if all we're doing is updating a DDO control algorithm (e.g. BTCRv2 supports TWO different control mechanisms, and one of them depends on data from the DDO).

Take uport for example, "control" of DDO is basically determined by an Ethereum smart contract. Do you now want to define an RDF/JSON-LD vocabulary that captures the full expressiveness of that smart contract logic, just so you can include it in the DDO's "control" (or "writeAuthorization" or whatever) block?

That could be one way to do it, if the uPort folks feel there is value there. I don't think one would try to encode the entire smart contract as JSON-LD, but merely the algorithm (like some ERC-20-like declaration might be enough with the definition of a few inputs). If not, they don't have to do it and the uPort DID Method would specify the other mechanisms for controlling the DDO, but again, this isn't as flexible is being declarative about the algorithms that you're using for control in the DDO.

I think this means that "control", "guardian" etc. are only needed for logic that's not already inherent in the ledger-specific method anyway?

For BTCR and uPort, that's probably true for this revision. I don't know if it'll hold in the future as other control and guardian algorithms are designed and deployed. For example, for the uPort implementation one may want back-references from the DDO to where to the contracts that control a DDO instead of having to scan the entirety of the Ethereum ledger.

For Veres One, "control" and "guardian" are an integral part of the DDO as the ledger is specifically designed to pay attention to those fields and there is not much else that goes into the ledger (since it's fit for purpose). That is, all of the control logic in Veres One is declarative.

So, I agree that your logic is sound for some of the ledger in use today. I'm uncertain if it works as the ecosystem expands to other ledgers and as uPort, BTCR, and Sovrin are upgraded as the years go on. We need to ensure that we don't make decisions that prevent us from extending and upgrading the systems in the future.

kimdhamilton commented 7 years ago

Earlier @msporny, @ChristopherA and I discussed the BTCR spec and agreed that the current form is too method-specific and not sufficiently declarative. I took a stab at reformulating it in the structure that Manu has started above (below). First some notes and questions.

I think this approach works well with BTCR and it nicely forced some editorial decisions. If we miss any of the dropped fields (e.g. varieties of transaction encoding, etc, which are easily derivable and probably not essential) we can include them in the method-specific spec.

Question 1: FYI @ChristopherA and @msporny: What I have below neglects other capabilities such issuing claims that we tried to include in the BTCR MVP. I'm unclear about the role of these capabilities in the DID Spec MVP. I think I've heard a range of options ranging from nothing to spec-level consideration:

  1. Only authenticating-as and updating the DDO are in scope for MVP (the thread above suggests it?)
  2. DID MVP should address how DIDs are used in (TBD) Verifiable Claims scenarios. Note this doesn't necessarily include at the spec level, mostly convincing ourselves...
  3. Extending (2), DID spec should specifically address some (again TBD) set of capabilities

Question 2: The only problem BTCR may present to the DID MVP spec is how to address the id placeholders I describe below, which are relevant for immutable content (in a content addressable store like IPFS).

BTCR DDO Using Above Approach

This example will assume the BTCR transaction references what we call a DDO "fragment" or "continuation" DDO in IPFS. We'll first look at the fragment and them how it manifests in the final, derived DDO.

DDO Fragment in IPFS

The following DDO fragment is stored in IPFS, and the address of this is stored in the OP_RETURN field of the BTCR transaction.

This optional IPFS DDO fragment states:

  1. It's adding an authentication credential with the specified public key pem. The DID in id and owner fields will depend on the BTCR transaction so they are using this placeholder * syntax (details in subsequent section)
  2. It enables an additional recovery/revocation/update mechanism via DIDs defined elsewhere
{
  "@context": "https://w3id.org/btcr/v1",
  "id": "*",
  "authenticationCredential": [
    {
      "id": "*/keys/1",
      "type": "RsaCryptographicKey",
      "owner": "*",
      "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
    }
  ],
  "writeAuthorization": [
    {
      "field": ["authenticationCredential", "writeAuthorization"],
      "permittedProofType": [
        {
          "proofType": "RsaSignature2017",
          "minimumSignatures": 3,
          "authenticationCredential": [
            {
              "id": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941/keys/123",
              "type": "RsaCryptographicKey",
              "owner": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941",
              "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
            },
            ...
          ]
        }]
    }]
}

Details about placeholder ids

Because changing the content changes the address, and because the DID depends on the Bitcoin transaction reference, we have a bootstrapping problem. We are using * as the placeholder for a valid DID (i.e. not revoked or rotated) that points to this IPFS address in its OP_RETURN.

It's significant that this specific example uses IPFS. Because the content is immutable, the transaction signature signs the content hash as well. If not using content-addressable store, then another LD signature scheme would be used.

BTCR Transaction and Derived DDO

Suppose the Bitcoin testnet transaction is issued, resulting in the BTCR DID: did:btcr:xyv2-xzyq-qqm5-tyke. We generate the final DDO by combining the information from the Bitcoin transaction with the (optional) referenced data.


{
  "@context": "https://w3id.org/btcr/v1",
  "id": "did:btcr:xyv2-xzyq-qqm5-tyke",
  "authenticationCredential": [ // The following can be used to authenticate as ...tyke
    { 
      // Derived from transaction; see (A)
      "id": "did:btcr:xyv2-xzyq-qqm5-tyke/keys/transaction-key",
      "type": ["EdDsaSAPublicKey", "CryptographicKey"],
      "owner": "did:btcr:xyv2-xzyq-qqm5-tyke",
      // note deviation
      "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
    },
    {
      // Fetched from the DDO fragment in IPFS; see (B)
      "id": "did:btcr:xyv2-xzyq-qqm5-tyke/keys/1",
      "type": "RsaCryptographicKey",
      "owner": "did:btcr:xyv2-xzyq-qqm5-tyke",
      "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
    }
  ],
  "writeAuthorization": [
    {
      // Derived from transaction; see (C)
      "entity": "did:btcr:xyv2-xzyq-qqm5-tyke/keys/output_address",
      "field": ["authenticationCredential", "writeAuthorization"],
      "permittedProofType": [
        {
          "proofType": "SatoshiBlockchainSignature2017"
        }
      ],
      "owner": "did:btcr:xyv2-xzyq-qqm5-tyke1",
      // note deviation: in BTCR we only reveal Bitcoin address of the revocation/rotation address, which is a base58-encoded hash of a public key
      "hash-base58check": "mvZ3MyLgsvYr87GGSbsPBWEDduLRptfzEU"
    },
    {
      // Fetched from the DDO fragment in IPFS; see (D)
      "field": ["authenticationCredential", "writeAuthorization"],
      "permittedProofType": [ {
          "proofType": "RsaSignature2017",
          "minimumSignatures": 3,
          "authenticationCredential": [{
              "id": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941/keys/123",
              "type": "RsaCryptographicKey",
              "owner": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941",
              "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
            },
            ...
          ]
        }]
    }]
}
dlongley commented 7 years ago

Here's another take on this with some slight changes.

Specifically, I've moved the "capability" into a separate property within the more general "authorization" property. So "writeAuthorization" becomes "UpdateDdo" as a capability within authorization. I've also added "IssueCredential" as a separate capability with a specific restriction on the key that can be used to issue credentials where the issuer is "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938" (the DID for this DDO).

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938",
  "authorization": [{
    // this entity may update any field in this DDO using any authentication mechanism 
    // understood by the ledger
    "capability": "UpdateDdo",
    "entity": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938"
  }, {
    // this entity may update the authenticationCredential field in this DDO as long as they 
    // authenticate with RsaSignature2017
    "entity": "did:v1:b5f8c320-f7ca-4869-85e6-a1bcbf825b2a",
    "capability": "UpdateDdo",
    "field": ["authenticationCredential"],
    "permittedProofType": [{
      "proofType": "RsaSignature2017"
    }]
  }, {
    // anyone may update the authenticationCredential and writeAuthorization
    // fields as long as they provide a specific multi-signature proof
    "capability": "UpdateDdo",
    "field": ["authenticationCredential", "writeAuthorization"],
    "permittedProofType": [{
      "proofType": "RsaSignature2017", 
      "minimumSignatures": 3,
      "authenticationCredential": [{
        "id": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941/keys/123",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:304ebc3e-7997-4bf4-a915-dd87e8455941",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }, {
        "id": "did:v1:0f22346a-a360-4f3e-9b42-3366e348e941/keys/foo",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:0f22346a-a360-4f3e-9b42-3366e348e941",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }, {
        "id": "did:v1:a8d00377-e9f1-44df-a1b9-55072e13262a/keys/abc",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:a8d00377-e9f1-44df-a1b9-55072e13262a",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }]
    }]
  }, {
    // this entity may issue credentials where the "issuer" field is this DDO's DID
    // as long as this specific RSA key is used
    "capability": "IssueCredential",
    "entity": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938",
    "permittedProofType": [{
      "proofType": "RsaSignature2017",
      "authenticationCredential": [{
        "id": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938/keys/1",
        "type": "RsaCryptographicKey",
        "owner": "did:v1:215cb1dc-1f44-4695-a07f-97649cad9938",
        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
      }
    }]
  }],
  "authenticationCredential": [...]
}
dlongley commented 7 years ago

Another option is to include an assuranceLevel in authentication credentials -- and then indicate the required level of assurance in the authorization metadata.

Of course, this requires standardizing around the meaning of those levels. There are some FIPS/NIST/FIDO/etc specs that talk about such levels but in slightly different ways or perhaps without a sufficient level of granularity for certain use cases. The approach may also introduce a further need for "proof of assurance level" -- that the level should be trusted as specified (via, e.g. TPM) rather than simply user declared.

Specifying the individual authentication credentials required would maximize granularity but makes it more difficult to update/manage changes to authentication credentials. However, it may be the better choice here.

msporny commented 7 years ago

Hey @kimdhamilton, just getting back to you on the question you asked above (thanks for the BTCR write-up, btw, super helpful):

@kimdhamilton wrote:

What I have below neglects other capabilities such issuing claims that we tried to include in the BTCR MVP. I'm unclear about the role of these capabilities in the DID Spec MVP. I think I've heard a range of options ranging from nothing to spec-level consideration

I think there are at least two schools of thought on how to proceed:

  1. Only put the minimum of what's necessary for DIDs to be useful (basically, "authentication" and "authorization to update the DDO") into the DID Spec. Everything else should go in extension specs (note: this doesn't mean DID Method specs). Think of it more like how we deal with extensions to HTTP. There is a core HTTP spec, and then there are specs that cover HTTP Header-based extensions (like "Signing HTTP Messages". We could design the DID Spec in the same way, which would be an argument for putting "Issuing" in another spec.
  2. Put what we think is the minimum useful set of features into the DID Spec. For example, a few people think Issuing and Guardian is a critical feature, so we should put that in the core spec.

I personally prefer the former, and it tends to be how things are done at IETF and W3C and supports more decentralized innovation.

msporny commented 7 years ago

@kimdhamilton wrote:

The only problem BTCR may present to the DID MVP spec is how to address the id placeholders I describe below, which are relevant for immutable content (in a content addressable store like IPFS).

"id": "*",

Instead of using a microsyntax there, just omit it. It's perfectly valid to have a Linked Data object with no identifier. This is called a "blank node" and is the way you say stuff like "I don't know the identifier for this thing yet, but it definitely has these attributes".

Doing this may create some attack vectors, so please do a thorough security analysis on it. @dlongley might have some thoughts on DDOs that temporarily don't have identifiers.

In general, as long as everything is content addressed, and where the event order is anchored in a Blockchain, you should be good.

I think the attack you might want to explore is what happens if someone detects the initial DID-less DDO and submits something to the Bitcoin blockchain simultaneously claiming the DID in the same block. Could there be a sleeper cell attack there? Is the worst that an attacker can do is make it indeterminate as to who owns the DID? My read on your approach says "No" to both cases because the DID is based on a combination of the transaction ID as well as the key information? I don't know enough about the details to do a thorough attack analysis.

kimdhamilton commented 6 years ago

Thanks @msporny, I will open issues to:

  1. make these changes to BTCR, and
  2. perform a security analysis
dlongley commented 6 years ago

@rxgrant,

You had asked what the core problem was that we were trying to address in this issue on one of the CCG calls. I think it boils down to a problem where there's a distinction without a real difference in the current DID spec:

Note that Proof of Ownership is separate from Proof of Control because an identity owner may wish to enable other entities to update the DDO (for example, to assist with key recovery as discussed in section 6.5) without enabling them to prove ownership (and thus be able to impersonate the identity owner).

Not only are both of these terms ("ownership" and "control") confusing, there is currently no actual difference (despite the spec stating so) because of a lack of granularity and a conflation of authentication and authorization. In concrete terms, anyone that can demonstrate "Proof of Control" can update the DDO to make themselves an owner -- therefore enabling them to establish "Proof of Ownership".

There is certainly a use case where we want to allow third parties to add new authentication credentials on behalf of the DID "owner", however, indicating that there is a difference between Proof of Control and Proof of Ownership without a sufficient level of granularity to actualize that difference is misleading.

Therefore, in this thread we have attempted to establish a capability-based model for more granular and clearly separated authentication and authorization. In this model you can specify which parties are authorized to modify particular parts of a DDO. Furthermore, it enables the specification of required levels of assurance via particular authentication credentials. These credentials must be used to authenticate the parties that designate what specific parts of the DDO they wish to update.