w3c-ccg / did-method-web

DRAFT: did:web Decentralized Identifier Method Specification
https://w3c-ccg.github.io/did-method-web/
Other
31 stars 16 forks source link

Decide what to do about 'proof' section and other DID Doc Metadata #20

Open dmitrizagidulin opened 3 years ago

dmitrizagidulin commented 3 years ago

Signing the DID Document itself (adding an OPTIONAL/recommended proof section, for example) would offer integrity protection / move towards the did docs being self-certifying.

Since the proof property (as well as other metadata fields such as created and updated) were removed from the DID Core spec, we need to make a decision on how to handle these in the did:web method.

Our options:

  1. Put the metadata fields (proof, created etc) into the DID Document itself.
  2. Store not the DID Document in the .json file on the web server, but instead embed it in a structure similar to the DID Resolution Result.

Example structure for option 1:

{
    "@context": "https://www.w3.org/ns/did/v1",
    "id": "did:web:example:com",
    "authentication": [{
        "id": "did:web:example:com#keys-1",
        "type": "Ed25519VerificationKey2018",
        "controller": "did:web:example:com",
        "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }],
    "service": [{
        "id": "did:web:example:com#vcs",
        "type": "VerifiableCredentialService",
        "serviceEndpoint": "https://example.com/vc/"
    }],
    "proof": {
        // signature over the whole DID document would go here.
    },
    "created": "2019-03-23T06:35:22Z",
    "updated": "2023-08-10T13:40:06Z"
}

Example structure for option 2:

{
    "@context": "https://w3id.org/did-resolution/v1",
    "didDocument": {
        "@context": "https://www.w3.org/ns/did/v1",
        "id": "did:web:example:com",
        "authentication": [{
            "id": "did:web:example:com#keys-1",
            "type": "Ed25519VerificationKey2018",
            "controller": "did:web:example:com",
            "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
        }],
        "service": [{
            "id": "did:web:example:com#vcs",
            "type": "VerifiableCredentialService",
            "serviceEndpoint": "https://example.com/vc/"
        }],
                "proof": {
                    // signature over the whole DID document would go here.
                }
    },
    "didDocumentMetadata": {
        "created": "2019-03-23T06:35:22Z",
        "updated": "2023-08-10T13:40:06Z"
    }
}
awoie commented 3 years ago

@dmitrizagidulin Is it correct to say that option 2) might be the more standard way of doing it because it these are registered terms in DID Document Metadata Properties? Option 1) will require extensions to context. Further, would be the proof contain a detached JWS?

dmitrizagidulin commented 3 years ago

@awoie - hmm, good question. Option 2 (the DID Resolution Result) is still very much in progress, spec wise. Buuut, you're right, we don't want to mess with the context in option 1.

And now that I think about it, if we adopt option 2, it'll give us room to put things like the optional 'audit trail' (KERI-like), and other sorts of metadata.

dmitrizagidulin commented 3 years ago

@OR13 - do you have any strong preferences here?

OR13 commented 3 years ago

I personally don't like the idea of attaching proofs to did:web.... I had done the same thing with did:github, and it made it super frustating to update.... we even tried getting github actions to add the proof, which worked but is still not as elegant as just relying on the web server... I guess end of the day, if you really need the extra security, you can sign your did document.

just be prepared to manage all the update complexity that comes with that.

OR13 commented 3 years ago

regarding "audit trails".... I think this is a waste of time... did web is not meant to be like other did methods, and leaving some obvious reasons to upgrade for higher security scenarios makes sense.

The simpler the spec, the better, did:web should be a gateway to better did methods, not try to compete with them.

dmitrizagidulin commented 3 years ago

@OR13 I see, ok. That still leaves the question open about what to do with "did doc metadata" and did:web. Which option do you prefer?

OR13 commented 3 years ago

@dmitrizagidulin I prefer to pull caching / expiration / headers from the resource and simply reflect them in the did doc meta data.

dmitrizagidulin commented 3 years ago

@OR13 got it, ok. So that seems like a vote for option 2.

awoie commented 3 years ago

@mirceanis would also be good to get your opinion on that.

mirceanis commented 3 years ago

I also don't see a good reason to add proof section to the did doc. Perhaps I'm not grasping it completely but it seems to me that it serves only as decoration and does not add any more trust to the result, while also complicating any implementation. I very much like the idea about the metadata, if any, being compiled from the headers instead of being written to the json document.

mirceanis commented 3 years ago

@OR13 got it, ok. So that seems like a vote for option 2.

I'm not reading it that way :)

Also, I'm not putting any weight on either of the two options presented. I guess I'm opting for a third where the JSON that is served is the actual DID document and the server is free to present metadata as headers. It would be the resolver's option to present some of the headers as metadata.

dmitrizagidulin commented 3 years ago

So, the reason I'm reading it as a vote for Option 2 is -- the question here is what's the data model of a did:web DID Doc stored on disk. In order for the web server to present those metadata headers, it's gotta get them from somewhere. Which assumes the need for an envelope document like in option 2.

@mirceanis

it seems to me that it serves only as decoration and does not add any more trust to the result

But it does add one important part to the result - it adds the fact that the DID Document has not been tampered with (it's signed by the DID controller...).

dmitrizagidulin commented 3 years ago

And just to clarify, with option 2, the proof would not be in the DID Doc itself. It would be in the metadata section of the 'resolution result' data structure.

mirceanis commented 3 years ago

So, the reason I'm reading it as a vote for Option 2 is -- the question here is what's the data model of a did:web DID Doc stored on disk. In order for the web server to present those metadata headers, it's gotta get them from somewhere. Which assumes the need for an envelope document like in option 2.

So this would be applicable to documents that are served by "dumb" webservers, where the DID controller does not have too much control over the returned headers, right?

... But it does add one important part to the result - it adds the fact that the DID Document has not been tampered with (it's signed by the DID controller...).

The reason why it looks like ceremony to me is that did:web already relies a lot on the trust in the webserver. If the DID document is hosted or intercepted by a malicious server, it could very well replace the document entirely, including the DID controller and proof and a client would never be able to tell the difference unless some other out of band mechanism is in use.


On a separate note, I'm not very familiar with how DID document metadata is supposed to be used in practice, so my opinions here should not carry much weight. If there is a proof section being served next to the DID document, who is supposed to verify it? if it's the resolver, then what types of proofs are accepted/recommended? It complicates things a lot for a DID method that is supposed to be a bridge between old infrastructure(with its own cryptographic guarantees) and the new.

OR13 commented 3 years ago

proof was removed from did core, and IMO, it's best not to use it at all on did documents.... trust in a did document should come from the DID Method and the VDR and the DID Controller OpSec.

if the proof is being used to pull the created timestamp... thats complicated, and as already pointed out, anyone with control of the web server can replace all of this... so proof does not add anything regarding trust... imo, its pure complexity and should be removed.

dmitrizagidulin commented 3 years ago

@mirceanis

So this would be applicable to documents that are served by "dumb" webservers, where the DID controller does not have too much control over the returned headers, right?

That's right, yeah. Which applies to a large chunk of the use cases did:web is addressing.

If there is a proof section being served next to the DID document, who is supposed to verify it? if it's the resolver, then what types of proofs are accepted/recommended?

I'm not sure if I fully understand the question. It's exactly the same as with Verifiable Credentials. Whoever is consuming the DID (so, holder, verifier, etc) can verify it. And which type of proofs - whatever the DID Method (or even your use case) agrees on.

@OR13

it's best not to use it at all on did documents.... trust in a did document should come from the DID Method and the VDR and the DID Controller OpSec.

So.. again, that seems like an argument for Option 2. "Trust in the VDR and DID Method" -- so, having a proof in the Resolution document (not the DID Document) increases trust in the VDR and the DID Method.

OR13 commented 3 years ago

@dmitrizagidulin JSON-LD Proofs do not help increase trust with did:web. IMO, did:web should not have any normative requirements on JSON-LD Proofs.

did:web trust flows from web server control, and proof gives a false sense of security given this.

dmitrizagidulin commented 3 years ago

@OR13 but again, the question is not about proof specifically, or JSON-LD Proofs in general. (They are certainly not required). The main thing that we have to decide is - what should we do about any sort of metadata in the did document, with did:web.

dmitrizagidulin commented 3 years ago

@OR13 so far, if I'm understanding your argument correctly, you seem to be saying "no metadata in the DID Document at all". I think that's too limiting, and that there are several use cases that would be well served with a general metadata mechanism, on the data model level.

OR13 commented 3 years ago

Yes, the DID WG has decided specifically to not put meta data in the did document, and the did spec registries has a separate section to make this even clearer: https://w3c.github.io/did-spec-registries/#did-document-metadata

I'm not against some "extension" which places meta data in the did document, but I think encouraging meta data in the did document generally for did web will be viewed as wrong by anyone familiar with other did methods.

dmitrizagidulin commented 3 years ago

@OR13 I remember that debate, sure. And one of the points that was made was -- the metadata belongs in the Resolution Result document. Which is exactly what we're talking about / proposing here.

OR13 commented 3 years ago

https://github.com/transmute-industries/did-key.js/blob/master/packages/did-key-common/src/getResolver.ts#L113

https://w3c-ccg.github.io/did-resolution/#output-resolutionmetadata https://w3c-ccg.github.io/did-resolution/#output-documentmetadata

^ all of these are places that are fine to put metadata imo...

OR13 commented 3 years ago

I assume we are talking about the normative requirements did:web has on "resolution metadata" and "document metadata"

This issue is not very specific, and appears to be addressing both proof and meta data, hence the confusion.

OR13 commented 3 years ago

To be crystal clear:

  1. There should be no meta data in a did:web did document (no proof, updated or created).
  2. I am ok with updated and created in did document meta data.
dmitrizagidulin commented 3 years ago

@OR13 ok, that seems pretty clear. (And like I said, that is exactly Option 2. Using the Resolution Result doc, which has 3 sections, the didDocument itself, the resolution metadata, and the didDocumentMetadata.)

dmitrizagidulin commented 3 years ago

@OR13 so the next question is.. so what does that look like, implementation wise? Is the .json file that's stored on a website - does it hold the overall Resolution Result doc, with the 3 sections? And then the resolver fetches that, does its thing, and only returns the didDocument part? That's kind of what I'm leaning towards.

OR13 commented 3 years ago

@dmitrizagidulin yes, imo, it should be possible for the web server operator to control all 3 sections via vanilla JSON.

I would not be opposed to fancy HTTP Header based overrides for the did:web resolver to consider as well.

While we are on this subject, we might as well also consider did:web in JSON / CBOR / YAML...

IMO, a did web resolver builds a URL from https://w3c-ccg.github.io/did-resolution/#resolving-input

Makes a GET Request to the URL, and optionally considers headers returned in the response as taking priority over the field members.

OR13 commented 3 years ago

did:web resolvers should implement:

resolveRepresentation ( did, did-resolution-input-metadata )
     -> ( did-resolution-metadata, did-document-stream, did-document-metadata )

over http... they should support representations other than JSON, such as CBOR.

I think its fine to "default them" to JSON, but we should allow to different JSON / JSON-LD at a minimum.

kdenhartog commented 3 years ago

Just to chime in here as well, I'm leaning more towards the direction of option 2 over option 1. I don't see many benefits to option 1 that don't eventually lead to did:web ending up diverging from many other expected usage patterns of other did methods (e.g. metadata in a separate portion of the did resolution result).

On the topic of representation I think what Orie brings up is a potential answer to supporting multiple representations by storing multiple representations on the server independently. This does open the potential for the different representations to be in different states though, so I lean more towards the option of having a resolver fetch the JSON representation translating it to the ADM and then translating it to the requested representation instead. The downside to this approach is that different representations will likely have different signature formats used such that some requesting parties (the client of the resolver doing the translator) may be unable to verify the signature method of the JSON representation.

However, as @mirceanis points out here there are ways to subvert the integrity of document in ways that aren't going to be detectable. At best for these types of things we'll want to state "MUST use TLS 1.2 or greater" and warn about DNS injection issues in the security section as well.

dmitrizagidulin commented 3 years ago

Just as an update -- as the DID Core spec is nearing its first CR, the editors of the did:web spec are actively discussing this topic.

OR13 commented 3 years ago

did web documents should not be signed with LD Proofs... its security theater... web admin can alter the proof... unless we are going to make did:web 100% dependent on LD Proofs, this is a feature that should removed from the spec, what people do with their own JSON-LD is their business, but I see no reason for did:web to endorse use of LD Proofs for anything.

I'd recommend doing this:

  1. application/did+json and application/did+ld+json both resolve to the same .json file on a web server.
  2. avoid discussing LD Proofs in the DID Web Spec.

Don't try and support CBOR yet, it's clearly not ready to be looked at seriously.

awoie commented 3 years ago

I think that most people are in agreement that Option 2 is the better option to support DID Doc Metadata--I'm not talking about the proof property. I think we might be even ready to provide a PR for the spec changes?

@dmitrizagidulin do you think that makes sense?

awoie commented 3 years ago

On a separate note, we should discuss whether other properties of the DID Doc Metadata such as versionId would require a spec change or if this can be done by the implementers themselves?

vitorpamplona commented 1 year ago

did web documents should not be signed with LD Proofs... its security theater...

Is it? What about caching systems? If the original web server signs a DID Document, no web mirrors worldwide can change it's contents. I think that is a real feature for enterprise systems.

I have to define a DID Document and I am exploring signing possibilities to increase the security of redistribution. Any ideas are welcome.

gribneau commented 1 year ago

+1

The proportion of modern web traffic that runs through external third parties that terminate SSL in edge data centers (CDNs) is large.

In this scenario, a signature adds another layer of verification beyond the base SSL to prevent tampering prior to delivery.

dmitrizagidulin commented 1 year ago

+1, that is a good point.

mirceanis commented 1 year ago

How would the resolver verify the integrity of the DID document?

vitorpamplona commented 1 year ago

How would the resolver verify the integrity of the DID document?

In my use case, the resolver has had direct access to the signer (or the trust registry the signer belongs to) in a previous event to collect and store an anchor of trust (x509 cert) for that signer. That anchor is hard coded in the resolver and the complete chain is verified at every resolve.

mirceanis commented 1 year ago

But do you think this would be the case for every did:web? I'm trying to figure out how this would look like from a spec perspective.

gribneau commented 1 year ago

Could it be optional and flexible?

I can foresee a scenario in which people might like to self-certify with a proof and then simply serve a static file including that proof over some large CDN provider.

vitorpamplona commented 1 year ago

But do you think this would be the case for every did:web? I'm trying to figure out how this would look like from a spec perspective.

I am not sure. But I don't see any point in having a key-resolving mechanism that is not cryptographically secure. In other words, what's the point of downloading a keyset document that an intermediary infrastructure can tweak around? What would the keys be good for if the environment is unsecured?

So, either the web infrastructure at play provides the security needed or the document itself must be signed. If users don't see a way to fully close all security loopholes their web infrastructure provides, users must choose the latter. If the spec doesn't offer that option, only a small subset of the web infrastructure can be used to provide DID:webs. For instance, by not having an optional proof element, you might be self-selecting the spec to only work inside secured VPNs.

mirceanis commented 1 year ago

I don't disagree with the necessity of securing here. I'm trying to understand how you think it would look from a resolver/verifier perspective. How does the proof provide anything extra over the TLS certificate checks?

Also, in these scenarios how do mirrors and CDN come into play, wouldn't they use different URLs? (sorry if this is an ignorant question, I'm trying to understand)

gribneau commented 1 year ago

Also, in these scenarios how do mirrors and CDN come into play, wouldn't they use different URLs?

Mirrors operate on their own domains with their own SSL certificates.

CDNs, on the other hand, can take over an entire domain and terminate TLS on behalf of that domain.

Speaking generally, to put a CDN in front of an origin, one points the appropriate DNS A records to the CDN IP addresses (generally a pair of v4 IPs, routed via BGP Anycast to geographically distributed "edge" locations that are located close to population centers where the clients will be). The CDN then is, from the point of view of clients, the target website.

The CDN "origin" is configured, often with the original address(es) of the webserver(s) that produce the content (including the did:web documents) and a host header with the domain name. The CDN edge servers request content from the origin server, cache that content, and deliver it to many clients.

The clients resolve the A records to the target domain name and receive the CDN BGP Anycast addresses. Each edge data center advertises those same routes, and the client traffic reaches the nearest edge data center, where the CDN servers handle SSL and respond to the client request.

OR13 commented 1 year ago

I am fine with folks profiling on top of did web, adding various other JSON members to it, including "data integrity proofs"... I don't think the method spec is the right place to talk about that kind of thing, since it applies to all "did documents"... better to do that at a resolver layer, or in a specific profile of did web...

OR13 commented 1 year ago

I'd like to close this issue, since I don't see us reaching any form of consensus on requiring or allowing data integrity proofs in the did web spec... and there are better places to have that discussion.

gribneau commented 1 year ago

Fair enough.

there are better places to have that discussion.

Is there any specific place this conversation should happen?

vitorpamplona commented 1 year ago

I wouldn't dismiss the importance of specifying the correct, universally-accepted way to sign a did web. Even if the place is not in the spec itself, there must be a tight spec somewhere. Implementers shouldn't be just doing whatever they want in this. Otherwise, we are going to have an interoperability hell to correctly resolve did:webs.

vitorpamplona commented 1 year ago

There is this note in the DID-Core spec:

Some DID methods allow digital signatures and other proofs to be included in the DID document or a 7.3 Metadata Structure. However, such proofs by themselves do not necessarily prove control over a DID, or guarantee that the DID document is the correct one for the DID. In order to obtain the correct DID document and verify control over a DID, it is necessary to perform the DID resolution process as defined by the DID method.

It seems to say that the proof that guarantees that the DID document is the correct one should be specified by the DID resolution process of the DID method. So, it should be in the DID:WEB spec.

It also seems to make a distinction between "the correct one" (infrastructure proof) and "hasn't been changed" (application proof), which are different proofs.

vitorpamplona commented 1 year ago

The question is: where does each proof type go and how does it get there? Where does one store the proof section, such that resolvers can verify it if it's not in the did.json itself? Is there another file that the resolver hits to download the proof itself to put into the DID Resolution Result? Or should it be transferred over the HTTP headers of the did.json GET call? If so, how does the mapping between the section and the headers work?

kdenhartog commented 1 year ago

Fair enough.

there are better places to have that discussion.

Is there any specific place this conversation should happen?

I'd say this fits way better within the context of did-resolution since this is a generic problem of a resolution protocol and resolution implementations. Trying to stuff this into a data model spec seems wrong and that security consideration was likely just because we've always known this was a problem and wanted to make people knew about the issue as they were writing the method (which really should be considering resolution considerations as well IMO)

I'd be curious what @peacekeeper take is on this as well