Skip to content

Conversation

@swcurran
Copy link
Contributor

@swcurran swcurran commented Oct 21, 2025

NOTE: This PR is still in draft, as I need to clean up the internal section links, the definitions and references,
anchors and links, and getting a consistent ReSpec style. I’m putting in the PR now to get feedback on the general ideas
and approach vs. on the ReSpec nitty-gritty. As this is discussed, I’ll continue with the cleanup.

A rendered version of the PR can be seen here: https://swcurran.github.io/did-resolution/.

Addresses issues: #218, #209, #201, #200, #181, #156

This pull request significantly revises and expands the content of the DID URL Dereferencing section to clarify how
DID URL components — specifically the path, query parameters, and fragment — are to be interpreted during dereferencing.
The update draws an explicit analogy to HTTP URL handling, helping implementers relate familiar URL resolution behavior
to DID URLs, while also clearly defining where DID-specific semantics differ. Most notably, this change introduces
deterministic and interoperable handling of the DID URL path, which was previously undefined in the specification.
The additions establish a clear default behavior using the new FileService service type, while allowing for custom
behavior via method-specific or DID extension service types. The result is a specification that is easier to implement,
more extensible, and more aligned with the expectations of developers familiar with web infrastructure.

This update is (intended to be) backwards compatible:

  • No existing required behavior has been changed or invalidated.
    • Techniques defined and used by Cosmos for Linked Resources and Cheqd for DID Linked Resources are untouched in their use of fragments and query parameters, respectively. The main focus here is on formalizing DID URL path handling.
  • The FileService model supports DID Documents already using serviceEndpoint mappings that align with intuitive path-based routing.
  • While the wording is updated, the handling of fragments and query parameters is (intended to be) unchanged.

Summary of changes:

  • Removed the outdated "DID Parameters" section (now deprecated and unreferenced), and defining the Query Parameters defined in this spec to the “DID Resolution Query Parameters and Service Types” section.
  • Replaced the previous "DID URL Dereferencing Algorithm" and "Examples" subsections with new normative and structured content.
  • Added new structured subsections to the DID URL Dereferencing section:
    • DID URL Components: Path, Query Parameters, and Fragments — defines interpretation rules for each component, with HTTP comparisons.
    • DID URL Dereferencing Algorithm — provides normative steps for resolving a DID URL to a resource via service mappings.
    • DID Resolution Query Parameters and Service Types — defines recognized query parameters (e.g., service) and registered service types (e.g., FileService).
      • This brings together into “mini-specifications” all of the query parameter and service types defined by the DID Resolution spec. The previous “DID Parameters” content is moved to this section.
    • Examples — includes multiple concrete cases showing default and custom behaviors, including a fictitious FictitiousVerifiedFileService.

Preview | Diff

@wip-abramson
Copy link
Contributor

Addresses issues: #218, #209, #201, #200, #181, #156

Thanks @swcurran!

I noticed that the DID Resolution Options section still references #did-parameters for its definitions of versionId and versionTime. Perhaps we just point them to the new section these definitions moved to?

@swcurran swcurran marked this pull request as draft October 21, 2025 21:42
Copy link
Contributor

@dmitrizagidulin dmitrizagidulin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work 👍

(One minor question about the contentStream of the resolution result)

@swcurran
Copy link
Contributor Author

Added a few more comments, cleaning up the links in the document, making sure all links that are expected are there, and trying to be consistent with the formatting of the HTML. I think I will need to do one more full pass before I remove the "Draft" status, so I don't waste people's time on this.

Looking forward to discussing this at the DID Working Group meeting.

@ottomorac
Copy link
Contributor

DID WG Discussion on 23-Oct:

https://www.w3.org/2025/10/23-did-minutes.html

Copy link
Collaborator

@peacekeeper peacekeeper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the general idea is interesting, and some years ago I also used to think about the DID Path in the same way. But today I have several concerns with this PR..

  1. I don't really like how this completely replaces the current "DID URL Dereferencing Algorithm" section. It would be better if this updates or extends the current section to add the new functionality. For example, some of the effects of replacing the current section would be:

    • In the current algorithm, it's possible to have just a "service" parameter without path and without "relativeRef". The PR would break this.
    • The current algorithm defines how to process the "verificationRelationship" option. The PR completely removes this, why?
    • Some error handling details are also being removed here.
  2. Some statements in the PR are clearly wrong, such as "A DID URL MUST include a path component".

  3. As discussed, I think this breaks how some existing DID methods use the path, e.g. under the current rules, did:cheqd:testnet:55dbc8bf-fba3-4117-855c-1e0dc1d3bb47/resources/398cee0a-efac-4643-9f4c-74c48c72a14b is dereferenced to an image resource, without depending on service endpoints, and without requiring the use of HTTPS endpoints. The PR would break this.

  4. If we decide that we want this functionality in DID Resolution, then I think it would be important to NOT allow DID methods to override it, so that resolvers and clients can be certain that this feature always works in the same way, just like "service" and "relativeRef" work today in a completely DID method independent way. So for me, it would be important to know how the did:cheqd community feels about this, and if they could be convinced to abandon their current use of the DID Path.

  5. I think this PR also breaks a feature in the existing HTTPS Binding section, which can return a 303 redirect to a selected service endpoint URL.

  6. Note that in the current algorithm, the result of dereferencing a DID URL with a "service" / "serviceType" and optional "relativeRef" parameter is a list of selected service endpoint URLs. The result is NOT a resource at those URLs. I believe it has been our common understanding for a while that retrieving something from a service endoint URL is a separate dereferencing step that happens after DID URL dereferencing.

  7. I don't think the way how path and query parameters are used together is conformant with basic URI architecture. In an example like did:example:123456789abcdefghi/path/to/file.txt?versionTime=2025-10-01T12:00:00Z, I would expect that "versionTime" means the version of the file.txt, not the version of the DID document. Furthermore, I think there's some kind of layering violation, if this PR says that query parameters "understood by the DID resolver" are used for the DID document, and that "unused query parameters" are appended to a service endpoint URL. The results could differ by resolver implementation and therefore be unpredictable.

    • Just as a side note, this is why matrix parameters would have been nice. Then we could have cleanly separated "parameters for the DID document" and "parameters for the service endpoint URLs". E.g. the example above would have looked like did:example:123456789abcdefghi;versionTime=2025-10-01T12:00:00Z/path/to/file.txt?otherparam=value. Note that the introduction of relativeRef was actually a direct result of removing matrix parameters, see @dlongley 's comment w3c/did#159 (comment) and issue w3c/did#349

Finally, I'm sorry, but I'm still not sure if I agree with the motivation here. I think the fact that path handling is left completely to the DID method can also be considered a feature, not a problem. The current design means that DID URLs with paths provide a namespace that fully inherits all the benefits of DIDs, such as decentralization, persistence, cryptographic verifiability. Using a DID Path and using "relativeRef" serve two different purposes. This PR would abandon this design by binding the DID Path to service endpoints, which in practice will be HTTPS URLs and therefore have a lot of potential downsides that DIDs were designed to solve in the first place.

@swcurran
Copy link
Contributor Author

I'll add in-line comments:

I think the general idea is interesting, and some years ago I also used to think about the DID Path in the same way. But today I have several concerns with this PR..

  1. I don't really like how this completely replaces the current "DID URL Dereferencing Algorithm" section. It would be better if this updates or extends the current section to add the new functionality. For example, some of the effects of replacing the current section would be:

The DID URL Dereferencing algorithm remains. It has been adjusted to reflect the guidance provided in the "Components Handling" section, and to encourage that handling.

  • In the current algorithm, it's possible to have just a "service" parameter without path and without "relativeRef". The PR would break this.

That could still be valid by including that in the definition of "service". I would think that the behaviour is better accomplished by using a fragment that is the id of the service. That said, by using query parameters service and serviceType without a path, I'm not sure what the result is -- a guess the DIDDoc with an array of "node references" to services -- as if there were multiple fragments. I'm also not sure that would be useful.

  • The current algorithm defines how to process the "verificationRelationship" option. The PR completely removes this, why?

I'll look at that -- it was not intended to change.

  • Some error handling details are also being removed here.

Happy to include them back in. I'll see what I can determine. I've never been very clear on when it is OK to say "report an error" vs. "report a specific error" in the DID family of specs. AFAIK, only "NOT FOUND" and "ERROR" are defined.

  1. Some statements in the PR are clearly wrong, such as "A DID URL MUST include a path component".

I think you were looking at an earlier version of what I submitted -- not the latest commit. When I removed the <STRONG> tags I accidentally changed some MAYs to MUSTs (doh!!!), but in the last cleanup, those were all changed. If any are still there, that is clearly an error. Sorry about that.

  1. As discussed, I think this breaks how some existing DID methods use the path, e.g. under the current rules, did:cheqd:testnet:55dbc8bf-fba3-4117-855c-1e0dc1d3bb47/resources/398cee0a-efac-4643-9f4c-74c48c72a14b is dereferenced to an image resource, without depending on service endpoints, and without requiring the use of HTTPS endpoints. The PR would break this.

As discussed on the call, I think we settled that I would add a step to say "DID Methods specific handling" can be done in the process, but is discouraged.

Without that, the DID Linked Resources spec will break. That said, the goal of DID Linked Resources -- especially for Cheqd -- would have been far easier and logical with this PR in place. They would have simply defined a Cheqd service type that used the path /resources to be selected, extracted the collectionId from the DID and the resourceId from the path. So yes, some things may be different, but I think it makes future work much easier.

  1. If we decide that we want this functionality in DID Resolution, then I think it would be important to NOT allow DID methods to override it, so that resolvers and clients can be certain that this feature always works in the same way, just like "service" and "relativeRef" work today in a completely DID method independent way. So for me, it would be important to know how the did:cheqd community feels about this, and if they could be convinced to abandon their current use of the DID Path.

Fully agree with that. Let's have the conversation.

  1. I think this PR also breaks a feature in the existing HTTPS Binding section, which can return a 303 redirect to a selected service endpoint URL.

I'll take a look at that, but could probably use some help in understanding that.

  1. Note that in the current algorithm, the result of dereferencing a DID URL with a "service" / "serviceType" and optional "relativeRef" parameter is a list of selected service endpoint URLs. The result is NOT a resource at those URLs. I believe it has been our common understanding for a while that retrieving something from a service endoint URL is a separate dereferencing step that happens after DID URL dereferencing.

This comment is HUGE. My understanding is that a DID Path (even one produced by relativeRef) is expected to return the resource, not an array of URLs. If DID with path is not expected to return the referenced resource, but rather the URL for the expected resource, we have a big misunderstanding. I think it should return the resource -- hence this PR. Definitely something that needs to be clarified.

  1. I don't think the way how path and query parameters are used together is conformant with basic URI architecture. In an example like did:example:123456789abcdefghi/path/to/file.txt?versionTime=2025-10-01T12:00:00Z, I would expect that "versionTime" means the version of the file.txt, not the version of the DID document. Furthermore, I think there's some kind of layering violation, if this PR says that query parameters "understood by the DID resolver" are used for the DID document, and that "unused query parameters" are appended to a service endpoint URL. The results could differ by resolver implementation and therefore be unpredictable.

This is why I wanted the "Query Parameters and Service Types" section to be a series of "mini-specs" to avoid exactly this issue. I understand your comment, but I disagree with it as applied to DIDs. In what is above, the versionTime parameter can only be used without a path -- with, I guess, the weird exception of the path being to a DID. But an important capability of DIDs is that we can achieve "long lasting" identifiers by being able to reference the DID at a particular version. For example, if the /path/to/file.txt has a related data integrity proof (perhaps it is a VC) that is based on the key in the particular version of a DID active at the time the file was created it is necessary to have a way to find both the key and the resource. I think that is a crucial feature of DIDs -- long lasting verifiability, while also allowing for best practices key handling.

An alternate that we discussed to clarify this is that there could be a query parameter on the DID that specified (in percent encoded form) that query parameters to be included in the assembled URL. That way, any query parameters not understood can be thrown away and there are ONLY DID Resolver query parameters.

As an aside on this point -- I would also like to see added to the DID Spec the capability to clearly deactivate keys used in prior versions of a DIDDoc with an indicator such as "we've rotated to a new key and is no longer being used" and "this key was compromised -- don't trust anything signed with it". We have deactivating a DID, but I think we should also focus on deactivating keys while retaining the DID.

  • Just as a side note, this is why matrix parameters would have been nice. Then we could have cleanly separated "parameters for the DID document" and "parameters for the service endpoint URLs". E.g. the example above would have looked like did:example:123456789abcdefghi;versionTime=2025-10-01T12:00:00Z/path/to/file.txt?otherparam=value. Note that the introduction of relativeRef was actually a direct result of removing matrix parameters, see @dlongley 's comment w3c/did#159 (comment) and issue w3c/did#349

I don't think this is necessary, and would be more complex. It's also not AFAIK compliant with RFC3986. But that's just me. :-). Happy to discuss.

Finally, I'm sorry, but I'm still not sure if I agree with the motivation here. I think the fact that path handling is left completely to the DID method can also be considered a feature, not a problem. The current design means that DID URLs with paths provide a namespace that fully inherits all the benefits of DIDs, such as decentralization, persistence, cryptographic verifiability. Using a DID Path and using "relativeRef" serve two different purposes. This PR would abandon this design by binding the DID Path to service endpoints, which in practice will be HTTPS URLs and therefore have a lot of potential downsides that DIDs were designed to solve in the first place.

In writing the PR I was as focused as much on Cheqd's "resources on a blockchain", on "resources as files secured on a blockchain", and on "IPFS" use cases as I was with "resources with HTTPS URLs". I tried to make sure all were enabled. I think the use of a service type to define how to handle a path is extensible such that the goal can be accomplished, with the ability of service types defined at the DID resolution spec level (all DID Methods), the DID Method level (one DID method -- not ideal) and the DID Extensions Registry (multiple DID Methods) is a good balance. Some things like using IPFS can be accomplished using the DID Resolution spec-defined FileServce (assuming the DID Resolver knows how to resolve such a URL), simply by using that protocol in the serviceEndpoint.

Let's discuss further.

@swcurran
Copy link
Contributor Author

DID WG Discussion on 23-Oct, I think the following changes were requested:

  • Update to reference a "DID dereferencer" instead of "DID resolver" where appropriate.
  • Add the (discouraged, but possible) "DID Method-specific" path handling step to the processing flow.
  • Add "collect types" step in the process.

I'll also reread the cheqd DID Linked Resources Spec and think about how to get it to align with the "new" DID Resolution approach for paths.

Comment on lines +1130 to +1132
response. DID Resolver clients are generally more flexible than
browsers, applying deployment-specific handling of the resolved
resource by media type, including metadata and fragment (if any).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The described behavior of a DID Resolver client matches my understanding of the behavior of a Web browser. What part of this is more (or less) flexible?

Copy link
Contributor Author

@swcurran swcurran Oct 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking on this:

A browser "just" receives a response, displays it, and (when used) "jumps" to the referenced node of the DOM tree referenced by a fragment. Of course, I suppose with the programmable extensions in JavaScript or WASM (etc.) there is a lot more a browser could do, but for this purpose I left that aside.

A DID resolver client is "custom" (non-standardized) code that takes the result of a DID URL resolution and "does something" -- verifies a signature, verifies a verifiable credential, uses a document related to a DID in some way, etc.

My comment was thus based on the "standardization" of the behavior of a browser, and the "custom" behavior of a DID Resolver client.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a lot more a browser could do

Right, requiring specific requests, extensions, etc., just as a DID resolver client can "do something" -- but this is not automatic nor the same "something" in all DID resolver clients.

Maybe someone else has some thoughts on teasing this out.

swcurran and others added 9 commits October 25, 2025 10:41
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Signed-off-by: Stephen Curran <[email protected]>
Signed-off-by: Stephen Curran <[email protected]>

Co-authored-by: Ted Thibodeau Jr <[email protected]>
@swcurran
Copy link
Contributor Author

Thanks, @TallTed -- much appreciated. Just left the ones related to the question I asked -- happy to include those as well. The "batch" feature in GitHub was helpful :-).

Still to be done are the items listed above from the discussion on Thursday.

Signed-off-by: Stephen Curran <[email protected]>
Signed-off-by: Stephen Curran <[email protected]>

Co-authored-by: Ted Thibodeau Jr <[email protected]>
@peacekeeper
Copy link
Collaborator

peacekeeper commented Oct 27, 2025

  1. I don't really like how this completely replaces the current "DID URL Dereferencing Algorithm" section. It would be better if this updates or extends the current section to add the new functionality. For example, some of the effects of replacing the current section would be:

The DID URL Dereferencing algorithm remains. It has been adjusted to reflect the guidance provided in the "Components Handling" section, and to encourage that handling.

I think it would be fine if this PR actually "adjusts" the existing DID URL Dereferencing algorithm, by adding the proposed functionality. But instead it completely replaces the entire content about DID URL Dereferencing. This causes a lot of issues with other functionality and other parts of the specification.

I have already listed some of the issues in my previous comment, but this PR includes major changes that I think will really affect many other parts of the document. For example, some statements in the "DID Resolution Architectures" section would also be broken by this PR.

Removed the outdated "DID Parameters" section

I don't understand this either. A PR that proposes changes to how dereferencing of the DID Path is handled shouldn't have to suddenly declare the entire existing content about DID Parameters "outdated" and "deprecated".

@swcurran
Copy link
Contributor Author

To clarify this comment:

Removed the outdated "DID Parameters" section

I don't understand this either. A PR that proposes changes to how dereferencing of the DID Path is handled shouldn't have to suddenly declare the entire existing content about DID Parameters "outdated" and "deprecated".

I misworded my original overview description. I didn't remove the contents of the "DID Parameters" section -- I moved it to be a part of the DID URL Dereferencing, alongside sections on fragment and path handling. The "id" of the section remains, and references elsewhere in the spec now point to the section in its new place.

I think it would be fine if this PR actually "adjusts" the existing DID URL Dereferencing algorithm, by adding the proposed functionality. But instead it completely replaces the entire content about DID URL Dereferencing. This causes a lot of issues with other functionality and other parts of the specification.

My intention was to "adjust" the algorithm. I will review again the two versions to see if anything is missing from the previous, and would be glad to have feedback of anything missing.

@wip-abramson
Copy link
Contributor

wip-abramson commented Oct 28, 2025

1. Note that in the current algorithm, the result of dereferencing a DID URL with a "service" / "serviceType" and optional "relativeRef" parameter is a list of selected service endpoint URLs. The result is NOT a resource at those URLs. I believe it has been our common understanding for a while that retrieving something from a service endoint URL is a separate dereferencing step that happens after DID URL dereferencing.

This comment is HUGE. My understanding is that a DID Path (even one produced by relativeRef) is expected to return the resource, not an array of URLs. If DID with path is not expected to return the referenced resource, but rather the URL for the expected resource, we have a big misunderstanding. I think it should return the resource -- hence this PR. Definitely something that needs to be clarified.

The current dereferencing algorithm defined in the spec appears to be aligned with what @peacekeeper states, specifically steps 8.2, 8.3 and 8.4 of the derefencing a resource algorithm - https://w3c.github.io/did-resolution/#dereferencing-algorithm-resource.

My intention was to "adjust" the algorithm.

It does seem that the algorithm has been rewritten from scratch - I appreciate that the intention was to keep the same functionality as the previous version.

As there seems to be a lot for the WG to discuss here, we will have a special topic call on Wednesday the 5th of November dedicated to this PR. In the meantime, lets continue to conversation here. Especially interested to hear from @tweeddalex and @jandrieu

@tweeddalex
Copy link

tweeddalex commented Oct 29, 2025

Hi @swcurran coming to this fresh and have a lot to catch up on! I'll caveat the below comments by saying that I probably need to read through the proposed updates again:

  • Am I correct to assume that the FileService type would be much more valuable for web-based DID methods than other types of DID Methods?
  • With web-based DID methods, the FileService type seemingly helps resolvers negotiate request formats into coherent HTTP URLs, pointing to specific endpoints or resources. This makes sense for did:web because the HTTP URL can be extracted from the DID and appended with the contents of the prefix/service endpoint.
  • However, for non-web DID Methods, I don't see universal value. E.g. if we added a /resources/ prefix and FileService into did:cheqd DID Documents, a resolver or DID URL Dereferencer would still need to be aware of how to recompile DID Documents and Resources from the cheqd ledger.
  • Therefore, on first read - I see this being useful for a sub-set of DID Methods (that can be wrangled into HTTP URLs), rather than a blanket service type that should be universally adopted by ALL resolvers and DID URL dereferencers.
  • Perhaps this could be its own standalone spec for applying to did:web, did:webvh, did:webs, etc.

@ankurdotb
Copy link

Context

This suggested edit does seem to break the DID Linked Resources specification.

That said, the goal of DID Linked Resources -- especially for Cheqd -- would have been far easier and logical with this PR in place. They would have simply defined a Cheqd service type that used the path /resources to be selected, extracted the collectionId from the DID and the resourceId from the path. So yes, some things may be different, but I think it makes future work much easier.

To provide a bit of motivation behind why DID-Linked Resources was created and to answer some of the points raised above:

  1. The reason we didn't go with the service section is that many DID Core authors, including Drummond, clarified that the intention of the service section was to point to APIs, endpoints etc and not to specific files. The other consideration is we wanted to add richer metadata on versioning, file media type, versioning etc which would be hard to add within the service section without deviating from the definition in DID Core (see below on that).
  2. Adding a new top-level section in the DID Document was considered, and then not selected because it could not be standardised as core property without modifying DID Core (which was considered tough to achieve). While the DID spec does allow new properties to be added, practically speaking many software libraries will have strong typing/validation to only parse the core properties. So while this change could be made at the specification level, it might break practical implementations.
  3. Hence, the approach adopted was to consider linked resource resolution as a subset of DID Resolution rather than DID Core, since in practical terms a lot of software libraries treat typing/validation more permissively in the DID Document metadata than in core, and would also the specification to be treated for standardisation with the DID Resolution spec.

(Sidebar: @tweeddalex The current spec draft for DLRs does call out some of architectural considerations, but we should perhaps expand these considerations to explain some of the above, which I do recall being answered/shown in decks about the spec.)

Suggested path forward

I don't per se disagree with the idea of a FileService service type. I think that approach fits within the semantic definition of "service types define type of API endpoint". IMO, the architectural tradeoff this model makes is not having as rich metadata to present as query parameters but that's an okay tradeoff for a DID method to make. Especially in web-based DID methods, such file path handling can be done using HTTP headers like media type, ETag to understand cache expiry etc.

What I do think would be a less invasive way to do this would be to add a FileService type in DID Spec Registries, and defining how it behaves there, rather than changing the DID Resolution spec so extensively. The concern identified on breaking DLR spec is just one topic (and there are 6-7 other DID methods besides did:cheqd that implement DLR spec). There might be other, unforseen breakages that we have not identified in this thread. So I would suggest:

  1. Define FileService service type in DID Spec Registries, along with some basic, DID method agnostic resolution guidance
  2. Provide detailed guidance on how FileService service type resolution is done for a specific DID method, e.g., did:webvh
  3. Keep DID Resolution spec unchanged, except for any minor, non-breaking edits.

@swcurran
Copy link
Contributor Author

Responding to @tweeddalex comment here and his fundamental question here "Am I correct to assume that the FileService type would be much more valuable for web-based DID methods than other types of DID Methods?"

The short answer is no :-) -- definitely not my intention. If it is, that needs to be fixed. In writing this response, I think I see something in what I've done that could be adjusted to make it more inclusive -- covered in the PROPOSAL below.

Here is my motivation on this PR:

The core issue is to define a useful, standard and flexible way to handle paths in a DID URL. Currently, step 9 of the Dereferencing the resource algorithm says essentially "path handling is not defined by the DID Resolution spec". It is left to the DID method, extensions or the client (??) to decide. I think that makes it really hard for everyone to use DID URL paths and I think that is unfortunate. DID URLs with paths are extremely useful, as almost all of us have found that want to associate resources with DIDs.

This PR attempts to fill that gap with the following approach.

  1. When you have a path, find an appropriate service for intended for that path, with a [definition of how to find the service](the path matching algorithm).
  2. Given the service found, use the specification for the type of the service to understand the rules to assemble a URL from the path. The definitions for the service types can be found in the DID Resolution spec, the spec for the DID Method, and the DID Extensions.
  3. Resolve the assembled URL.

The proposed specification for the FileService service type is in the DID Resolution spec, and it is used to combine a base URL with the path. It is useful for any resource that can has a URL -- regardless of the DID Method.

This should give two levels of flexibility:

  1. If the meaning of the path can be expressed as a URL (HTTPS, IPFS, DID, MAGNET, etc.) then FIleService suffices.
  2. If not, specify another Service Type that can be used at the DID Resolution spec level, the DID Method or the DID Extensions level.

PROPOSAL As I've responded to this I realize that my proposed 3 steps (above) should really be 2, with the 3rd step ("Resolve the URL") removed and left to the discretion of the specification of the service type (Step 2). I've been assuming that Step 2 produces a URL based on the service type, Step 3 resolves that URL. Instead it should be Step 2 -- "process the path according to the service type definition to produce a resource". For the "FileService" service type, that means assembling a URL and resolving it, but other service types can do other things without needing to produce a URL.

This would make Step 2:

  1. Given the service found, use the specification for the type of the service to process the path and return a resource.

@swcurran
Copy link
Contributor Author

in response to @ankurdotb 's comments found here.

The response I provide to @tweeddalex covers your comments as well. The core problem I'm trying to solve is that the handling of path is not specified in the DID Resolution spec. By specifying how a path is to be processed in the DID resolution spec, we can have service type definitions like "FileService" (and others!) that provides flexibility. Without solving the "what to do with a path" problem, the "FileService" can't be defined as you propose.

Perhaps here is the path forward -- an answer to this question:

Is there a philosophical objection to defining in the DID Resolution spec a consistent way for how a path is to be processed? Assuming there is an approach leaves flexibility at the DID Method and DID Extensions level.

@w3cbot
Copy link

w3cbot commented Oct 30, 2025

This was discussed during the #did meeting on 30 October 2025.

View the transcript

Announcement: DID Path special topic call (5-Nov)

<ottomorac> w3c/did-resolution#221

Wip: Don't discuss on the call today -- hence special call.

manu: Won't make the special call -- has lots of opinions. Surprised by the response. Not sure if opposed philosophically or is it the PR content.

swcurran: +1 to what Manu said. The philosophical is "do we want to define what path handling should be as a part of DID spec, or do we defer it to DID Methods only?".

<ottomorac> q>


@ottomorac
Copy link
Contributor

ottomorac commented Oct 30, 2025

As heads up for everyone on the thread here, there will be a special topic to discuss this next week on 5-Nov: https://www.w3.org/events/meetings/fc72b076-8389-4fd8-b223-a985590d3f33/20251105T100000/

@peacekeeper
Copy link
Collaborator

My understanding is that a DID Path (even one produced by relativeRef) is expected to return the resource, not an array of URLs.

Given the service found, use the specification for the type of the service to process the path and return a resource.

As @wip-abramson pointed out, this is not what the current algorithm does. It can return a DID document with the selected services, or list of selected service endpoint URIs, depending on the "accept" option.

A DID resolver returning an array of selected service endpoint URIs is comparable to a web server returning a 303 redirect. The client can then choose to dereference the other URI(s) or not. What you are suggesting would be similar to saying that a web server should contact another web server at a redirected URI, fetch the resource from there, and return it to the client. You would be combining two dereferencing processes into one, without involving the client in dereferencing the second URI.

If I read your PR correctly, the "service" parameter wouldn't even be processed unless there is a DID Path. Dereferencing something like did:example:123?service=agent would be undefined. Also, with your PR, only one "service" could be selected, whereas the current algorithm supports selecting multiple services (which can be a common use case, especially when serviceType is used).

Is there a philosophical objection to defining in the DID Resolution spec a consistent way for how a path is to be processed?

I don't think you're actually achieving this, since with your proposal, the result of dereferencing the DID Path would depend on a mix of DID method specific logic AND on the contents of the DID document. Sometimes dereferencing the path would depend on the services in the DID document, and sometimes it wouldn't ("If the DID Method specifies its own path handling algorithm, it MUST be applied, and the rest of this algorithm skipped.").

Compared to this, in the current algorithm you have:

  • "service" and "relativeRef" always work in a consistent, DID-method independent way. No DID method overrides this or defines any custom method-specific logic for this.
  • DID Path is left entirely to the DID method, without any interference from the DID Resolution spec.

Put differently, today the DID Path is essentially an addressing mechanism WITHIN the DID method's VDR. In the case of did:cheqd, the DID Path is used to identify resources within the Cheqd VDR. In the case of web-based DID methods, the DID Path should be used to identify resources within the web server.

What you are suggesting is that the DID Path would be used to identify resources anywhere outside the DID method's VDR, determined by services. E.g. with your proposal, something like did:web:example.com/path/resume.pdf could return a PDF resource from anywhere outside of example.com, which seems very strange to me. With the current approach, the "did:web" method could simply specify that did:web:example.com/path/resume.pdf returns the resource at https://example.com/path/resume.pdf, which I think makes much more sense.

@swcurran
Copy link
Contributor Author

@peacekeeper , I have a some comments to make in response to your last comment that I'll put in after, but the most important one is to ask how the following is supposed to work -- via the DID Resolution spec:

With the current approach, the "did:web" method could simply specify that did:web:example.com/path/resume.pdf returns the resource at https://example.com/path/resume.pdf

Is there something in the current DID Resolution spec that says that is supposed to be how it is happen?

@peacekeeper
Copy link
Collaborator

Is there something in the current DID Resolution spec that says that is supposed to be how it is happen?

In this section: https://www.w3.org/TR/did-resolution/#dereferencing-algorithm-resource

Step 9.1 says:

The applicable DID method MAY specify how to dereference the DID path and/or DID query of the input DID URL.

This means that the did:web DID method (and potentially other web-based DID methods) could define how to dereference something like did:web:example.com/path/resume.pdf

@dlongley
Copy link

dlongley commented Nov 1, 2025

I think the fact that some DID methods like web happen to run on HTTP is totally orthogonal to the FileService (or whatever name we prefer to give this) feature. That feature is decoupled from the specific DID method and intended to allow any controller of any DID document the capability to redirect DID URLs related to their DID document to locations of their choosing -- via the path component. It is also meant to be a backwards (and forwards) compatible feature, such that existing DID methods, that happen to have defined method-specific path resolution behavior, are unaffected by this -- except for DID documents where the controller opts into controlling their own paths.

It is already the case, to my knowledge, that DID methods can define path resolution however they would like -- such that, if desired, the web method could specify the kind of behavior Markus is mentioning. But that would not cover this feature. It would require the use of that method to get behavior that is not really DID-method specific, the behavior would be locked to a particular origin per DID (which doesn't cover the desired cross-origin redirection functionality), nor would that origin even necessarily be one of the origins of interest for path redirection by the DID document controller.

Here's the feature that's desired:

A DID controller can specify, in their DID document, a mechanism by which to have DID URL paths resolve to (redirect to) other URLs, i.e., other authorities that provide other resources, whilst using/preserving the path in the DID URL (with minimal optional path prefix adjustments). If desired, a controller can redirect DID URLs starting with the base path /foo to a wholly different location than those starting with the base path /bar.

This is not HTTP-specific, though obviously HTTP would be useful (including redirecting to a variety of different origins from the same DID document). In fact, a DID document controller using DID method X might even benefit by redirecting some DID URLs to other DID URLs that use method Y and/or Z.

In the issue(s) related to this PR, proposals were made to enable this feature as opt-in -- to ensure there was backwards compatibility for existing DID methods that defined their own path resolution already (and forwards compatibility for DID methods that might later define it).

If the proposed approach is somehow insufficient, perhaps we can add another query parameter to indicate whether path resolution is method-controlled or DID-document controlled. But hopefully what has been proposed is already sufficient and any confusion around this has either been due to some issues in the details of the specification, a lack of understanding that backwards compatibility was indeed considered, desired, and believed to have been achieved, or that there's some other oversight that could be adjusted to achieve it.

I understand there may be some other philosophical disagreements, but I think it's important that we at least have consensus on the aims of the feature, otherwise alternative proposals may not quite line up.

@swcurran
Copy link
Contributor Author

swcurran commented Nov 3, 2025

@peacekeeper -- thanks for your response. I had thought that might be the answer and in an earlier comment you said "it is a feature not a bug". That's at the core of our disagreement. I really think it is a "bug not a feature" that DID URL paths are not a DID Resolution-level capability that can be used as is for many use cases, and extended where needed by DID Methods, or (better) via DID Extensions. I may not have it exactly right in the PR, but I really think it is important that we have to have DID Resolution-level handling of DID URL paths.

@peacekeeper
Copy link
Collaborator

@swcurran I'm not fundamentally opposed to this. As I said, several years ago I also used to think about the DID Path exactly like you do now. But the removal of matrix parameters and simultaneous introduction of relativeRef changed a lot about the mechanics of DID URLs including the DID Path.

If we can answer some of the open questions in this thread, especially about backwards compatibility, DID URLs that don't require HTTP endpoints, and about the interpretation of DID parameters, then maybe there's a way to make it work. I just don't see it yet in this current PR, which in my opinion breaks a lot of things.

@w3cbot
Copy link

w3cbot commented Nov 6, 2025

This was discussed during the #did meeting on 06 November 2025.

View the transcript

DID URL Dereferencing PR

<ottomorac> w3c/did-resolution#221

ottomorac: There has been a lot of back and forth on this one, and we had to cancel a special topic call on it because of conflicts.
… Markus has expressed some feedback there.

wip: The only thing I want to flag is to JoeAndrieu, we might discuss this informally at TPAC, but Markus and Stephen won't be there, though they may be remote. When we get back we'll schedule a dedicated time to deal with it.
… I know, Joe, you have opinions, and it would be create to get them out there. Manu doesn't think we should close this and move on. He thinks we should work as a group to come together and move this forward.

JoeAndrieu: I'm not up to speed, and it looks like there has been a lot of activity in the last couple of weeks. My understanding is that Stephen was going to take things forward, but I haven't had time to see how people have responded. We should take some time at TPAC.

wip: At TPAC, I want to spend time on the more general issues. The agenda is pretty flexible at the moment, so we can make time for it.
… I expect it to be a dedicated session in November.

ottomorac: It would be evening time in America if we overlap with TPAC for part of the discussion to happen virtually.

wip: I don't think we'll have formal session for this. There are other things we need to make time for.

JoeAndrieu: If we as a working group want to take some of that meeting in Kobe at a time that's most convenient for virtual attendance, first thing Tuesday morning would be Monday 5pm Pacific.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.