Resolver Refactor #422
Replies: 7 comments 25 replies
-
I really like the idea of caching for future resolutions. I wonder if we need to expose the possibility to to specify the TTL of the cache. I guess with the current proposal implementers can choose when to reuse the resolver or create a new one, but maybe we could build in support for configurable caches (see https://github.com/decentralized-identity/did-resolver#caching for thoughts on that). |
Beta Was this translation helpful? Give feedback.
-
Where would that theoretical standard compliant resolver live? It sounds that would be external to identity.rs? Would that be external to the IF? |
Beta Was this translation helpful? Give feedback.
-
In general, this seems like a step in the right direction 👍. I agree with @eike-hass on the standard compliance. We can offer this better interface for our users, but should probably also provide a compliant resolve function.
I don't fully understand the idea here. If the I also don't get why the So unless I misunderstand, I would let let did: IotaDid = "did:iota:Gh9LYviikgCnakMtrLcCCk7F4zUsjKzZGwikRi5gMvCr".parse().unwrap();
let resolver_factory: ResolverFactory = ResolverFactory::new(client_map, resolution_options);
let resolver: Resolver = resolver_factory.resolve(did).await?;
let full_document: CoreDocument = resolver.document(); // instead of getResult()
let older_document: CoreDocument = resolver.document_at(5); // instead of getDocument()
let verification_method: DocumentProperty = resolver.dereference("#key-1")?;
// Match and see what we got
match verification_method {
DocumentProperty::VerificationMethod(method) => {},
DocumentProperty::Service(service) => {},
}
|
Beta Was this translation helpful? Give feedback.
-
First off, I love the idea of designing and building an API that is specialized for the languages that developers are going to be using to build applications, and not only providing a JSON constrained spec-compliant API. Thank you for starting this discussion! As a caveat to the below, I spend way less time in this code base and using the APIs then you all do, and wrote this at the end of a long day so please forgive any misunderstandings :) What I like about the proposal:
What I find confusing and/or have questions about: A. The spec is VERY specific about the difference between "resolution" and "dereferencing" (I've read several long threads about this in various forums), especially what the allowed inputs and outputs are. The current proposal conflates these two definitions which is confusing at best, and at worst could lead to an entirely incorrect understanding of the API by someone familiar with the spec
B. One API to rule them all is not always what it's cracked up to be
C. MEGA-NIT!! Is "Factory" the right term here? Usually "factory" is used in a context when you aren't specifying the type of object being created. There's nothing magical or generic going on here so another term would probably be better :) Responses to (some of) your open questions:
Since it's only needed during the As an additional option, the
Building one ourselves would answer this for us 🙃 (see my other response) Okay, that's enough for now, I have more thoughts but this is already WAY too long for this format! |
Beta Was this translation helpful? Give feedback.
-
In case this API is going to replace the History API:
|
Beta Was this translation helpful? Give feedback.
-
We would like to come to a conclusion on this discussion and have converged on two options that we would like some final thoughts on, before we make a decision. In the team, we voted on being spec-compliant, but that doesn't mean we can't expose a separate API that we feel is better. So with both options we will have a Option 1// did is of type did, not did_rul
let resolution: Resolution = resolve(did, resolution_options);
let document: IotaDocument = resolution.document();
let metadata: DocumentMetadata = resolution.metadata();
let history: DocumentHistory = resolution.history();
let old_document: IotaDocument = history.document_at("2021-10-01");
// ResolutionResult is an enum that wraps IotaDocument, and all kinds of properties on the document
let service: ResolutionResult = document.dereference("key-1");
let service2: ResolutionResult = old_document.dereference("key-1");
// Additionally, we have a high-level dereference method that takes a DidUrl
let dereference: ResolutionResult = dereference(did_url, resolution_options); Here we have freestanding functions Option 2// did is of type did, not did_rul
let document: IotaDocument = resolve(did, resolution_options);
// DocumentMetadata is an IotaDocument + imetadata
let metadata: DocumentMetadata = resolve_with_metadata(did, resolution_options);
// DocumentHistory is a wrapper around an array of DocumentMetadata, so it includes metadata & document
let history: DocumentHistory = resolve_with_history(did, resolution_options);
let old_document: IotaDocument = history.document_at("2021-10-01");
let service: ResolutionResult = document.dereference(did_url); Here, we have three distinct functions, with the same functionality as option 1. Each function returns more data than the method before, in the sense that Notes on both optionsWe want to have the ability to resolve documents at some point in the past, for example, to check if a credential together with an older document state was valid. In the presented approaches, the entire history needs to be computed, to then call A side discussion: In both examples, it's also imaginable to have a
I hope that includes any points raised before, if not, feel free to point them out. |
Beta Was this translation helpful? Give feedback.
-
Opened #486 to address the required metadata changes. Resolver API issue: #493 |
Beta Was this translation helpful? Give feedback.
-
Note: Discussion timeboxed until Wednesday 5th of October, after which it will be converted to an issue. Discussion will still be possible, but implementation will get started.
The
did
module contains aresolution
module that has two functions:resolve
anddereference
. These follow the suggested API format as suggested inside the W3C DID standard. The DID standard is generally a JSON format standard rather then forcing an API design on the implementers, this is different with DID Resolution, where they enforce functionalities in a certain way. I propose to deviate from the DID Resolution standard making our framework a confirming DID, DID Document, producer, consumer and method but not a conforming DID resolver or URL dereferencer. As these are split, it doesn't break our DID compatibility and I still think we can return the data-structures as they require them, just with a different API. This means a second-layer solution on top of the IOTA Identity framework CAN be a conforming DID resolver and URL dereferencer.Motivation
DID Resolution is a resource intense operation. It produces a lot of network traffic as many API requests are send too the IOTA node and every resulting IOTA message must be parsed and validated. Caching and resolving old versions of a DID Document is currently not supported in the framework and we have a separate DID History API to at least have access to the history of a DID Document.
In addition, the DID Resolution already requires a lot of work to follow the proposed data structures from the DID standard, add support of DID parameters and move several fields from the DID Document to the
didDocumentMetadata
. This is a good time to review how it works and refactor if necessary.Proposal
As such I would like to propose a design for the DID resolver for within the IOTA Identity framework. Feel free to disagree or provide a counter proposal. Data formats that follow the W3C DID Resolution spec are tagged with "(W3C)" after it.
The
resolution
module would contain a ResolverFactory that developers can use to set the application settings such as aClientMap
orresolutionOptions
(W3C). In addition it has a function toresolve
given aDID URL
, returning aresolver
object. This `resolver object has done the requires DID Resolution or URL dereferencing during its creation.The
resolver
object has the following functions:getResult
: Returns the expected value of type DID Document or varied depending if aDID
orDID URL
was provided.getDocument
: Returns the DID Document from the resolved DID. This could take in a parameter to also return older states of the DID Document.getResolutionMetadata
: ReturnresolutionMetadata
(W3C) to allow compliance with DID standard.getDocumentMetadata
: ReturndidDocumentMetadata
(W3C) to allow compliance with DID standard. This could also take in a parameter to return the metadata of an older DID message.dereference
: Given aDID URL
returns a "part of" the DID Document.It might also need to inherit more functionalities from DID History API, but I am not familiar enough with it to determine if all functionality is properly included here.
Advantages
Given the above object, we now simplify the API from
resolve
,resolution
andDID History
into one single powerful API call. It still is able to generate all required metadata to allow the development of a W3C compliant Resolver and a single resolve action can be reused throughout an application. A major optimization that is now possible, is too allow the verification of Verifiable Credential (VC) or Verifiable Presentation (VP) to now take an existingresolver
object, removing duplicated DID resolution actions and at the same time allowing a VC or VP to verify given an "outdated" DID Document. This allows application developers to check if a VC/VP was valid during a certain time.Additional Required Changes
Move the following fields over from DID Document to
didDocumentMetadata
as suggested in the spec, keep in mind that they stay on-tangle in the DID Messages:created
andupdated
previousMsgId
(inside amethod
object (As suggested in the example)proof
(inside amethod
object)Rename a few fields and parameters that are named differently (e.g.
InputMetadata
should beresolutionOptions
), that should follow the spec.Inside the
ResolutionMetadata
we should probably removeresolved
(no purpose?) and introduce a boolean fieldcached
that can if true, caches the entire history. To support caching, it would need to be part ofresolutionOptions
.Add support for
versionId
,versionTime
,service
andrelativeRef
DID Parameters.Resources
Link to any resources relevant for the task such as Issues, PRs, reference implementations, or specifications.
message_id
inIotaDocument
#361Account
to resolve remote DIDs #387Open Questions
resolutionOptions
be part of the Resolver settings instead of being passed into the Resolver Factory?resolve
functionality be removed? ([Request] AllowAccount
to resolve remote DIDs #387)resolver
have to completely replace the DID History API?Beta Was this translation helpful? Give feedback.
All reactions