WebOfTrustInfo / btcr-hackathon-2019

BTCR Hackathon 2019
https://weboftrustinfo.github.io/btcr-hackathon-2019/
MIT License
2 stars 0 forks source link

Need a Canonical BTCR 'Implicit' DID Document #4

Open ChristopherA opened 5 years ago

ChristopherA commented 5 years ago

We need to have a canonical BTCR 'implicit' DID Document.

This is the one I'm playing with now — but I believe all the values are correct.

@mattcollier: there is no btcr @context schema yet, but does it look basically correct?

@peacekeeper: are the key types correct now?

@rxgrant, @kimdhamilton: does this look like a good minimal satoshi audit trail set?

all: Looking for a better name for the tip, currently unspent-tip-address-base58

@peacekeeper, @msporny: Instead of the tip being in the satoshi audit block, should it instead be in a standard control proof DID block? It isn't the public key, it is hash of the public key.

{
    "@context": ["https://w3id.org/did/v0.11", "https://w3id.org/btcr/v1"],
    "id": "did:btcr:xyv2-xzpq-q9wa-p7t",
    "publicKey": [
        {
            "id": "did:btcr:xyv2-xzpq-q9wa-p7t#keys-1",
            "owner": "did:btcr:xyv2-xzpq-q9wa-p7t",
            "type": "EcdsaSecp256k1VerificationKey2019",
            "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
        }
    ],
    "authentication": [
        {
            "type": "EcdsaSecp256k1AuthenticationKey2019",
            "publicKey": "#keys-1"
        }
    ],
  "service": [
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    },
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#CRS",
      "type": "CredentialRepositoryService:BTCR",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    }
  ],
}

The audit trail for this (to be sent as optional data by the DID Resolver) is:


{
"SatoshiAuditTrail": [
        {
            "blockhash": "00000000b3487880b2814da8c0a6b545453d88945dc29a7b700f653cd7e9cdc7",
            "blockindex": 1,
            "outputindex": 1,
            "blocktime": "2019-08-07T08:20:50Z",
            "burn-fee": -0.05,
            "bond-value": 1.3,
            "unspent-tip-address-base58": "mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw"
        }
    ]
}
mattcollier commented 5 years ago

I recommend changing the publicKey owner property to controller as shown here: https://gist.github.com/mattcollier/c0b673cef7a764a85c12c813d4ca76ad

You'd want to use the following URL for the latest DID context which does actually resolve to a context document: https://w3id.org/did/v0.11

Another context to be aware of is: https://github.com/w3c/web-ledger/blob/gh-pages/contexts/webledger-v1.jsonld

Which is available from https://w3id.org/webledger/v1

If the blockIndex here is a 0 based, then it would map nicely to blockHeight in the WebLedger context. We would need to see SatoshiAuditTrail and all it's properties defined somewhere.

Also, we want to see all the key terms defined in one of these two contexts: https://github.com/w3c-dvcg/security-vocab/tree/master/contexts

publicKeyHex for instance is not yet defined in the security context.

mattcollier commented 5 years ago

Also, I think it's just a typo, but there should be agreement on the key type as EcdsaSecp256k1VerificationKey2019 in all the places. The key type given in authentication of EcdsaSecp256k1AuthenticationKey2019 is not a thing.

mattcollier commented 5 years ago

You might also consider moving the publicKey entry object directly into authentication and not referencing it like that.

ChristopherA commented 5 years ago

@mattcollier I updated the DID context url in my example above, and in a meeting this afternoon we decided to move the audit trail to a separate structure instead of being part of the DID Document (@peacekeeper we should talk about this as a general resolver pattern). We also added endpoints where the DID Resolver can look for a continuation document or other service can look for public VCs.

However, I wasn't quite able to puzzle how to to fix the other things in your comment.

Your comments and these changes should be a discussion for our Zoom call tommorow (@kimdhamilton can you add to agenda?)

Thanks!

-- Christopher Allen

OR13 commented 5 years ago

I like the serviceEndpoint use for continuation URL.

If you want to switch from publicKeyHex to publicKeyJwk, you may find this useful:

https://github.com/decentralized-identity/lds-ecdsa-secp256k1-2019.js

mattcollier commented 5 years ago

@ChristopherA here's my suggestion based on your latest:

{
    "@context": ["https://w3id.org/did/v0.11", "https://w3id.org/btcr/v1"],
    "id": "did:btcr:xyv2-xzpq-q9wa-p7t",
    "authentication": [
        {
            "id": "did:btcr:xyv2-xzpq-q9wa-p7t#keys-1",
            // changed owner -> controller
            "controller": "did:btcr:xyv2-xzpq-q9wa-p7t",
            "type": "EcdsaSecp256k1VerificationKey2019",
            // this term is not in existing contexts, need to define term or use different encoding
            "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
        }
    ],
  "service": [
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    },
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#CRS",
      "type": "CredentialRepositoryService:BTCR",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    }
  ],
}
mattcollier commented 5 years ago

Another cut:

{
    "@context": ["https://w3id.org/did/v0.11", "https://w3id.org/btcr/v1"],
    "id": "did:btcr:xyv2-xzpq-q9wa-p7t",
    "publicKey": [
       {
            "id": "did:btcr:xyv2-xzpq-q9wa-p7t#keys-1",
            // changed owner -> controller
            "controller": "did:btcr:xyv2-xzpq-q9wa-p7t",
            "type": "EcdsaSecp256k1VerificationKey2019",
            // this term is not in existing contexts, need to define term or use different encoding
            "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
        }
    ],
    "authentication": ["#key1"],
  "service": [
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    },
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#CRS",
      "type": "CredentialRepositoryService:BTCR",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    }
  ],
}
mattcollier commented 5 years ago

with assertionMethod:

{
    "@context": ["https://w3id.org/did/v0.11", "https://w3id.org/btcr/v1"],
    "id": "did:btcr:xyv2-xzpq-q9wa-p7t",
    "publicKey": [
       {
            "id": "did:btcr:xyv2-xzpq-q9wa-p7t#keys-1",
            // changed owner -> controller
            "controller": "did:btcr:xyv2-xzpq-q9wa-p7t",
            "type": "EcdsaSecp256k1VerificationKey2019",
            // this term is not in existing contexts, need to define term or use different encoding
            "publicKeyHex": "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
        }
    ],
    "authentication": ["#key1"],
   // corresponds to the `proof.proofPurpose` that will be found on a signed VC.
   "assertionMethod": ["#key1"],
  "service": [
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    },
    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#CRS",
      "type": "CredentialRepositoryService:BTCR",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    }
  ],
}
msporny commented 5 years ago

I note that serviceEndpoints are pointing to files that may change... is that ok?

    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld"
    },

If not, you may want to create a hashlink to the serviceEndpoint so that the document can't be compromised in way that's not detectable.

One possible way using hashlinks:

    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld?hl=z87f623hkjh578v76dsf873h"
    },

Another using hashlinks:

    {
      "id": "did:btcr:xyv2-xzpq-q9wa-p7t#DCS",
      "type": "DIDDocumentContinuationService",
      "serviceEndpoint": "hl:z87f623hkjh578v76dsf873h:z876234hu5h78e96784165234h5kjl234h5bnmf"
OR13 commented 5 years ago

The fact that I can change my DID Doc by commit to git is probably one of my favorite features of BTCR so far, but I agree with manu, its a bit of a security issue. Github can change my keys anytime they want.

I don't see why its can't be a url or a hashlink, it just makes the resolver code a little bit more complicated, but its worth it for the true SSI experience, I would IPFS my ddo.jsonld.

msporny commented 5 years ago

I'm a bit concerned about this pattern:

   "authentication": ["#key1"],
   "assertionMethod": ["#key1"],

The reason Veres One doesn't (haven't checked lately, but if it does, it shouldn't) share keys between different verification methods is that authentication is a lower risk thing than making an assertion. You will probably be ok w/ an encrypted on drive key for authentication, but you should probably be using an HSM for assertion.

If you're working on a canonical example for BTCR, I suggest folding some best practices in there.

The reason we argued against publicKey is because it leads to this pattern... where you re-use the same key for everything and increase the risk of having your DID compromised as a result.

peacekeeper commented 5 years ago

@msporny :

you may want to create a hashlink to the serviceEndpoint so that the document can't be compromised in way that's not detectable.

@OR13 :

I don't see why its can't be a url or a hashlink

I'd prefer this to be a hashlink as well. I raised an issue for this on the BTCR spec a few months ago: https://github.com/w3c-ccg/didm-btcr/issues/14

On a related note, I've always felt a bit unsure whether the DID Document continuation URL should be considered a "service endpoint". Perhaps that URL is just something internal to the BTCR method's Read/Resolve operation and is used to construct the final DID Document, but the URL should not actually itself be a service endpoint in the final DID Document. It could be returned as resolution metadata instead. Just a thought, I can also see arguments for the way it is now.

peacekeeper commented 5 years ago

@ChristopherA :

in a meeting this afternoon we decided to move the audit trail to a separate structure instead of being part of the DID Document (@peacekeeper we should talk about this as a general resolver pattern).

I agree that would be cleaner. In the DID Resolution spec we're talking about a "DID Resolution Result", which contains the DID Document, resolver metadata, and method metadata:

https://w3c-ccg.github.io/did-resolution/#did-resolution-result

ChristopherA commented 5 years ago

We can't use hashlinks in the BTCR bitcoin OP_RETURN mutable URL to the continuation document for 2 reasons:

a) they are likely too long. We have a limit of 40 chars (preferred) 80 chars (max). b) The same catch-22 we have with IPFS: the DID ID needs to be in the continuation document, and it will not be known until the block is confirmed at least once, and technically 100 times.

I don't have a problem with DID Resolvers returning unsigned DID Documents that add hashlinks to any URLs. However, see next comment.

-- Christopher Allen

ChristopherA commented 5 years ago

There is a problem we are running into which is who is the intended user of a DID document. We have been putting things into DID documents that are only needed/used by the DID resolver, and don't really need to be shared further to the intended DID app relying on a DID resolver.

For instance, there is no signature on an implicit DID document, as it is "proven" by the resolver by looking at the blockchain, not by a signature.

Similarly, if a continuation document is found by a resolver, it doesn't need to pass on a continuation service, as only the resolvers uses that, and it has already resolved it. Related, it doesn't need to pass on the continuation proof block to the app, as the resolver has to verify it against the blockchain key before passing it on as well, so why pass it on?

I my next comment I'll make a more concrete proposal, given these assumptions:

-- Christopher Allen

ChristopherA commented 5 years ago

Here is a simple BTCR foundational DID transaction: a straight up P2PKH with no OP_RETURN, with an unspent output index 0. This should be the simplest BTCR DID.

You can see this transaction at https://blockstream.info/testnet/tx/be5be4b2c4e530b49af139a8448ae2ae8b5882f2e7f5c7908eca0268f72494e9

Here is my proposal for what the RESOLVER outputs to relying apps (resolvers may have some interim states that they construct, but I believe this is what the end result should look like).

{
    "@context": "https://w3id.org/did/v0.11",
    "id": "did:btcr:xg35-jzrx-qtyt-jqr",
    "publicKey": [
       {
            "id": "did:btcr:xg35-jzrx-qtyt-jqr#satoshi",
            "controller": "did:btcr:xg35-jzrx-qtyt-jqr",
            "type": "EcdsaSecp256k1VerificationKey2019",
            "publicKeyBase58": "28bvc9NGemrqeLg9mZoM7EZuXFkfWVCZQz3eX9f9QQC5t"
        },
        {
             "id": "did:btcr:xg35-jzrx-qtyt-jqr#vckey-0",
             "controller": "did:btcr:xyv2-xzpq-q9wa-p7t",
             "type": "EcdsaSecp256k1VerificationKey2019",
             "publicKeyBase58": "28bvc9NGemrqeLg9mZoM7EZuXFkfWVCZQz3eX9f9QQC5t"
         }
    ],
    "authentication": ["#satoshi"],
    "assertionMethod": ["#vckey-0"],
}

Note that in this example is only one key, but duplicated with two names:

1) The "satoshi" key is the key for whatever the current latest bitcoin transaction is, and is can used for a variety of forms authentication (for now named "authentication" but we should probably come up with something more specific). In future updates of this DID, #satoshi will always be the key of the current transaction (aka it "mutates").

2) the "#key0" key is the key to be used for Verifiable Credentials, and other proofs that use "assertionMethod" proof purpose. It is intended to be immutable, but this is not enforced. In the this first transaction, #key0 is the first of the series of keys. In the next DID update, #key1 would be a new VC key, but if #key0 is still in the revised DID document, all VCs signed by the original DID are still valid. If #key0 is not included in the revised DID document, the VC is presumed to be invalid (but not necessarily revoked-discuss this later).

Note that by this convention if someone wishes to have other VC keys in a DID Document that are not also used by a blockchain, they should not use "#vckey-X" and use another id.

There is no OP_RETURN in this transation, so there are no assumed DID endpoints. Verifiable Credentials issued by this DID will have to be bearer shared.

I have also tried to work out what would be the resolver audit output for this DID, and this requires a lot more work. @mattcollier suggested we use webledger context, which has some useful things, but is missing a lot as well. We would need to have someone like @dlongley or @msporny help resolve adding generic things that apply to multiple blockchains like audit, burn-fee, chain, network, etc. I suggest we move this to another issue, but I wanted to include this for people trying to understand the DID Document above.

{
    "@context": ["https://w3id.org/webledger/v1","https://w3id.org/btcr/v0.1"]
        "id": "did:btcr:xg35-jzrx-qtyt-jqr",
        "Audit": [  
        {
            "chain": "bitcoin",
            "network": "testnet3",
            "txid": "be5be4b2c4e530b49af139a8448ae2ae8b5882f2e7f5c7908eca0268f72494e9",
            "txref": "txtest1:xg35-jzrx-qtyt-jqr",
            "blockhash": "0000000000000011fd70846401c79e3b04ba2f0b75c6d160cbaae71287a9c1b7",
            "blockHeight", "1354004",
            "transaction-index": "195",
            "transaction-output-index": "0",
            "created": "2018-07-16T22:45:25Z",
            "burn-fee": -0.05
            "bond-value": 1.3,
            "bond-address": "mooh9yq5aV4u5gSR9oRZGfYS9qbydBVLjA"
        }
    ]
}

-- Christopher Allen

ChristopherA commented 5 years ago

In parallel to the simple example above, here is what an implicit DID returned by a DID RESOLVER would be for a transaction that has an OP_RETURN, but the OP_RETURN has no valid continuation document, thus the DID Document has to be constructed by the DID Resolver.

You can see this transaction at https://blockstream.info/testnet/tx/f8cdaff3ebd9e862ed5885f8975489090595abe1470397f79780ead1c7528107 where you can see that the output 0 is confirmed unspent.

{
    "@context": ["https://w3id.org/did/v0.11", "https://w3id.org/btcr/v1"],
    "id": "did:btcr:xyv2-xzpq-q9wa-p7t",
    "publicKey": [
       {
            "id": "did:btcr:xyv2-xzpq-q9wa-p7t#satoshi",
            "controller": "did:btcr:xyv2-xzpq-q9wa-p7t",
            "type": "EcdsaSecp256k1VerificationKey2019",
            "publicKeyBase58": "owh12LKNuphe97teJTZKQTKNewSVTwjHcskPbq34epCY"
        },
        {
             "id": "did:btcr:xyv2-xzpq-q9wa-p7t#vckey-0",
             "controller": "did:btcr:xyv2-xzpq-q9wa-p7t",
             "type": "EcdsaSecp256k1VerificationKey2019",
             "publicKeyBase58": "owh12LKNuphe97teJTZKQTKNewSVTwjHcskPbq34epCY"
         }
    ],
    "authentication": ["#satoshi"],
    "assertionMethod": ["#vckey-0"],
    "service": 
      {
        "id": "did:btcr:xyv2-xzpq-q9wa-p7t#CRS",
        "type": "BTCR-CredentialRepositoryService",
      "serviceEndpoint": "https://github.com/ChristopherA/self/blob/master/ddo.jsonld?hl=z87f623hkjh578v76dsf873h"
      },
}

Notes:

Still some open questions: I'm increasingly feeling like the block creation timestamp proof date and the DIF resolution date needs to be in the DID document offered by the DID Resolver, and not only in the audit trail.

-- Christopher Allen

ChristopherA commented 5 years ago

Still some open questions: I'm increasingly feeling like the block creation timestamp proof date and the DIF resolution date needs to be in the DID document offered by the DID Resolver, and not only in the audit trail.

Frustrated here, as I realize if continuation DID documents replace the implicit ones, they can't have this information.

-- Christopher Allen

ghost commented 5 years ago

@ChristopherA - In your did:btcr:xg35-jzrx-qtyt-jqr example above, what is producing did:btcr:xg35-jzrx-qtyt-jqr#vckey-0 if this is from a transaction that has no OP_RETURN? I see the note "resolvers may have some interim states that they construct, but I believe this is what the end result should look like", but in this case no continuation doc and no spent tip.

Would it not be like below, in this case and similarly in others without a continuation document?

{
    "@context": "https://w3id.org/did/v0.11",
    "id": "did:btcr:xg35-jzrx-qtyt-jqr",
    "publicKey": [
       {
            "id": "did:btcr:xg35-jzrx-qtyt-jqr#satoshi",
            "controller": "did:btcr:xg35-jzrx-qtyt-jqr",
            "type": "EcdsaSecp256k1VerificationKey2019",
            "publicKeyBase58": "28bvc9NGemrqeLg9mZoM7EZuXFkfWVCZQz3eX9f9QQC5t"
        }
    ],
    "authentication": ["#satoshi"],
    "assertionMethod": ["#satoshi"]
}

I understand using the same authentication & assertionMethod may be a concern, but the alternative would be to not allow an assertionMethod at all if no continuation doc, and thus not allow vc signing w/ bitcoin keys, right?

ghost commented 5 years ago

This PR to btcr-did-tools-js should produce what was discussed above and now in the spec: https://github.com/WebOfTrustInfo/btcr-did-tools-js/pull/9

ChristopherA commented 5 years ago

They are the same key, duplicated, and in a BTCR DID without an OP_RETURN, the DID resolver constructs a DID document with both keys having the same value.

The idea is that the #satoshi key can be relied on as being the current key for every DID update transaction and thus is ephemeral over time, whereas #vckey-0 in transaction #0 would persist over time and could optionally be permitted as a VC assertionMethod in future DID Documents (which would require an OP_RETURN) even though they are deprecated for authentication after the DID update.

The idea is that in the next transaction #1, the #satoshi key from #0 would be deprecated, and only the updated #satoshi could be used as an authentication key. In addition, VCs signed by transaction #1 key named #vckey-1 would be valid, and IF there was an OP_RETURN continuation document, the continuation document could allow #vckey-0 to still be used as assertionMethod for verifiable claims made by the #0 transaction.

-- Christopher Allen