Skip to content

major rewrite to address resolution/dereferencing confusion. take 2#315

Open
jandrieu wants to merge 17 commits intow3c:mainfrom
LegReq:resolve-deref-take-2
Open

major rewrite to address resolution/dereferencing confusion. take 2#315
jandrieu wants to merge 17 commits intow3c:mainfrom
LegReq:resolve-deref-take-2

Conversation

@jandrieu
Copy link
Copy Markdown
Contributor

@jandrieu jandrieu commented Mar 31, 2026

Replaces PR #311

I believe I have responded to all of the comments and suggestions in that PR.

Hopefully this one is easier to compare.

FWIW, I would move the dereferencing section ahead of the resolution section, as per my comment. However, since people complained about not being able to tell where the changes were, I reverted that edit. Otherwise, both sections would look like a complete rewrite.


Preview | Diff

Comment thread index.html Outdated
Comment thread index.html Outdated
Comment on lines +222 to +223
verification methods, such as attestations, authorizations,
encryption, and key agreement.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't have a concrete suggestion - apologies - but I think we need to distinguish the verification methods from the things the produce (attestions, authorizations etc).

Maybe verification method for purposes such as Feels a bit clunky though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah... Good catch. These are verification relationships.

Comment thread index.html
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html
@w3cbot
Copy link
Copy Markdown

w3cbot commented Apr 2, 2026

This was discussed during the #did meeting on 02 April 2026.

View the transcript

DID URL Dereferencing PR \[3\] (20 min)

<ottomorac> w3c/did-resolution#315

Otto Mora: this week to review this PR, and we will arrive at a special topic call with hopefully more concrete
… Concerns about what the changes required are, okay? And then we'll just move on

Will Abramson: Yeah, I just wanted to say that's one thing, too, Otto. Maybe, Joe, if you can take, I don't know...
… 10-15 minutes to just write up 1, 2, 3 on the ish… on the PR. I think that would be really helpful

Joe Andrieu: Yeah, I'm happy to do that...

Will Abramson: I'm sure we could do that. Yeah, great, thanks...

Otto Mora: Okay. So...

<swcurran> Joe What is the specific item that you said was dismissed -- the multiple resources? I've just lost track.

Otto Mora: Yeah, in the interest of time as well, like, yeah, I just want to give Joe time to present his change as well, because I think it is important as well that we understand it
… Um… so, Joe, please go ahead. You can highlight the changes if you like, uh, by screen sharing, or if you want to just tell us what the key changes are, that's fine too

Joe Andrieu: Sure, let me… let me speak to it first. There… there are two main changes...
… One is that I refactored the algorithm so that it was easier to understand
… Um, I had a very hard time understanding the existing algorithm when trying to contribute to Steven's work on the path handling algorithm
… Um, it was nearly impossible, with the way it was structured, to separate dereferencing from resolution
… Um, and it connected for me with, oh, maybe this is why Jeffrey Raskin thinks that it's confusing how we talk about dereferencing and resolution
… Um, so that was a start, and I started with the threat, uh
… the threat modeling exercise to socialize, here's a version of what I think the algorithm is, and people seem to buy into that. And so, that was the first write-up, is to say, hey
… Can we get this opening to express this different algorithm?
… Um, I guess there's a third thing, which is just the introduction that frames this issue about dereferencing, because the other big change, and this is a huge change, and I do apologize that it is… it is
… Um, it is substantial, which is to say, I got rid of this idea of a
… uh, software API and an interface for a dereferencer
… Because I think that is fundamentally a confusing concept, given how the rest of computer science and the web
… talks about and means dereferencing. So, I think what we need, um, is for
… A, uh, to describe how a client of the resolution process prepares, calls, and then
… deals with the response to resolution. I think because our URLs are different than other URLs, I think it's important
… To have that sort of distinction of what is the dereferencing algorithm. Um, but if we
… introduce in the… as we do in the current text, if we introduce this new object that is itself a dereferencer, then we have this underspecified thing that's a client
… which is calling the dereferencer. And so now we have 3 objects in our system, which we have to threat model, and which we have to explicitly define, and we don't have that client defined. It's not a conformant requirement
… Um, and I think there are some opportunities lost there because of that structuring. In particular, we don't have the spec anywhere that requires that the user is able to choose the resolver
… for particular DID methods. And I think that is a huge security flaw in the current approach
… Um, and I think where we would put that, I think, would be in the client component of the current spec
… But there isn't a client component of the current spec. There's a couple of lines in the current spec about, um, dealing with dereferencing a fragment, and that's something that this client software, which is otherwise underspecified
… Um, does. So those… those are the… the two big changes, is this effort to
… To get rid of this complex piece of additional software that isn't really how most of the rest of the web deals with dereferencing
… Um, and to clarify the algorithm, um, so that it was easier to understand from a first read

Otto Mora: Mm-hmm...

Joe Andrieu: And I'm open to all sorts of suggestions on how to clean that up. I'm actually very interested, Manny, in the criticisms you have of it, because if you think I got it wrong, I want to try and fix it...

Otto Mora: Okay...
… So those are the high-level changes. Uh… okay, I see Steven first. Steven?

Stephen Curran: I… I like...
… I think the client needs to be there. I don't think it should be
… in the middle of processing, so I would… would prefer to see. that
… It is that… that the client passes in
… a div URL
… That goes through a sequence of steps
… And returns a result
… And the client then does some processing on that result
… Um, I would prefer to see that style of piece, and then
… That logical piece of software
… It has to first retrieve a DID doc, and that may require the use of
… parameters, and so on. And then
… based on the remainder of the URL. do additional processing
… And then pass the result back to the client, and the client then
… May still do further processing, such as processing the fragment. I think that model

Otto Mora: Hmm...

Stephen Curran: works. Um, and so does it require two separate algorithms? Requires a single algorithm?...
… Um, where, obviously, the early part of the process is to find the appropriate DIDO to be dealt with, and the second part to be
… handle everything else that's on the URL that hasn't been
… Um, used in finding the… finding the object. So that's kind of how I would like to see it
… Doctor, I'm reading through yours today, I thought
… The thing that threw me was the client sort of in the middle of the process
… As if it was sort of multiple calls in and out of whatever's doing the resolution and dereferencing. That's it

Otto Mora: Okay, so just to get a range, so did URL...
… set of steps to… to process that. There's a result. That can then be shared with the client
… Did document, and then final, um
… Pass back to the client with any additional processing on the fragment that. Might be done by the client itself, is that right?

Stephen Curran: The only thing… the only thing you added there was the did doc. The did doc...
… Doesn't necessarily go back to the calling client if they didn't want it

Otto Mora: Okay...

Stephen Curran: That… but, I mean, that I'd be willing to talk about, is did we always also pass back the doc, but I… again, now you're starting to get into passing multiple things back, which gets complicated...

Otto Mora: Mm-hmm...

<Zakim> JoeAndrieu, you wanted to agree. Dereferencing should start off the specification rather than resolution

Stephen Curran: I'm not quite sure how you would handle that...

Otto Mora: Okay, thank you. Uh, Joe...

Joe Andrieu: Um, yeah, it's interesting. The way you described it is how I would describe the current algorithm. Um...
… The first PR, I, in fact, reorganized the document so that it was clear that dereferencing is the
… Starting, or the outer algorithm, and that resolution is an algorithm that happens in the middle of that
… Um, but that made it look like I rewrote everything because of the diffs. So, I put a little note in here that says, hey, I think dereferencing specifications should kick off this spec
… Um, but… so, in the order of the spec is not the order of the algorithm. And I believe the algorithm, uh, is exactly as you just described
… It's like, you are preparing for resolution, you are performing resolution, and getting a DID document, that's
… That's one pushback I'd have on what you just said. Resolution must return a did document, and so that algorithm needs to be defined in a way that
… um, honors that contract that we have with did method creators. Um, and I think the work is figuring out, well, how does the client do that? Like, how do they prepare and call resolution, and then what do they do with the response? And I think that is the outline you'll see in the dereferencing algorithm
… That's it

Otto Mora: Mm-hmm. So, I guess, did URL goes to either dereferencing or resolution?...
… Uh, initially, and then… and then just different results get… Sure

Joe Andrieu: No, no. The… what you do with a URL is you dereference it to bring it in the current context so that...

<swcurran> Absoluttely a DIDDoc must be resolved -- just a question of whether it is the result to the client

Joe Andrieu: Um, either the browser can display it, or you can pull it into a JavaScript process and use the data that came back from that
… Um, so dereferencing is the root action that you have a URL, you want to use it. First thing you do is you dereference it so you can get the reference that it is pointing to
… and then you can do something with it. So resolution is entirely a subset of dereferencing
… Um, and it's not that someone gets to choose one or the other at the beginning, um
… you are fundamentally dereferencing that did URL. Um, that's the reason you are calling resolution, is to. Get through that, the referencing process

Otto Mora: Okay, got it. So they… yeah, the referencing filter first, the pointer resource, then...

<ottomorac> Wip

Otto Mora: If it is indeed something to be resolved, then resolution applies. Okay. Thank you. Um… Uh, yes, Will

Will Abramson: Yeah, I don't know if Joe will like this, but I wondered about...
… like, is there a way that we can, um, apply some of these changes, like, that are smaller, right? Like, it feels like one of the main changes that I've seen you propose, Joe, which I think everyone is on board with
… is instead… for did resolution, right, we should pass in a did URL
… Uh, and probably the URL dereferencing algorithm could… should come first

<manu> I'm not on board with that :)

Will Abramson: I feel like people are on board with that, like, is there a smaller PR that could do that rearranging, maybe update the introduction like you proposed?
… And then there's a separate PR that is really about fixing or, you know, improving, refactoring
… that did URL dereferencing algorithm. Uh, another thing that I think it
… people are agreed with, but I'd like to hear that, if this is the case
… you, Joe, are proposing that dereferencing happens on the client, right? Like, so the client is dereferencing this URL. The first thing the client does is they call the resolver to get back the resolution result, which contains
… The did document. And then the client applies the dereferencing algorithm to that result
… And that would mean the change that I think is also in this PR is getting rid of the HTTPS binding for Dig URLD referencing
… I think people are… are okay with that, right? So it feels like there's… there's some bits of this PR that everybody is on board with that would be great to get into the spec
… sooner than later. And then there is a more contentious bit, which is about how we restructure the digital dereferencing algorithm. I guess I'd be interesting to hear if you think. These could be decomposed, or… no

Otto Mora: Yes...
… And… uh… Steven
… Oh, sorry, what's up? Let me see… look at this queue again. Uh, Manuel

Manu Sporny: Uh, yeah, so let me kind of point out the things I like about the PR. Um, I like the fact that it is breaking apart things that were previously together, right? Uh, I don't think we should have just one long algorithm, uh, you know, to do any one of the things that we're doing. So, plus one...
… For separating, kind of, the read resolution part from the dereferencing part
… I think that's a good change. Uh, I think it's a good change to remove the HTTP binding
… Like, I don't think we… we need that. Um… uh
… Okay, so those… and then the rewording, Joe's also… Joe is always very careful about, you know, making sure that we're using the right phrasing and wording throughout. I think there are a number of positive
… you know, changes there. There are other things that I didn't quite like. I don't know if it's in this rev, but there was some dead user
… you know, language there that I felt we were… we were creating new terminology that we didn't necessarily need to create. Um, okay, so going into the things that, you know, I don't quite like. Um, uh
… I think this stuff… the concepts can be introduced in a variety of different orders. I don't think that there is one right way to do it
… Right, so I reject the notion that we have to start with talking about, did URL dereferencing, and… and that is the… that is the entry point
… No, that we don't… that is not… that doesn't need to be the way that we explain it. I agree that it could be explained in that way, but I think explaining it in other ways is totally legitimate as well, like talking about, you know, the did resolution process, the thing that you get a DID document back from
… you can pass a did URL into that. It's totally… it's… that's a totally legitimate thing to do, right? Um, and if we want to talk about dereferencing completely separately, we can say dereferencing also takes a did URL
… in. It will call the resolution, you know, algorithm to get the did document and figure out what it needs to do, and then it'll do a whole bunch of other stuff, right? I'm not saying that we explain it in that way, that is certainly the way I have it modeled in my head
… Um, but I don't think there is one right way to… way to, you know, go through this and explain it. I think, you know, Jeff Free's comments can be, you know, explained in a variety of different ways, so
… Um, so coming at it, saying, did URLD referencing is the entry point, that is where we start, I don't think is… I don't think is
… it feels very weird to me. Not weird to the point that I'm going to object to the spec going forward in that path, but it's just kind of like
… That is definitely not the mental model I've ever had around, you know, dead resolution. Um
… Okay, uh, but going back to the good parts of this, uh, I think, uh, you know, teasing these things out and removing the HTTP binding are good things to do
… fundamentally, I think these are things that we can do during CR, because they do not change the outcome of the implementations
… Like, I don't… I don't see how this… like, I think it's a good, you know, rearranging to make. I do agree that there are probably some algorithmic things that are broken or need to be aligned
… But the fundamental outcome of, like, what does did resolution do, and what, as, you know, me as an implementer, what am I actually implementing, I don't think the end result changes
… Right? You're gonna get a DID document at some, you know, step, or you're gonna get some kind of resource at another step. And, you know, whether we use the algorithm, you know, that Steven has in PathService, or whether we figure out what the gaps are, if there are any
… with Joe's thing is… is kind of, like, implementation detail that's largely opaque. Uh, to the test suite. Um… That's it, for now

Otto Mora: Okay, Steven?...

Stephen Curran: Um, I'm gonna… I would prefer to see one long algorithm...

<ottomorac> Joe will have final word

<manu> I would prefer to NOT see one long algorithm.

Stephen Curran: Um, because I think it makes more sense. I… I do think we need to… I keep bringing up the fact that the spec currently says there's 5. Possible outcomes?
… From, um, dereferencing, or from… from
… the process, and I would really like us to
… Agree or not that these are the possible outcomes, and under what ways they come about
… and I think the one long algorithm leads to that
… The thing that gets returned is a did doc, then that would come out early, because you have to get the did doc first
… The only question is whether… is that the intended result?

<TallTed> One long algorithm might often be decomposable into several internal sub-algorithms...

Stephen Curran: from, uh, from the DID that is… the DID URL that's being processed. And again, I always use DID URL because, again, even if you're just getting the DID, because of version time and version
… ID, it's a did URL, even if the thing you're going to return is a did doc
… Um, I would also like to just add one more thing, which is my PR adds
… detail about how to handle a path, which to me is a very important part of a URL. That's all it does. It doesn't
… it fits in with the rest of it. I don't… you know, it's not fundamentally different, uh, adding anything fundamentally different, except to
… Provide a specification of what you do with a path, which to me is
… Um, is… is missing or way understated in the current spec. That's it

Otto Mora: Mm-hmm. Okay, uh, Joe is gonna have the final word, but I… during the special topic call, we will dedicate equal time to both of these, uh, pull requests...
… And, uh, then some, uh, close-up discussion time to just come to some kind of synthesis and agreement. Uh, so Joe, go ahead

Joe Andrieu: Thanks. Um...
… Uh, so, first of all, I think it would be easy, Steven, to incorporate

<swcurran> +1

Joe Andrieu: um, some version of the algorithm you're trying to define, like, into this PR, and I did not attempt to do that

<swcurran> Agreed

Joe Andrieu: I just tried to capture what was already in the spec with regard to relative ref, and how service parameters are treated
… Um, so I totally agree, this PR did not attempt to address that. Um, I think to your opening question, Will, I think the problem is that the root of this was about confusion between, uh, did resolution and dereferencing, and I don't think
… you know, piecewel changes are going to address that confusion. Um, we could cherry-pick some stuff, but we're not going to address Jeffrey Askins' concerns with that. Um
… I think, you know, to… Manu, I'm not sure why you think I said it had to be a certain way. Um, I said two different things. One is I said, I believe it would be clearer if we started with dereferencing. And one of the reasons I said that is because Steven, who's with us
… just interpreted that dereferencing was in the middle of the algorithm, but it's not. It happens to be in the middle of the document, and I think it's a natural thing that when people scan these documents, that, you know, they think it is going through the algorithm in order, and so I think we should put it in the order that things actually

happen
… The other thing I said is that what you do with the DID URL is you dereference it. This is a
… computer science concept, that that is just the action that happens. Um, the fact that we have not spoken about it that way is also probably why there's confusion in the marketplace
… Uh, and with regard to did URLUser, I'm happy to find a different term. I needed a term in the threat modeling exercise to talk about the individual who has a URL who's interacting with a device to do something with that URL
… Um, happy to figure out another term for it, um, but that was a term that came to mind
… And… and that's it

Otto Mora: Okay. Okay...
… So, uh, Wednesday, uh, the 8th, special topic call
… Yes, go ahead

Joe Andrieu: Wait, I'm sorry, I forgot, I had, um, a couple of other things. Um, I had two index cards, my apologies...
… Um, one is… one of the reasons I'm concerned with, you know, going to CR without
… figuring out which way we're going to go with this, is these are going to be normative changes. So even though it may not affect whether or not, um
… resolution changes, because I don't think there's any real proposed changes to the resolution algorithm

<manu> You can make normative changes in CR, even giant ones.

Joe Andrieu: But we are proposing that there are normative steps that the client of Resolver should go through before and after. Um, and I think also this speaks to that there are not, in my PR, 5 possible outcomes
… Did resolution has one outcome, which is a did document, and then the client does whatever they need to do, which could be a million different things
… They're going to take the result of that, and they are going to interpret in the current context. And in some cases, that will mean validating a proof on a verifiable credential. In other cases, it will mean putting something on the screen and scrolling to the appropriate context
… Um, and then, finally, the reason I think we have to have two algorithms is because people will implement resolvers, um, without implementing the AD referencer or a client

<Wip> +1 definitely

<swcurran> That's what the client does with the result. Not with the dereferencing returns.

Joe Andrieu: And so, if I have a did method, and I know that I need a resolver that supports a particular interface
… I need to have that algorithm clearly defined somewhere so that I can implement that, and it will work with whatever clients are out there, even though I may never implement a client. And that's it, sorry

Otto Mora: Okay. Uh, just one thing here on the timing for next week. So, Will, I see that the meeting is scheduled for...
… 10 to 11 Eastern. It's… this would be effectively set
… 7 Pacific, which might be
… A problem, it wouldn't be

Will Abramson: That's the time it is. Well, we...

Otto Mora: At the moment, it is… It needs to be… it needs to be the same time, right?...

Will Abramson: Yeah, I mean, we could try and find another time, but that's just been the time that we call. We've… been at, it feels like...
… Would be complicated to try and find another time, especially in time for next week

Otto Mora: So it… it needs to be 8am Pacific, right?...

Will Abramson: 7am Pacific is when we have always...

Joe Andrieu: Yeah, why do you...

Otto Mora: Oh, we've always had it. Oh, okay, just making sure...

Joe Andrieu: No, we've always had it at 7. Yeah, it's an annoying time for...

Otto Mora: Okay, okay, okay, sorry, yes...

Joe Andrieu: For some of us, but...

Otto Mora: Okay. Alright, well, then that's it...

Will Abramson: I will say, I think the transcriber bot is a success, right? Like, it's… I mean, I've not noticed, I've not, like, paid too detailed attention, but it seemed to work much better than last month...

<ottomorac> transcriber-bot, pause

Pierre-Antoine Champin: It was much better, yeah...


@TallTed
Copy link
Copy Markdown
Member

TallTed commented Apr 2, 2026

Replaces PR #311

Perhaps this should also be noted on #311?

@peacekeeper
Copy link
Copy Markdown
Collaborator

If I'm reading this correctly, it seems "relativeRef" is only mentioned in the "Service Selection Algorithm", not in the "Service Type Selection Algorithm"?

Also, I wonder about this sentence:

If the input DID URL contains the DID parameter relativeRef and a service of type "PathService" is selected ...

Does this mean that "relativeRef" is only supported in conjunction with PathService, not with "service" and "serviceType" parameters?

@peacekeeper
Copy link
Copy Markdown
Collaborator

Why does this remove the "expandRelativeUrls" and "verificationRelationship" options? Is this intentional or an accident?

Comment thread index.html Outdated
jandrieu and others added 2 commits April 2, 2026 16:32
Co-authored-by: Will Abramson <[email protected]>
Co-authored-by: Will Abramson <[email protected]>
Comment thread index.html Outdated
@jandrieu
Copy link
Copy Markdown
Contributor Author

jandrieu commented Apr 2, 2026

If I'm reading this correctly, it seems "relativeRef" is only mentioned in the "Service Selection Algorithm", not in the "Service Type Selection Algorithm"?

Also, I wonder about this sentence:

If the input DID URL contains the DID parameter relativeRef and a service of type "PathService" is selected ...

Does this mean that "relativeRef" is only supported in conjunction with PathService, not with "service" and "serviceType" parameters?

That's an oversight. We should probably apply that in both cases.

@jandrieu
Copy link
Copy Markdown
Contributor Author

jandrieu commented Apr 2, 2026

Why does this remove the "expandRelativeUrls" and "verificationRelationship" options? Is this intentional or an accident?

Because I got rid of the "dereferencer" as a library and the resolver should return the authoritative DID document.

I'd be on board with defining these algorithms for a resolver client to apply after getting the DID document from resolution, but in this proposal, the software formerly known as a dereferencer is the resolving client and they don't have to return anything. They bring the resource into the current context, as is appropriate for that context.

It's only because there's a "function" in the current spec that it needs to return things. But I think it is important to clarify what a resolving client does without requiring it to support external interfaces it has no reason for. Just like we don't require browsers to expose a dereferencing function for URLs. They just dereference into current context, as appropriate. CSS links get added to the CSS object model for the HTML page that has the link. Images are displayed. JavaScript elements are parsed and invoked. What is done with the resource is up to the client and trying to squeeze that through an interface is just confusing and weirdly limiting.

@peacekeeper
Copy link
Copy Markdown
Collaborator

@jandrieu I still don't get why you think that the current specifcation defines a dereferencer as a library or a piece of software that needs to "expose" something.

Dereferencing is a process/function which returns a result. The word "return" is meant in an abstract/logical way, just like the function of adding 1+1 "returns" the result 2. This doesn't mean that there is an external endpoint. When a browser dereferences an HTTPS URL including a fragment, then that dereferencing process/function also "returns" something.

If you look e.g. at Figure 10 of the current specification, it shows exactly what everybody is saying all the time, i.e. that dereferencing the fragment is done on the client side. I think this is exactly the same idea that you call "dereference into current context".

So I really don't understand where your confusion or desire for such major rewrites comes from?

jandrieu and others added 2 commits April 3, 2026 08:43
Co-authored-by: Will Abramson <[email protected]>
Co-authored-by: Will Abramson <[email protected]>
@jandrieu
Copy link
Copy Markdown
Contributor Author

jandrieu commented Apr 3, 2026

@jandrieu I still don't get why you think that the current specifcation defines a dereferencer as a library or a piece of software that needs to "expose" something.

Because the spec requires that dereferencers expose a function with specific inputs and outputs. Section 5 DID URL Dereferencing defines a function which MUST be implemented and MUST implement a particular interface.

dereference(didUrl, dereferenceOptions) →
   « dereferencingMetadata, contentStream, contentMetadata »

Dereferencing is a process/function which returns a result.

This is the heart of the disagreement. As my suggested PR puts it,

This algorithm may or may not return one or more values and may affect program state, depending on the context of use. For example, dereferencing in the context of web browsing may support any number of common URL usage patterns.

Dereferencing is an algorithm, which may affect the current context in any number of ways. Requiring that it return a content stream leaves the actual integration of that string into the current context to an underspecified "client" which is rather confusingly described:

client
Software and/or hardware that invokes a DID resolver in order to execute the DID resolution and/or DID URL dereferencing algorithms. This invocation is done via a binding. The term client does not imply any specific network topology.

This language implies the "client" == the software calling the resolver (which would be the dereferencer, NOT the client calling dereferencing. So, where do we define the client that calls the dereferencer?

I believe this is the heart of the confusion about dereferencing versus resolution. It's a strange anti-conflation between clients and dereferencers, which should be the same but are confusingly given different tasks at different times.

Specifically, when a DID URL with a DID fragment is dereferenced, then Dereferencing the Resource is done by the DID resolver, and Dereferencing the Fragment is done by the client.

I believe we've had some consensus that the resolver does not return the resource (except in the degenerate case where the resource is the DID document, but the caller doesn't know yet if that's the final resource without further evaluation, so its more accurate to say the resolver returns a DID document which may or may not be the final resource). So "dereferencing the resource" is definitely not what the resolver does. It returns the authoritative DID document. Getting the actual resource is the job of the client of the resolver, not the resolver.

In fact, section 5.4.1 explicitly describes what the dereferencer must do, NOT the resolver.

Validate that the input DID URL conforms to the did-url rule of the DID URL Syntax. If not, the DID URL dereferencer MUST return the following result:

So, if your prior statement were correct, it would be in conflict with Section 5.4.1 which clearly defines [Dereferencing the Resource] as something the DID URL dereferencer does.

This is inconsistent and confusing.

The word "return" is meant in an abstract/logical way, just like the function of adding 1+1 "returns" the result 2. This doesn't mean that there is an external endpoint. When a browser dereferences an HTTPS URL including a fragment, then that dereferencing process/function also "returns" something.

Respectfully, it is described much more explicitly as a function that MUST be implemented with a particular signature and responses. That's the problem. That definition, which is required for all conformant "dereferencers" does not fully dereference the URL into the current context, it returns a content stream that the client--who is actually dereferencing a DID URL into the current context--who must finish dereferencing. So the function as defined doesn't actually finish dereferencing, which is left to the "client" of the dereferencer. This is confusing.

If you look e.g. at Figure 10 of the current specification, it shows exactly what everybody is saying all the time, i.e. that dereferencing the fragment is done on the client side. I think this is exactly the same idea that you call "dereference into current context".

Yes, dereferencing the fragment is done by the client. So a fundamental portion of dereferencing cannot be achieved by the dereferencer. This is confusing. Why name a piece of software as a dereferencer if it doesn't actually dereference into the current context?

So I really don't understand where your confusion or desire for such major rewrites comes from?

Hopefully my previous comments highlight specific instances of confusion.

However, my rewrite is not from a desire to do so, but a commitment to answer Jeffrey's question from the TAG review.

First, Jeffry Yaskin in the TAG review:

The use of "resolution" here seems inconsistent with other uses. In particular, I don't think it's "the process of determining an access mechanism and the appropriate parameters necessary to dereference a URI" from https://www.rfc-editor.org/rfc/rfc3986.html#section-1.2.2, and it's not "the process of resolving a URI reference within a context that allows relative references so that the result is a string matching the syntax rule" from https://www.rfc-editor.org/rfc/rfc3986.html#section-5 (which is also used in https://www.w3.org/TR/did-1.1/#relative-did-urls). Is it the right term? Perhaps you're just defining how to "dereference" both DIDs and DID URLs?
There's a note that 'The difference between "resolving" a DID and "dereferencing" a DID URL is being thoroughly discussed', but the link doesn't point to a comment that discusses it. This should be resolved before publication.

In fact, I do think we mean resolution in the meaning in RFC3986 as referred to by Jeffrey. But our discussion of it is confusing. So I took on responding to Jeffrey. I had hoped that would be a simple clarification of a few sentences here and there, but once I got into it, I realized that the best way to get my concerns across was to present a fully-formed alternative.

Second, Stephen Curran, on multiple occasions has argued that the distinction between dereferencing and resolution doesn't make any sense to him and that we should just use the same term for both. That one of our own struggles to distinguish between the two is a fairly clear sign that our language isn't clear. It doesn't tell us how to fix it, but it does point to a deep conceptual divide in our own community.

Third, I tried to help Stephen separate dereferencing from resolution in PR #260. First commenting piecewise on the language in those PRs. Then, at his request, I attempted a rewrite to give him some language that would address my concerns while trying to support the feature he is trying to get into the spec.

I failed.

I got through an update of the initial section that introduced definitions for PathService and Relative Ref, but once I started looking at the dereferencing algorithm, I too found that it was too confusing to integrate Stephen's algorithm in a way that wouldn't break existing practice.

So, after Jeffrey, Steven, and I were unable to make sense of how the current specification handles the distinction between dereferencing and resolution, I first confirmed my understanding of the algorithm, using the context of the DID Resolution Threat Model to get feedback on the process as I understand it. #226 (comment) and #226 (comment)

Then I turned my attention back to the spec and realized that the algorithm as I understood it was, in fact, not the algorithm defined in the spec, which introduces a required component called a dereferencer, which paradoxically, can't actually dereference into the client context.

Ah-hah! I believe that this is where the confusion is. If you have to dereference the result of the dereferencer into the current context, then why is the dereferencer called a "dereferencer" and what is it really doing? I raised this as issue #310, which so far only you, Markus have responded to, with a very reasonable concern that it is late in the timeline to consider such far reaching changes.

Unfortunately, I don't know how to respond to Jeffrey's (and Stephen's and my) confusion without a revision that more clearly distinguishes the phases in the dereferencing algorithm and restores the client as the dereferencer and removes the intermediary that seems to be the root of the confusion.

So I provided spec text that I believe clears up the confusion.

This is a big refactoring, both in substance (removing the dereferencer) and in structure (making the algorithm clearer at the top level with better separation between stages).

It is late in the game to consider it. But we didn't realize how problematic it was until Jeffry and then Stephen brought the conflict to our attention.

This PR is simply my best effort to resolve the confusion that the current spec creates.

Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html Outdated
Comment thread index.html
Comment on lines +416 to 427
Some DID parameters are completely independent of any specific
<a>DID
method</a> and intended to function the same way for all
<a>DIDs</a>. Other DID parameters
are not supported by all <a>DID methods</a>. Where optional
parameters are
supported, they are expected to operate uniformly across the
<a>DID methods</a>
that do support them. The following table provides common DID
parameters that SHOULD function the same way across all <a>DID
methods</a>. Support for all
<a href="#did-parameters">DID Parameters</a> is OPTIONAL.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Some DID parameters are completely independent of any specific
<a>DID
method</a> and intended to function the same way for all
<a>DIDs</a>. Other DID parameters
are not supported by all <a>DID methods</a>. Where optional
parameters are
supported, they are expected to operate uniformly across the
<a>DID methods</a>
that do support them. The following table provides common DID
parameters that SHOULD function the same way across all <a>DID
methods</a>. Support for all
<a href="#did-parameters">DID Parameters</a> is OPTIONAL.
Some DID parameters are completely independent of any specific
<a>DID method</a> and intended to function the same way for all
<a>DIDs</a>. Other DID parameters are not supported by all
<a>DID methods</a>. Where optional parameters are supported,
they are expected to operate uniformly across the <a>DID
methods</a> that do support them. The following table provides
common DID parameters that SHOULD function the same way across
all <a>DID methods</a>. Support for each and every
<a href="#did-parameters">DID parameter</a> is OPTIONAL.

Comment thread index.html

<section id="dereferencing">
<h1>DID URL Dereferencing</h1>
<h1><dfn data-lt="DID URL Client|Client">DID URL Client</dfn></h1>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this "DID URL Client" algorithm is significantly under-specified such that an implementers will not know what to do. The following are a few examples that I think are problematic:

  • Combinations of service and serviceType parameters. For example, as specified serviceType parameters are silently ignored if a service parameter exists.
  • I don't see what happens when a service or serviceType is "selected"? It’s not clear to me what is the result of that selection.
  • Per the algorithm, if a property in the DIDDoc or DIDDoc Metadata is found that relates to dereferencing it should be used — without any trigger to indicate it should be used. I would interpret that as, if I pass in a DID URL that is “just a DID”, and I find a Linked Resource in the retrieved DID Doc, I am supposed to return the resource it points to. I’m sure that is not what is meant, but that is how I read it.
  • I don’t see that anything is defined if any other query parameters are encountered, or if a path is included.

While these are examples, I don't think this algorithm is backwards compatible with the existing spec (is that a goal?) and is incomplete.

In general, I think this algorithm is a step back from what is in the spec today, making implementations harder.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this "DID URL Client" algorithm is significantly under-specified such that an implementers will not know what to do.

That may still be true. However, I contend that it is far clearer what to do in this PR than in the current specification.

The following are a few examples that I think are problematic:

  • Combinations of service and serviceType parameters. For example, as specified serviceType parameters are silently ignored if a service parameter exists.

That's an interesting question. My personal opinion is that specifying both is overspecifying and I would return an error. @wip-abramson suggested maybe the better interpretation is that if both are used that a consistency check is applied such that if the service type doesn't match the service object specified by the service parameter, return an error.

What we should NOT do is simply return all the URLs for all the matching objects. How would the client understand which one was for which?

My algorithm has a specific prioritization. It could probably be improved, but IMO, if a service is named in a service parameter, that should define retrieval. If that service name fails to find any objects, the dereferencing should fail. A clear deterministic algorithm will simplify implementations. An algorithm that tries to waffle on how to prioritize will not.

  • I don't see what happens when a service or serviceType is "selected"? It’s not clear to me what is the result of that selection.

From the PR:

The retrieval strategy is determined by the type property of the selected service.

This is explicitly stated in the Section 6.3 Determine Retrieval Strategy steps 1 and 2.

  • Per the algorithm, if a property in the DIDDoc or DIDDoc Metadata is found that relates to dereferencing it should be used — without any trigger to indicate it should be used. I would interpret that as, if I pass in a DID URL that is “just a DID”, and I find a Linked Resource in the retrieved DID Doc, I am supposed to return the resource it points to. I’m sure that is not what is meant, but that is how I read it.

That is what is meant. We have an unresolved question about how the client knows which properties have that feature. My proposal is not in this PR, but I have proposed it in yours, Stephen. Define a type property that labels an object as a path handler.

If there's support for that, I could add it.

In fact, I have said many times that supporting the actual functionality you want @swcurran is going to be easier in this PR than in yours, which breaks linkedResources in ways that I still haven't succeed at explaining to you. I created that property. I know why it was designed the way it was, and there simply is no way to return a URL, did or otherwise, for all of the variants that linkedResources supports.

  • I don’t see that anything is defined if any other query parameters are encountered, or if a path is included.

Indeed. I don't know of any impact on dereferencing from any other query parameters. The ones defined in the spec like versionId and versionTime do not affect dereferencing, only resolution. Personally, I would rather NOT open up the dereferencing algorithm to dynamically change based on arbitrary query parameters other than service and serviceType. We have enough of a challenge handling the arbitrary properties that have their own dereferencing algorithms.

So, I didn't include it as I know of no approach to affecting dereferencing through query parameters other than service and serviceType. And I strongly think it would be a bad idea to extend beyond that. If we have evidence of practices in the wild that do in fact, do that, then I might be convinced, but please, let's not add complexity for some notion of consistency.

While these are examples, I don't think this algorithm is backwards compatible with the existing spec (is that a goal?) and is incomplete.

I'm sure it can be made more complete. I don't pretend that it is done. This is literally the first pass at a MAJOR change and if the group doesn't want to go in this direction, there's no need to improve it.

So, no, it was not designed to be compatible with the existing spec. It was designed to clear up the confusion that the existing spec has created. For you. For Jeffrey. For me. And, I believe, for a lot of folks.

Forcing dereferencing into a function call is a category error that, IMO, is adding exceptional complexity and confusion without actually creating any clear features or functions we don't already get by defining a coherent algorithm the client uses.

In general, I think this algorithm is a step back from what is in the spec today, making implementations harder.

It may make them harder, but I think it makes them clearer. What is hard is figuring out what to do with the five different kinds of results you might get from the dereferencer and even harder to figure out how to dereference a URL whose method you don't understand. And that latter part is, IMO, the entire point of the DID resolution spec: to allow arbitrary clients to get a DID document they can reason over within their particular context, regardless of the DID method. Once the client software needs to do things differently because of the DID method, we fail at interop.

I would welcome a PR from anyone else if folks see an easier way to respond to Jeffrey's confusion. At this point, it seems that I'm the only one who has been willing to take that on and it is more than frustrating to have my work attacked because it changes things. The POINT is to clear up the confusion. That means changes. Based on my read of the spec, that dereferencer is the cause and change is called for.

If you think otherwise, anyone, please suggest an alternative PR that you feel will clear up Jeffrey's concerns.

@swcurran
Copy link
Copy Markdown
Contributor

swcurran commented Apr 6, 2026

I’m not a fan of how the term “client” is used in this PR. In my mind, the goal of this specification is that a DID URL can be passed to different implementations of this specification, and the result returned will be the same from each. I think of the “client” is the thing that calls those implementations, and what gets back what it expects based on the DID URL it passed in and then using it in some way — via business logic that is outside the scope the specification. While I have struggled with the term “DID URL Dereferencer”, I think it separates it from client and should be retained. I would prefer not use the term “client” as it is used in this PR.

Copy link
Copy Markdown
Contributor

@wip-abramson wip-abramson left a comment

Choose a reason for hiding this comment

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

Currently there are a number of ReSpec linking inconsistencies that should be addressed.

At least the instances where the type of ReSpec linking used appears incorrect. E.g. a biblio link instead of a section

Comment thread index.html
Comment thread index.html Outdated
Comment thread index.html
@jandrieu
Copy link
Copy Markdown
Contributor Author

jandrieu commented Apr 8, 2026

If I'm reading this correctly, it seems "relativeRef" is only mentioned in the "Service Selection Algorithm", not in the "Service Type Selection Algorithm"?

Also, I wonder about this sentence:

If the input DID URL contains the DID parameter relativeRef and a service of type "PathService" is selected ...

Does this mean that "relativeRef" is only supported in conjunction with PathService, not with "service" and "serviceType" parameters?

Not exactly. If another service type wants to use relative ref, that's fine too. I was trying to split the difference with @swcurran's PR and support the only service type I know of that uses relative ref. It certainly is the only one proposed so far to be defined in this specification.

What should happen if relative ref is defined and there is no service endpoint known to use that query parameter? Happy to update if we figure out how we want to handle that.

Another thing came up when @wip-abramson and I discussed this.

One consequence of this update to the algorithm is that it becomes exceptionally clear that when dereferencing a DID URL with a service or serviceType query parameter, that the service definition needs to define a retrieval strategy.

And none of the service types I know adequately address this. There was a long held assumption by many of us--and I also bought into it--that a service is likely derereferenced by applying a GET request of the http URL in the service_endpoint property. But that sort of tribal assumption is one of the things we need to formalize when we define a spec like this one.

That approach doesn't work if the service endpoint isn't an HTTPS URL. You can see this is the challenge with the bitcoin: scheme used in the endpoints for BTCR2. A "standard" dereferencing of that endpoint is just going to hurl. If fact, according to BIP 21 https://en.bitcoin.it/wiki/BIP_0021 that URI is used for making bitcoin payments and when dereferenced in a wallet brings up a payment form prefilled with that bitcoin address. This is clearly not how you retrieve the data from a Beacon as defined in BTCR.

The BTCR2 specification doesn't talk about how to dereference a DID URL with a service query for a beacon (from example at https://dcdpr.github.io/did-btcr2/data-structures.html#initial-did-document-example-panel-show) :
did:btcr2:k1q5pvh5zask8khdg7p58ygveewkcufetu3dlqyaca5dzqct6mjhf540qhrxgv3?service=%23initialP2PKH

In theory that SHOULD dereference to something, but what is undefined.

Instead, that URL is actually used as a URI by the resolution algorithm and is really, only ever used when validating the chain of updates as described in resolution.

Its "retrieval strategy" when accessed directly is undefined.

Which is, IMO, the right boundary. If a dereferencing client gets a URL with that service, but it doesn't know how to retrieve the resource for a "SingletonBeacon" it should error out.

@jandrieu
Copy link
Copy Markdown
Contributor Author

jandrieu commented Apr 8, 2026

I’m not a fan of how the term “client” is used in this PR. In my mind, the goal of this specification is that a DID URL can be passed to different implementations of this specification, and the result returned will be the same from each. I think of the “client” is the thing that calls those implementations, and what gets back what it expects based on the DID URL it passed in and then using it in some way — via business logic that is outside the scope the specification. While I have struggled with the term “DID URL Dereferencer”, I think it separates it from client and should be retained. I would prefer not use the term “client” as it is used in this PR.

Yes. We share that goal.

But the term "client" is not one I created. It was already in the specification, underdefined as just the "client of the resolver".

A URL (did or otherwise) can be passed to any application that wants to consume it, but what actually happens with it is entirely context-dependent.

A URL in an RDF statement is used differently than a URL in a hyperlink is different than a URL in a Verifiable Credential.

Even within the browsing context, what is expected to be consistent is that all browsers will attempt to render the same resource (or really a representation of a facet of that resource) by querying the same authority and treating its response as authentic. But different browsers handle different media types differently. Some browsers--like Brave--intentionally do NOT dereference many of the tracking mechanisms that most browsers blindly process, which absolutely breaks many web pages, even when Brave is displaying exactly the same HTML as another browser. The commitment is not the equivalence of the rendering, but the equivalence of the network request to retrieve a representation of the resource from a server specified by the authority (which includes CDNs and round-robin DNS approaches).

I think of the “client” is the thing that calls those implementations, and what gets back what it expects based on the DID URL it passed in and then using it in some way — via business logic that is outside the scope the specification.

Yes. That's exactly what the client is. The client, which is the software that calls the resolver, is the one that processes the business logic to apply the result of resolution to the current context. There is no dereferencer needed in that flow and plenty of reasons it creates problems, which I have enumerated.

Copy link
Copy Markdown
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.

In general I like the idea of making the dereferencing process more modular, but for now:

  1. As I mentioned in #315 (comment), I think this PR breaks how service, serviceType, and relativeRef work at the moment.

  2. Also, several of my comments in #311 have not been addressed and still apply here in this PR.

  3. I disagree with removing several features such as verificationRelationship and expandRelativeUrls, which we have extensively discussed in the past and decided to include.

  4. This removes the dereference() function, and I worry that this might break the use cases I listed in #306 (comment).

@jandrieu
Copy link
Copy Markdown
Contributor Author

jandrieu commented Apr 9, 2026

In general I like the idea of making the dereferencing process more modular, but for now:

  1. As I mentioned in #315 (comment), I think this PR breaks how service, serviceType, and relativeRef work at the moment.
  2. Also, several of my comments in first complete pass at resolution/dereference clean up. still draft. #311 have not been addressed and still apply here in this PR.
  3. I disagree with removing several features such as verificationRelationship and expandRelativeUrls, which we have extensively discussed in the past and decided to include.
  4. This removes the dereference() function, and I worry that this might break the use cases I listed in #306 (comment).

I'll take a look at these in more detail and attempt to address what I can.

jandrieu and others added 11 commits April 12, 2026 13:08
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]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
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.

6 participants