openwallet-foundation / acapy

ACA-Py is a foundation for building decentralized identity applications and services running in non-mobile environments.
https://aca-py.org
Apache License 2.0
421 stars 515 forks source link

Implement did:web registry #2369

Open dbluhm opened 1 year ago

dbluhm commented 1 year ago

Following the example of the Legacy Indy registry, implement a registry for did:web. This registry will require a backend interface for publishing anoncreds objects to a web server. This backend can behave very similarly to the indy-tails-server and it may be beneficial to start from it as a base. The identifiers used by this method are not currently defined in a spec specifically for did:web; we should follow the same pattern as the did:indy spec and construct DID URLs matching those used by did:indy.

PatStLouis commented 1 year ago

Hi @dbluhm, I worked on an implementation of did:web and anoncreds a while back with @genaris. I have presented this implementation to the w3c-ccg and the hyperledger anoncreds group with a positive feedback. The registry is something we have put some thought into. We would be happy to share our findings and discuss the best way forward.

Please see this issue I've opened on the did:web spec regarding identifiers and share your thoughts! https://github.com/w3c-ccg/did-method-web/issues/75

genaris commented 1 year ago

You can find more information about did:web AnonCreds method in the registry and current spec draft.

dbluhm commented 1 year ago

Interesting; the discussion on the linked issue had some unexpected commentary. I think the opposition to using paths is unfounded, to put it bluntly. As mentioned, they're virtually unused at this point and the DID core spec does not preclude its use for referring to resources external to the doc. At this point in time, only fragments are consistently used and they are the component that is used to refer to items internal to the document.

I'm not strongly opinionated and it's unlikely right now that I'll be the one to implement the registry in ACA-Py myself but I personally feel that the approach taken by the did:indy method is preferable to query parameter based URLs.

swcurran commented 1 year ago

I agree that the interpretation in that discussion is wrong about DID URLs referring to internal elements of the DIDDoc in all cases. The spec. explictly states that DID URLs are comparable to HTTP URLs, such that fragments (“#”) refer to internal elements of the DIDDoc, while paths (“/“) and query parameters (“?”) do not. We went over this in did:indy where we use the pathing to provide data about AnonCreds objects. We plan to make use of this in “did:webs”, where the path is to be used to access any file, along with a signature across the file content. This has been reviewed by experts in DIDs — those that wrote the spec, such as Markus Sabadello.

genaris commented 1 year ago

I've started AnonCreds did:web method using an approach similar to the one used for did:cheqd (using linked resources), but we switched to this other more accepted method based on the feedback we had in that discussion (where some of did:web authors were involved).

If we are about to use a new did method, such as the did:webs you mentioned, I think it's perfectly possible to define whatever way we want. In the end I think we are all be using this newer did:webs so we'll not encounter any objection to use this approach.

PatStLouis commented 1 year ago

One key element that I would strongly suggest is the use of hashlinks.

The did indy method has the following resources uri scheme <did>/<object-family>/<object-family-version>/<object-type>/<object-type-identifier>

The object-type-identifier relies on a transaction ID as a unique identifier for all cases except the schema, where the version is used instead. The web registry code might not keep track of transactions in the same way (TBD).

Another issue is data integrity. This is inherent to blockchain technology so whichever document you retrieve you know hasn't been altered. With web resources, you have no way of knowing this unless you have a checksum to validate the file content, where hashlinks come in. Embedding this hashlink in the ressourceID can allow the recipient to validate that the data hasn't been altered. I think using a hashlink as the object-type-identifier is a great workaround that would take care of both these issues.

This would be my interpretation of a ressourceID for an AnonCreds Web Registry Service, regardless of the resource type: did:webs:registry.anoncreds.example.com:<did>/zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e -> https://registry.anoncreds.example.com/<did>/zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e

Or a mix of indy with hashlinks did:webs:registry.anoncreds.example.com:<did>/anoncreds/v0/<object-type>/zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e -> https://registry.anoncreds.example.com/<did>/anoncreds/v0/<object-type>/zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e

For the backend service, wouldn't an api with a redis storage be more efficient than a file server as a registry?

swcurran commented 1 year ago

With did:webs we plan to use the messiness of hashlinks. We plan to have a file with a companion JWS file that has a payload of the hash of the file, signed by a key in the DIDDoc (or from its since rotated key from the DIDDoc. This is (IMHO) much cleaner than hashlinks. The file can be retrieved, the JWS retrieved and the file verified for both intentional publishing by the DID controller and tamper-evidence. That goes much further than hashlink.

See the draft specification and note the “signed files” section: https://dhh1128.github.io/did-method-webs/index.html

The spec should be moving soon to ToIP.