w3c-ccg / did-method-web Goto Github PK
View Code? Open in Web Editor NEWDRAFT: did:web Decentralized Identifier Method Specification
Home Page: https://w3c-ccg.github.io/did-method-web/
License: Other
DRAFT: did:web Decentralized Identifier Method Specification
Home Page: https://w3c-ccg.github.io/did-method-web/
License: Other
There is a lot of translation that's done with a did:web URL that feels like it could be simplified. For example, why don't we just require that all DID URL paths are absolute?
did:web:did.example/did.json // site-wide DID
did:web:did.example/alice.json // specific entity DID
did:web:did.example/some/arbitrary/path/foo.json // you can place DIDs at arbitrary paths
I just checked DID syntax, all the above is valid IIUC... why aren't we just doing that instead? It would allow people to just replace "https://" with "did:web:" to get a valid DID Web URL.
I'd like to see established global identifiers become translatable to new DID identifiers so that people don't have to remember/learn a new identifier. In particular, I find email addresses to be a) one of the few globally accepted and widely spread identifiers and b) built on the DNS system like did:web is.
Therefore, I propose to extend this specification with a translation mechanism from email addresses to did:web DIDs, e.g. [email protected] -> did:web:example.com:john.doe
/ https://example.com/john.doe/did.json
. In my understanding, this translation is mainly relevant for implementers of user interfaces that request identifiers from users to ease their way into SSI and to hide DIDs from them.
I see the following issues with this proposal:
Non-goals:
?? -> did:web:example.com:accounts:sales:john.doe
Without the standardization of email to DID translation, implementers could still choose to follow the proposal and try to resolve the corresponding DID. However, chances of success would be higher if the standardization existed and server operators would naturally adopt the mechanism.
I'd love to hear your thoughts on this idea.
Can we go ahead and make this a final CG Draft?
In w3c document they have mentioned the diddocument structure for Secp256 and jsw2020
https://w3c-ccg.github.io/did-method-web/
Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Headers DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified$
Options +FollowSymLinks
RewriteEngine on
# DID web via redirect
# RewriteRule ^did:web:(.+)$ https://did-web.web.app/api/v1/identifiers/did:web:$1 [R=302,L]
# http://localhost:8080/did:web:vc.did.ai
RewriteRule ^did:web:([a-zA-Z0-9/.\\-_]+)$ https://$1/.well-known/did.json [R=302,L]
# http://localhost:8080/did:web:did.actor:alice
RewriteRule ^did:web:([A-Z|a-z\.]+)(?::)([a-zA-Z0-9/.\-:\\_]+)$ https://$1/$2/did.json [R=302,L]
# http://localhost:8080/did:web:did.actor:alice:1
RewriteRule ^did:web:([A-Z|a-z\.]+)(?::)([a-zA-Z0-9/.\-:\\_]+)(?::)([a-zA-Z0-9/.\-:\\_]+)$ https://$1/$2/$3/did.json [R=302,L]
# DID web via url rewrite
# http://localhost:8080/did:web:did.actor:supply-chain:manufacturer:stacy
RewriteRule ^did:web:([A-Z|a-z\.]+)(?::)([a-zA-Z0-9/.\-:\\_]+)(?::)([a-zA-Z0-9/.\-:\\_]+)(?::)([a-zA-Z0-9/.\-:\\_]+)$ https://$1/$2/$3/$4/did.json [R=302,L]
If someone who is better with htaccess and regex can clean this up, we don't need a did web resolver any more.
Mine is missing, this is a note for me to fix that.
There's some odd edge cases that we'll want to be able to specify with greater detail.
For example how should the following DIDs be parsed?
did:web:example.com:
did:web:example.com.:
did:web:example.com..:
did:web:example.com:.:.:path
did:example%2ecom:path
There's probably more, but I think this exemplifies the problem around the different edge cases encountered with URLs
The use of did:web based identifiers assigned to Authoritative Issuers (especially when the issuer is a Sovereign which needs to be public and transparent and visible in identifying itself in digital transactions) such that they can bootstrap from existing infrastructure they already own, operate and trust (DNS and Web) looks to be important for both adoption as well as legitimacy and transparency i.e. Authoritative issuers of credentials and attestations should not, and do not have the luxury of hiding behind pseudonymous or anonymous identifiers; they need to be visible to be held accountable.
However, there may be potential privacy/tracking/correlation concerns in using the did:web method to assign a DID to a holder/subject or a verifier (when that verifier is a person and not an organization).
Does it make sense to limit and constrain the use of did:web to Non-Person Entities (NPEs) i.e. Organizations, Devices etc. ONLY given the ability of an organization to assert control over their Web and DNS infrastructure, and deliberately make the use of did:web for use as an identifier for a person to be out of scope?
Additionally, implementors should be aware of issues presented by a Spoofed DNS records where the record returned by a malicious DNS Server is inauthentic and allows the record to be pointed at a malicious server which contains a different DID Document. To prevent this type of issue, usage of DNSSEC which is defined in RFC4033, RFC4034, and RFC4035.
The point of having the server authenticate via HTTPS is to not have to rely on DNSSEC here.
When performing the DNS resolution during the HTTP GET request, the client SHOULD utilize
in order to prevent Man-in-the-middle attacks as well as to prevent tracking of the lookup.
Should utilize what?
Consider https://foo:[email protected]
. How is that supposed to be mapped?
If the user component is not permitted, document that explicitly. Alternatively make an example that shows how this is mapped.
This seems like a security considerations aspect but it's become apparent to us that in scenarios where the did:web is being used by an issuer for credentials that are verifiable in offline scenarios a caching strategy is necessary. While this is a more general pattern that needs to be considered such as what's mentioned in the did-resolution draft spec, do we want to make mention of it within this spec as a security considerations aspect? Something to consider here is that by relying on the cache we can help to solve some of the privacy issues from phoning home to get the most recent did document as well.
The spec outlines a basic concept for integrity protection, but it leaves a few important aspects unclear.
Lines 533 to 551 in 3302643
Like, how would the verifier know, which registry is used to store the hashes and who is authorized to add hashes for the corresponding DID?
This should be clearly defined in a spec (did web or an extension to it) and if some of the information can be dynamic (e.g., where the hashes are stored), it may be part of the DID URL itself.
Without further specification how integrity protection works in detail, I don't see how it helps at all to protect integrity of the DID documents.
Is there an implementation of this approach or more details that you could provide?
Currently this is all unspecified. We should define this method's CRUD operations in the form of HTTP GET, POST, UPDATE and DELETE (or a subset thereof).
by creating the DID in WEB method the verifiable credential can be verified from the third party verifiers??
creating DID in web method will visible to verifier to access the VC??
For use in web browsers, did:web
providers may need to set headers in the HTTP response for the DID document, for Cross-Origin Resource Sharing (CORS).
To enable any web origin to resolve the DID, the DID Document HTTP response can include the following header:
Access-Control-Allow-Origin: *
cc @sbihel
@awoie - would you object if we converted the spec from Bikeshed markdown to ReSpec HTML?
We should probably mention both in the spec, see also whatwg/url#498
There is no authentication or authorization mechanism applied to the DID Document, leaving it unprotected from modification by an attacker.
We have a number of open issues regarding different representation types, file extensions, and mime types that have been floating around for a while now (#8 #15 #20 #41). I think we are also not in compliance with the IANA Considerations section of the core spec at this point.
Resolving these issues gracefully seems likely to compel us to modify the simple resolution schema. A file named did.json
should not contain, for example, CBOR or YAML, and setting the appropriate content type without changing the file extension strikes me as a poor workaround.
Beginning with the core spec, we should be minimally supporting at least two representations:
.didjson
application/did+json
.didjsonld
application/did+ld+json
We can accomplish this by changing the URL resolution logic and relying on webserver configuration to return an appropriate file and set the proper content type by resolving to a directory containing multiple representations rather than a file.
did:web:example.com:charlie
https://example.com/charlie/
In this scenario, the webserver would be configured to recognize a number of index files, each with the appropriate file extension. These file extensions would also need to map to the appropriate content types.
charlie/did.didjson
charlie/did.didjsonld
charlie/did.cbor
We could require that simple json be accepted for all resolutions to support dumb webservers, but recognize the accept
request header to prioritize other formats on servers that are capable of handling that logic.
Accept: application/did+ld+json
Accept: application/cbor
Accept: application/did+json
The additional complexity should all be entirely optional so that a simple webserver hosting a simple .didjson
file will work today, but there is a path available to those who need other representations.
This would require modifying the URL resolution logic (and also the existing resolvers that have been implemented), but I think it would make more sense in the end.
What does everyone think?
When implementing did:web
resolution, I noticed the reference implementation checks the ID of the resolved document v.s. the input DID (https://github.com/decentralized-identity/web-did-resolver/blob/master/src/resolver.ts#L40).
This is not mentioned in the did:web
specification, but should probably be the last resolution step (https://w3c-ccg.github.io/did-method-web/#read-resolve).
Add the current methods of binding domain names to did:web
DIDs that are being implemented:
/.well-known
configurations.alsoKnownAs
(from other DIDs)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:
proof
, created
etc) into the DID Document itself..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"
}
}
~
is a safe character in URLs and doesn't have to be encoded, see also https://datatracker.ietf.org/doc/html/rfc3986#section-2.3:
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
In DIDs, ~
is not allowed:
idchar = ALPHA / DIGIT / "." / "-" / "_" / pct-encoded
The did:web spec doesn't say much about encoding of the path, only:
Directories and subdirectories MAY optionally be included, delimited by colons rather than slashes.
Being more precise here avoids ambiguities and potentially forging invalid DIDs.
There are roughly two options:
~
~
is encoded (and potentially decoded), while not accidently double-encoding the other characters that may already be percent-encodedWhat is the canonical URL for a did:web id
field. At present, one variation of the future looks like this:
did:web:example.com -> HTTP GET https://example.com/.well-known/did.json
Then the question becomes, what should we expect in the id
field for the resulting DID Document. One possibility is this:
"id": "did:web:example.com"
... but another possibility is this:
"id": "did:web:example.com/.well-known/did.json"
What if someone specified this as their DID: did:web:example.com/alice.json
, but their DID Document states:
"id": "did:web:example.com/alice"
Is this DID did:web:example.com
equivalent to this DID did:web:example.com/
?
The current specification does not have an answer to any of these questions, which can be summarized as: What is the canonical URL for a DID Web identifier, if any?
Therefore, if the proposal to use absolute URLs is rejected #52 ... then it raises the question around what a canonical DID Web ID is.
At present, there might be an assumption that there is a canonical URL for a DID Web ID, that is, these are canonical URLs for the examples above:
did:web:example.com
did:web:example.com/alice
If that's the case, then it holds that we have to have at least two special cases when determining if a DID Web ID is valid based on the DID Document we receive:
id
field in the DID Document MUST be did:web:DOMAIN
.id
field in the DID Document MUST be did:web:DOMAIN/ARBITRARY_PATH/FILE
(without the extension).Are there any other special cases we need to consider?
Now that we support paths (as of PR #5) in our did:web
URLs, and we're using the :
to encode the /
characters for paths, this poses another challenge.
Since we're using the :
character for paths, what do we do about the actual most common intended purpose of that character, which is to specify a port number?
So, specifically, say I am a developer who has just fired up a test server on their local machine, which is running on https://localhost:8443
(the https
is deliberate of course - I made a self-signed cert for it and everything). This kind of thing happens all the time (it's happening to me right now :) ).
If there's a did:web
document residing on that domain (say in /.well-known/did.json
), what will that URL look like? According to our rules so far:
did:web:localhost:8443
Except now we're using :
(in the did-specific-identifier
portion of the url) to encode path fragments. So that URL would "decode" to https://localhost/8443
. Not what we want.
So, what are people's thoughts on how to best handle this? @awoie, @OR13 ?
Example 1 uses "publicKey"
which is not defined in https://www.w3.org/TR/did-core/
Am I missing something?
I feel we should add language to the spec that specifically warns against and deters use of did:web with subdomains in ways that are not in keeping with the purpose if DIDs. For example: a large IDP may try to create subdomains on its centralized IDP service domain and 'issue' DIDs to users/customers, which would essentially lock their DID to that provider, the exact opposite of what DIDs were designed to do.
A hardcoded file called did.json
is not very flexible, and excludes other representations. We should update the spec to use Accept headers on Read. It'd also be better if the requester for Read just fetches the DID as it stands without adding fixed strings or filenames on the end.
The read mechanism does not provide any sort of auditability on the DID, which leaves this DID Method open to insider-threat attacks, among others.
(I'm sure there are more grown-up (less single-service-dependent) ways to do this, but we could start by snapshotting the DID doc with archive.org ๐ )
Might/should this spec have opinions about or include an optional behavior for historical query?
As @rhiaro cheekily suggested, you can always query
https://web.archive.org/web/20220731132838/https://www.spruceid.com/.well-known/did.json
if you want to read [in human-readable, HTML-wrapped form] what did:web:spruceid.com
resolved to on 31 July 2022, but some implementers I've heard from would rather configure their web servers to return that historical DID doc from
did:web:spruceid.com?dateTime=2022-07-31T19:17:47Z
Where would I send an implementer whose system requires this and would like to propose a standard for interop with other historical-query-supporting did:web hosts? Should they PR an entry into the DID Doc Extension Registry for the benefit of other DID hosting solutions that want to harmonize on query?
NB @dmitrizagidulin @peacekeeper since this is debatably more a DID resolution question than a DID web question...
Typically in a web domain a port is a part of the host authority and indicated via a :
followed by a number. However due to the way we're currently parsing a resource path we're using the :
which maps to a /
and changes the resource path. This leaves no way for a port to be specified with the did:web URI. Is this an expected feature or something that's just been overlooked.
@OR13 @dmitrizagidulin @dlongley @rhiaro I'd think you all may have an opinion on this.
What is the most appropriate way to resolve other documents than did.json
?
We are looking to propose a did:web
method for the AnonCreds v1.0 Specification.
The spec is currently implemented with did:[sov|indy|cheqd|cardano]
.
There are some json
objects which need to be publicly stored.
These include:
These are then referred to as object ID's for external processing, which are did urls.
Would appending a .json
at the end suffice to resolve these objects without conflicts? Meaning if the did url ends with .json
, do not append /did.json
.
Examples:
did:web:<domain>:<checksum>.json
did:web:<domain>:v1/schema/<checksum>.json
did:web:schema.<domain>:v1/<checksum>.json
did:web:<domain>:acme/v1/schema/<checksum>.json
Thoughts, concerns, insults, suggestions and opinions are all welcome!
Add https://github.com/interop-alliance/did-web-resolver to the Reference Implementations section.
I was thinking about it recently and came to realize that if the domain is replaced with an IP address, did:web can be made fairly decentralized while still maintaining all the main benefits around ease of integration. Would it be worth explicitly mentioning it with some examples? From what I can tell with the referenced domain
ABNF in [RFC1035], [RFC1123], and [RFC2181] there's no specific mention about how IP addresses could be a domain name (which makes sense). However, if we change the definition to be based around the host/path portion of a URL (thinking referencing WHATWG URL spec here) then it should make this possible.
Thoughts on supporting this?
Consider https://foo.example/bar/baz.html
.
did:web:foo.example.com:bar:baz.html
. Is that intended? If so, add an example to the doc. If not, be clear it shouldn't be. (I believe the entire URL path namespace should be mappable, perhaps even including parameters).http://foo.example/bar/baz.html/did.json
. Is that intended, turning "file" baz.html
into a "directory" all of a sudden? If so, please be clear about it. If not, document an alternative.This issue is raised to discuss potential breaking changes to the resolution rules for did web.
I propose we remove the .well-known
resolution rule, and instead handle resolution for naked origins as follows:
did:web:example.com
- > https://example.com/did.json
This is just another case of the existing path based routing resolution rules...
A 302 redirect can be configured to preserve any existing did documents.
This would simplify the did to url conversion logic by 50% with no loss of the name space.
If /.well-known/did.json
usage is to be kept (contrary to #50, but following #50 (review)), shall we register it with IANA/IETF?
Reads enable pervasive tracking of DID use across the Internet. There is currently no mitigation for this privacy-violating mechanism.
When a DID is resolved to a DID document using the abstract resolveRepresentation
function, the resolution result is supposed to include DID Resolution Metadata that includes a contentType
for the Media Type of the representation used in the didDocumentStream
part of the result.
resolveRepresentation
could be implemented for did:web
by passing through the HTTP response body as didDocumentStream
. But what should the resolution metadata contentType
be set to?
In other words, is a did:web DID document expected to be in JSON-LD representation, or in JSON representation?
The specific extension ".json" used in did:web suggests JSON, but in the Create (Register) operation, the DID document is referred to as a JSON-LD file. There is also an (obsolete?) section with a JSON-LD context definition.
Should the HTTP response Content-Type header be used to determine the representation contentType
? I think this would be consistent with DID document production/consumption rules:
A conforming producer MUST return the Media Type string associated with the representation after the production process completes.
A conforming consumer MUST determine the representation of a DID document using the Media Type input string.
This would mean however that .json
files hosted statically with default settings would be considered JSON rather than JSON-LD. So e.g. JSON-LD did:web DID documents on GitHub Pages would not work.
Or should did:web specify that its DID documents should always be considered one representation or the other?
The difference in representation is relevant as the JSON-LD representation is stricter, for example, its production rules require a specific initial value in the @context
property. Strict checking of that property, along with an assumption of JSON-LD representation, caused a problem with one did:web implementation and application: haxxnz/nzcp-rust#1 spruceid/ssi#345. There are also semantic and security reasons why the distinction in representation is important.
There is also some discussion about did:web DID documents having multiple representations: #15, #20 (comment)
I'm wondering if it's wise to do the following:
Bob, who controls bobsdomain.com
, wishes to allow Alice to issue VCs on his behalf. Alice controls alicesdomain.com
To allow this, in his DID document Bob puts did:alicesdomain.com:keysForBob#key1
as a verification method. If at some point Bob wants to change the arrangement he can change his did document.
I understand this is valid from the VC spec, but the key rotation/revocation prospects seem a bit dicey among other things. Is there a better way?
I note that Bob could also simply put one of Alice's public keys straight up in his DID document. I don't think this makes anything better though, and it seems a little less honest.
For the domain name
w3c-ccg.github.io
, thedid.json
will be available
The extension in the the current version of the did:web spec uses .json
in a number of places
But the official extension for a json-ld document is .jsonld
Is this worth changing?
https://w3c-ccg.github.io/did-method-web/
no sidebar is visible
It has been proposed that DID Web resolution follows HTTP redirects. If this is true, then there are security implications for blindly following re-directs. For example, if a redirect sends you off of the original domain then it allows an attacker to compromise a site merely by controlling the redirect rules rather than placing a file on the site. If we don't allow redirects off of the original domain, it makes it difficult to move a DID Web ID to a different domain in the future. There are trade-offs each way.
One solution to the problem is to restrict redirects for now until we have more experience for redirecting off of the original domain (we may choose to never do this).
One potential algorithm would be:
Another potential algorithm would be:
id
field that matches the initial canonicalized DID Web URL (see issue #54).I haven't put a great deal of thought into all the attack vectors for redirects yet, just trying to propose something that can be refined in this issue.
The method specific identifier MUST match the common name used in the SSL/TLS certificate, and it MUST NOT include IP addresses. A port MAY be included and the colon MUST be percent encoded to prevent a conflict with paths. Directories and subdirectories MAY optionally be included, delimited by colons rather than slashes.
As noted in RFC 6125, subjectAltName is the preferred place for the identity.
Since virtually every other did-resolver is able to expose multiple identities, I'd like to use a single domain to expose multiple DID. Accepting a path after the domain name would go a long way, but if it clashes then we can split the path with something different.
Example:
"did:web:my.domain.com|{uuid}" that would resolve to
We need to update the universal resolver driver support did web with path based routes, for example:
https://did-web.web.app/api/v1/identifiers/did:web:did.actor:supply-chain:manufacturer:stacy
ping @awoie @dmitrizagidulin
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.