Skip to content

Can't implement did-method-specific behavior for dereferencing when there's a path or a query #687

@vdods

Description

@vdods

In https://www.w3.org/TR/did-resolution/#dereferencing-algorithm-resource item "9)" says:

The applicable [DID method](https://www.w3.org/TR/did-resolution/#dfn-did-method-s) MAY specify how to dereference the [DID path](https://www.w3.org/TR/did-resolution/#dfn-did-paths) and/or [DID query](https://www.w3.org/TR/did-resolution/#dfn-did-queries) of the input [DID URL](https://www.w3.org/TR/did-resolution/#dfn-did-urls).

I see that DIDResolver has a method dereference_primary_with_path_or_query that's meant to handle this case (though its link to the spec are broken; see above for the current spec), but:

  • DIDResolver doesn't have a way to delegate that did-method-specific handling to the impl of DIDMethod, say through a method of the DIDMethod trait, call it fn handle_path_and_or_query (dumb name, but it's just for the purposes of explanation).
  • If it did, it would need to also pass the parameters primary_did_url, parameters, and resolution_output (of fn dereference_primary_resource) into the hypothetical DIDMethod::handle_path_and_or_query method.

The reason I bring this up is because my DID method, did:webplus, uses query params in the IDs for its verification methods, so that the precise versionId (and selfHash) fields from the DID document the verification method belongs to, so that the DID resolver can retrieve exactly the DID document needed when verifying a signature.

Currently I have my own hacked fork of the ssi crate that dereferences the output regardless of if there's a path or a query in the DID URL:

In pub(crate) async fn dereference_primary_resource<'a, R: ?Sized + DIDResolver> in ssi/crates/dids/core/src/resolution/dereference.rs

         None => {
-            // 2
-            if primary_did_url.path().is_empty() && primary_did_url.query().is_none() {
-                // 2.1
-                return Ok(DerefOutput::new(
-                    PrimaryContent::Document(Box::new(resolution_output.document)),
-                    document::Metadata::default(),
-                    resolution_output.metadata,
-                ));
-            }
-
-            // 3
-            if !primary_did_url.path().is_empty() || primary_did_url.query().is_some() {
-                return resolver
-                    .dereference_primary_with_path_or_query(primary_did_url)
-                    .await;
-            }
-
-            // 4
-            Err(DerefError::NotFound)
+            let _ = resolver;
+            return Ok(DerefOutput::new(
+                PrimaryContent::Document(Box::new(resolution_output.document)),
+                document::Metadata::default(),
+                resolution_output.metadata,
+            ));
         }

This probably doesn't work for all purposes, and certainly doesn't conform to the dereferencing spec (in that it doesn't allow for did-method-specific behavior).

What I would propose is to add some sort of handling method to DIDMethod to handle this case ("9)" in the dereferencing spec. Have any thoughts on the matter? This proposed method would be called instead of DIDResolver::dereference_primary_with_path_or_query

Also note that the links given (to https://w3c-ccg.github.io/did-resolution/ ) in the doc comment are broken. Here's my update:

-/// [Dereferencing the Primary Resource](https://w3c-ccg.github.io/did-resolution/#dereferencing-algorithm-primary) - a subalgorithm of [DID URL dereferencing](https://w3c-ccg.github.io/did-resolution/#dereferencing-algorithm)
+/// [DID URL Dereferencing](https://www.w3.org/TR/did-resolution/#dereferencing-algorithm).
 pub(crate) async fn dereference_primary_resource<'a, R: ?Sized + DIDResolver>(
     resolver: &'a R,
     primary_did_url: &'a PrimaryDIDURL,
     parameters: Parameters,
     resolution_output: Output,
 ) -> Result<DerefOutput<PrimaryContent>, DerefError> {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions