Closed mwherman2000 closed 5 years ago
The DID ABNF is more than a syntax specification ...more than a grammar...
_The DID ABNF is an algebra for working with the DID Document associated with a DID._
Let's use it that way. We don't need to invent anything new or extra.
@mwherman2000 thanks for consolidating some of your suggestions into a single issue. I think many of them are useful and will be implemented by DID Resolvers.
But as we discussed several times already, I think it will be very important to distinguish between:
I don't understand what value you see in conflating these 3 separate design issues into a single syntax definition. But we can certainly discuss it again on the next DID Resolution call!
I don't understand what value you see in conflating these 3 separate design issues into a single syntax definition.
@peacekeeper Why have 2 or 3 different, disconnected syntaxes? ...especially for basic operations like the dereferencing use cases 2a - 2d.
so, in the current world of hypertext and browsers the #
is never sent to the server and thus the browser handles the dereferencing and parsing. see: https://en.wikipedia.org/wiki/Fragment_identifier and therefore we have chosen to use this character to separate the did url from the decryption key for certain applications in IPID.
next problem. I don't know what invocation of a service endpoint
means. Is this on the DID document as an object capability (a la veras one) or on a service endpoint defined in the DID document. If it is the later then that would be very much dependent on the underlying DID method and difficult to lock down in these early days especially one that are purely blockchain focused.
@mwherman2000 next problem if you ask if a DID document exists, then the resolver is going to fetch it. So did:xyz:1234?exists
is and unnecessary waste of the resolver's resource. Like I said on the call, I'm thinking more about this like DNS resolution. Doesn't make sense to ask if there is record, because it is a process of requesting the record from the specific DNS server and if it isn't in the servers cache requesting it upstream. For privacy concerns, I am NOT supportive of caching, BTW, not to mention issues with eclipse attacks (see: https://eprint.iacr.org/2015/263.pdf ).
did:xyz:1234?exists
would make sense to see if it is cached locally, while you are fetching the upstream nameserver in the background. But part of the request has to be how long am I waiting to be satisfied that the record is up to date and no eclipse attack is happening.
So, I'm thinking that the DID resolution spec needs to have some consensus to perform the same functions on the DID document. Similar to how dig
and host
do on the linux command line.
dig @8.8.8.8 example.com
which returns:
` ; <<>> DiG 9.10.6 <<>> @8.8.8.8 example.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63594 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;example.com. IN A
;; ANSWER SECTION: example.com. 16059 IN A 93.184.216.34
;; Query time: 14 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Thu Mar 07 16:09:20 CST 2019 ;; MSG SIZE rcvd: 56`
By default dig
queries the DNS servers listed in your /etc/resolv.conf file, which are normally the DNS servers of your ISP. However, it can also be useful to query other DNS servers, and particularly the authoritative DNS server. In this analogy, each DID method will have their own authoritative primary source of truth. The job of the DID resolver is to act as a go-between as not every use will be running their own blockchain for each of the DID methods that use one.
@jonnycrunch Two separable issues:
so, in the current world of hypertext and browsers the
#
is never sent to the server and thus the browser handles the dereferencing and parsing. see: https://en.wikipedia.org/wiki/Fragment_identifier >
This is true. I actually woke up in the middle of the night to install Fiddler and verify this. You're correct. The "#" should be changed ...but only in the context of the overall set of did-url
requirements. The use cases, are this point, is our best source for the requirements for the did-url
syntax patterns we need to be done.
TODO: Find a replacement for "#" ...other than ""$" (see https://github.com/WebOfTrustInfo/rwot8-barcelona/issues/163)
therefore we have chosen to use this character to separate the did url from the decryption key for certain applications in IPID.
@jonnycrunch Do you have some example? ...this would be a good place to record some of the IPID examples.
Also, as a start/placeholder, I've added category G. DID Resolution Decode/Decrypt Use Cases to the use cases. Use cases 16a and 16b are examples that are consistent with the current patterns used in the use cases.
NOTE: We can keep consuming another special character for each new parameter/capability/operation we want to support in the did-url
. At the syntactical level, we need to keep the number of constructions as small as possible.
next problem. I don't know what
invocation of a service endpoint
means. Is this on the DID document as an object capability (a la veras one) or on a service endpoint defined in the DID document. If it is the later then that would be very much dependent on the underlying DID method and difficult to lock down in these early days especially one that are purely blockchain focused.
@jonnycrunch As discussed on yesterday's call, I had the Category B use cases (invocation) completely wrong. I've renamed them B. DID URL Service Endpoint Transformation Use Cases (using ";" token) ...a bit wordy but it's a start at correcting the problem.
I also referenced Paul Windley's article in the Comments column for use cases 2c and 2d.
RE: DNS discussion
Like I said on the call, I'm thinking more about this like DNS resolution. Doesn't make sense to ask if there is record, because it is a process of requesting the record from the specific DNS server
@jonnycrunch DNS isn't IMO a comparable. DNS is a binary protocol that is designed to be very efficient and highly performant. The typical request and response messages are very short - typically less than 100 bytes. (Read https://hyperonomy.com/2019/01/02/dns-domain-name-service-a-detailed-high-level-overview/).
The DID URL procotol is not efficient - the typical response is, comparatively, extraordinarily large (relative to a DNS response). In addition, on some Verifiable Data Registries (aka ledgers), multiple requests are required to create a fully-formed DID Document (e.g. Indy)
The need for the did:xyz:1234?$exists
operation is designed to address these types of inefficiencies.
if it isn't in the servers cache requesting it upstream
I'm not advocating caching as a requirement either. did:xyz:1234?$exists
can be an optional operation on a DID method by method basis.
To address optional operations, there is use case 11 in category E:
did:xyz:?$supportedCapabilities
I elaborate more on this operation here:
RE: use case 3. did:xyz:1234?exists
ambiguity problem
During yesterday's call, I noticed there was an ambiguity in the above syntax (relative to use cases 2c and 2d).
I've fixed this by prefixing all "operations" with a "$" sign. This goes further to make the syntax for "operations" more consistent with the syntax for $select, $filter, $top, $skip
, etc.
The new syntax for use case 3 is: did:xyz:1234?$exists
...and by extension: $ping, $getMethods, $supportedCapabilities
, etc.
next problem. I don't know what
invocation of a service endpoint
means. Is this on the DID document as an object capability (a la veras one) or on a service endpoint defined in the DID document. If it is the later then that would be very much dependent on the underlying DID method and difficult to lock down in these early days especially one that are purely blockchain focused.@jonnycrunch As discussed on yesterday's call, I had the Category B use cases (invocation) completely wrong. I've renamed them B. DID URL Service Endpoint Transformation Use Cases (using ";" token) ...a bit wordy but it's a start at correcting the problem.
I also referenced Paul Windley's article in the Comments column for use cases 2c and 2d.
@jonnycrunch @peacekeeper I've added two new categories of use cases. While these are new, the use cases in each category are proposed replacements for some of the earlier use cases.
Now that I better understand how service-id
transformations are supposed to work (e.g the Windley article), in Category H, I'm proposing a more general did-url
transformation capability that will help create a stable DID syntax that won't stifle innovation.
Category I is related: it uses a parallel concept for dereferencing the JSON fragment for a particular service-id
.
What are your thoughts?
$serviceid
transform option)These are alternatives (replacements) for use cases 2c1 and 2d1.
The following use cases use the "!" pipe option and $serviceid
transform option (aka $serviceid
transformer). These tokens immediately follow would formally be the full did-url
. The semantics are: take the did-url
up to the "!" pipe option and pass it through a transformation represented by the transform options that follow the "!" pipe option.
For example, if the transformer was $serviceid="<service-id>"
. the effect would be to produce the resolved URL/URI for, in this case, the service endpoint corresponding service-id
. See the table below for more specific examples of the syntax.
Conceptually, the processing is:
did-url
| transform(tranformOptions) to produce a transformed-url
Here's are 2 specific examples based on the Windley examples. These examples also make clear the difference between the transformer approach and the ';' approach:
Approach | Example |
---|---|
Windley | did:sov:123456789abcdefghij;exam_svc |
Transformer | did:sov:123456789abcdefghij!$serviceid="exam_svc" |
Both of the above resolve (dereference) to the same URI/URL: https://example.com/endpoint/8377464
Approach | Example |
---|---|
Windley | did:sov:123456789abcdefghij;exam_svc/foo/bar?a=1#flip |
Transformer | did:sov:123456789abcdefghij!$serviceid="exam_svc"/foo/bar?a=1#flip |
Both of the above resolve (dereference) to the same URI/URL: https://example.com/endpoint/8377464/foo/bar?a=1#flip
NOTE: DID schemes and/or DID Resolvers can define additional transform options. They are not limited by the syntax specification.
NOTE: The ";" token is no longer used anywhere in DID syntax patterns represented across all of the use case categories.
NOTE: Related (and reflecting the views of @dhh128 in comment https://github.com/w3c-ccg/did-spec/pull/168#issuecomment-471655338), there should no longer be a need to use ";' or any special symbol (other than "#") in the id
attribute of a service endpoint in a DID Document.
Use Case | did-url Syntax Example |
Corresponding HTTP Binding Example | Comments |
---|---|---|---|
2c2. Transform the DID URL using corresponding service endpoint using "!" pipe character and $serviceid transformation option (no parameters) | did:xyz:1234!$serviceid="bops"? |
http://uniresolver.io/did:xyz:1234!$serviceid="bops"? |
Alternative proposal for use case 2c1 |
2d2. Transform the DID URL using corresponding service endpoint using "!" pipe character and $serviceid transformation option (w/parameters) | did:xyz:1234/foo/bar?a=1#flip!$serviceid="bops" |
http://uniresolver.io/did:xyz:1234did:xyz:1234/foo/bar?a=1#flip!serviceid="bops" |
Alternative proposal for use case 2d1 |
These are alternatives (replacements) for use cases 2b1 and 4b1. These use cases use the "$serviceid" selector option which follows the "?" query option.
Use Case | did-url Syntax Example |
Corresponding HTTP Binding Example | Comments |
---|---|---|---|
2b2. Dereferencing a service-id to return the JSON description (fragment) of the service endpoint. |
did:xyz:1234?$serviceid="bops" |
http://uniresolver.io/did:xyz:1234?$serviceid="bops" |
Alternative proposal for use case 2b1 |
4b2. Does this DID Doc contain a service endpoint corresponding to a particular service-id resolvable by this DID Resolver |
did:xyz:1234?$serviceid="bops"&$exists |
http://uniresolver.io/ddid:xyz:1234?$serviceid="bops"&$exists |
Alternative proposal for use case 4b1 |
Next steps? Suggested community plan of attack...
a. The Use Cases for Decentralized Identifiers document is a good input to helping identify additional did-url use cases in addition to what is currently documented in DID Resolver did-url Use Cases (#32 tables A though I ...add additional tables for additional categories of did-url use cases as required. b. Tuesday, start reviewing and discussing the current DID Resolver did-url Use Cases (initially tables A through I). c. Build an executable did-url grammar for the common patterns found in the did-url use cases by adapting the BB version (saved here: https://github.com/mwherman2000/indy-arm/blob/master/abnf/did-abnf-2019-03-06.abnf) d. Validate the executable did-url grammar against the did-url examples from the tables using http://arran.fi.muni.cz/bnfparser2/ e. Interate: b. though d.
Thoughts?
I'd like to share this doc, which @mwherman2000 , @talltree and I discussed yesterday: https://docs.google.com/document/d/1KRuQIPbcXpYbO2fxlbxU5GBNUDc3uCouoiyzNHHH3N0/
It's an attempt to compare 1. @mwherman2000 's way of thinking about DID URLs and Resolution (where the DID URL grammar is considered an algebra or protocol that fully encapsulates resolution operations and parameters), vs 2. an approach where DID Resolution use cases, operations and parameters are specified using a set of abstract functions that are not part of the DID URL itself, but can then have different bindings.
Yes, it was a good discussion ...putting different options on the table and discussing each one to make each option better as well as discussing the relative merits of each.
Also note that column 1 and column 2 might not be mutually exclusively: that is, especially for more common/frequently used resolution/dereferencing did-url
use cases, it would be convenient to use column 1 syntax patterns while still supporting the "method" syntax of column 2. Similarly, in column 2, there may be more than one acceptable construction.
At this point, all of these are just options on the table for discussion. The following 2 articles (plus some other specifications like OData and WebDAV helped to inform the discussions):
Agreed that it was a good discussion yesterday, and that all of what we're discussing in this thread will be front and center as we advance the DID spec (to the Community Final version) and the DID Resolution spec (to the first complete draft) before the end of April.
We'll cover some of this on the weekly CCG calls but a reminder that we will begin a weekly 2 hour block of calls (first hour on the DID spec and second hour on the DID Resolution spec) starting this coming Thursday from 20:00-22:00 UTC. We'll send an email to the list the day before with the Zoom Room info.
A reminder that
On Sat, Mar 16, 2019 at 8:18 AM Michael Herman (Toronto) < notifications@github.com> wrote:
Yes, it was a good discussion ...putting different options on the table and discussing each one to make each option better as well as discussing the relative merits of each.
Also note that column 1 and column 2 might not be mutually exclusively: that is, especially for more common/frequently used resolution/dereferencing did-url use cases, it would be convenient to use column 1 syntax patterns while still supporting the "method" syntax of column 2. Similarly, in column 2, there may be more than one acceptable construction.
At this point, all of these are just options on the table for discussion. The following articles (plus some other specifications like OData https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=odata and WebDAV http://www.webdav.org/ helped to inform the discussions):
- Giving Grammars Written with ABNF Notation the Respect They Deserve https://hyperonomy.com/2019/03/11/giving-grammars-written-with-abnf-notation-the-respect-they-deserve/
- The #OpenToInnovation Principle: Internet protocols and standards not only need to be open, but more importantly, open to innovation https://hyperonomy.com/2019/03/12/internet-protocols-and-standards-not-only-need-to-be-open-but-more-importantly-open-to-innovation/
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/w3c-ccg/did-resolution/issues/32#issuecomment-473543631, or mute the thread https://github.com/notifications/unsubscribe-auth/ADLkTYKaMzjAFNdIO2XQDgrkQGD_R6Z3ks5vXQtTgaJpZM4bIW_Z .
@mwherman2000 I believe in https://github.com/WebOfTrustInfo/rwot8-barcelona/issues/122 you propose to incorporate not only "resolution"-related operations and their parameters into the did-url
syntax, but also the other DID operations "create", "update", "deactivate". I am curious what this would look like?
I think this would be akin to proposing that HTTP verbs such as POST/PUT/GET/DELETE plus HTTP headers should all be part of the HTTP URI syntax, or proposing that file system operations such as mkdir/rmdir/ls would have to be part of a file system's path syntax.
We should keep in mind the section Separating Identification from Interaction in the URI spec (RFC3986), which the DID spec builds on. It says:
Given a URI, a system may attempt to perform a variety of operations on the resource, as might be characterized by words such as "access", "update", "replace", or "find attributes". Such operations are defined by the protocols that make use of URIs, not by this specification.
I think some of your use cases (not all) about the did-url
grammar conflate identification with interaction, rather than separating them.
Since posting that comment relative to https://github.com/WebOfTrustInfo/rwot8-barcelona/issues/122 19 days ago, I'm "in the middle" ...as reflected in our 1:1 conversation last Friday ...my thinking has advanced.
I see https://github.com/WebOfTrustInfo/rwot8-barcelona/issues/122 as a set high-level use cases akin to the DID Use Case document that, in turn, should guide creation/updating the lower-level did-url
grammar use cases in https://github.com/w3c-ccg/did-resolution/issues/32.
I'm definitely not suggesting encapsulating all of the https://github.com/WebOfTrustInfo/rwot8-barcelona/blob/master/topics-and-advance-readings/Universal-DID-Operations.md functionality in the did-url
grammar ...but rather taking a critical/detailed/technical look at each method and its parameters to determine what should be encapsulated in the did-url
(via the did-url
grammar) and what should go into the options
...that is, establish a set of principles to provide guidance one way or another.
Moved to:
The content of this issue is now obsolete and has been closed.
Guiding Principles
service-id
in a single DID Document associated with a DID.did-url
syntax - eliminating the need for creating additional language and/or API constructs, where possible.did-url
parsing (and DID Resolution, specifically but not exclusively) ...that is, that the "DID ABNF" doesn't restrict the syntax patterns needed for present and futuredid-url
parsing (and DID Resolution, specifically but not exclusively) innovation. This is especially important because the current "DID ABNF" is completely defined in a different specification from the DID Resolution specification (i.e. the DID Specification).Background
In today's DID Resolution community call (Feb. 21, 2019), there was a early/initial discussion about using an HTTP binding pattern such as:
http://uniresolver.io/resolve/did:xyz:1234
http://uniresolver.io/dereference/did:xyz:1234#key1
I was surprised to see the above pattern being proposed because the
resolve
anddereference
operations are redundant ...but that's why we have these conversations (and write things down).I assume that the purpose of the current DID ABNF syntax discussions is to encapsulate these types of operations into what we are currently calling a
did-url
(link). Based on these assumptions, I expected that the followingdid-url
patterns (and corresponding HTTP bindings) will be used as the primary patterns for the previous 2 use cases:http://uniresolver.io/did:xyz:1234
(Reference: https://github.com/w3c-ccg/did-spec/issues/170#issuecomment-467272441)http://uniresolver.io/did:xyz:1234#key1
(Reference: https://github.com/w3c-ccg/did-spec/issues/170#issuecomment-467272441)did-url
Use CasesThe complete set of DID Resolver use cases is presented in the following tables. They represent a set of 20+
did-url
patterns that are guided by the current draft DID ABNF specification. These DID Resolver use cases represent a validation suite for successive versions of the draft DID ABNF specifications.A. DID Document Resolution and Dereferencing Use Cases B. DID URL Service Endpoint Transformation Use Cases (using ";" token) C. DID Document Operations Use Cases D. DID Document Collection Operations Use Cases E. DID Resolver Service Operations Use Cases F. DID Resolver Service Response Format Use Cases G. DID Resolution Decode/Decrypt Use Cases H. DID URL Service Endpoint Transformation Use Cases (using "!" pipe option and
$serviceid
transform option (transformers)) I. DID URL Service Endpoint Dereferencing Use Cases (using "$serviceid" selector option)NOTE: You may have to scroll left and right to see all 4 columns of the table.
A. DID Document Resolution and Dereferencing Use Cases
did-url
Syntax Exampledid:xyz:1234
http://uniresolver.io/did:xyz:1234
did:xyz:1234#key1
http://uniresolver.io/did:xyz:1234#key1
service-id
to return the JSON description (fragment) of the service endpoint.did:xyz:1234;bops
http://uniresolver.io/did:xyz:1234;bops
did:xyz:1234?$select="<selectexpression>"
http://uniresolver.io/did:xyz:1234?$select="<selectexpression>"
<selectexpression>
syntax TBDdid:xyz:1234#key1?$select="<selectexpression>"
http://uniresolver.io/did:xyz:1234#key1?$select="<selectexpression>"
<selectexpression>
syntax TBDB. DID URL Service Endpoint Transformation Use Cases (using ";" token)
did-url
Syntax Exampleservice-id
and transform the URI/URL for the corresponding service endpoint (with no parameters)did:xyz:1234;bops?
http://uniresolver.io/did:xyz:1234;bops?
service-id
and transform the URI/URL for the corresponding service endpoint (with parameters)did:xyz:1234;bops/foo/bar?a=1#flip
http://uniresolver.io/did:xyz:1234;bops/foo/bar?a=1#flip
C. DID Document Operations Use Cases
did-url
Syntax Exampleservice-id
resolvable by this DID Resolverdid:xyz:1234;bops?$exists
http://uniresolver.io/did:xyz:1234;bops?$exists
D. DID Document Collection Operations Use Cases
did-url
Syntax Exampledid:xyz:1234?$exists
http://uniresolver.io/did:xyz:1234?$exists
did:xyz:1234#key1?$exists
http://uniresolver.io/did:xyz:1234#key1?$exists
did:?
http://uniresolver.io/did:?
did:xyz:?
http://uniresolver.io/did:xyz:?
did:xyz:?$top=10&$skip=100
http://uniresolver.io/did:xyz:?$top=10&$skip=100
did:xyz:?$filter="<filterexpression>"&$top=10&$skip=100
http://uniresolver.io/did:xyz:?$filter="<filterexpression>"&$top=10&$skip=100
<filterexpression>
(did:xyz:?&$top=10&$skip=100&$select="<selectexpression>"
did:xyz:?&$top=10&$skip=100&$select="<selectexpression>"
<selectexpression>
syntax TBDE. DID Resolver Service Operations Use Cases
did-url
Syntax Exampledid:?$ping
http://uniresolver.io/did:?$ping
did:?$getMethods
http://uniresolver.io/did:?$getMethods
did:xyz:?$supportedCapabilities
http://uniresolver.io/did:xyz:?$supportedCapabilities
F. DID Resolver Service Response Format Use Cases
NOTE: $format is composable with any of the the above use cases that, by default, return a JSON string. The following are simple pattern examples only.
did-url
Syntax Exampledid:xyz:1234?$format="json"
http://uniresolver.io/did:xyz:1234?$format="json"
did:xyz:1234?$format="atom"
http://uniresolver.io/did:xyz:1234?$format="atom"
did:xyz:1234?$format="xml"
http://uniresolver.io/did:xyz:1234?$format="xml"
G. DID Resolution Decode/Decrypt Use Cases
did-url
Syntax Exampledid:xyz:1234?$decode="<parameters>"
http://uniresolver.io/ did:xyz:1234?$decode="<parameters>"
did:xyz:1234?$decrypt="<key>"
http://uniresolver.io/ did:xyz:1234?$decrypt="<key>"
H. DID URL Service Endpoint Transformation Use Cases (using "!" transformer (pipe) option and
$serviceid
transform option)These are alternatives (replacements) for use cases 2c1 and 2d1.
These following use cases use the "!" pipe option and
$serviceid
transform option (aka$serviceid
transformer). These tokens immediately follow would formally be the fulldid-url
. The semantics are: take thedid-url
up to the "!" pipe option and pass it through a transformation represented by the transform options that follow the "!" pipe option.For example, if the transformer was
$serviceid="<service-id>"
. the effect would be to produce the resolved URL/URI for, in this case, the service endpoint correspondingservice-id
. See the table below for more specific examples of the syntax.Conceptually, the processing is:
did-url
| transform(tranformOptions) to produce atransformed-url
Here's are 2 specific examples based on the Windley examples. These examples also make clear the difference between the transformer approach and the ';' approach:
did:sov:123456789abcdefghij;exam_svc
did:sov:123456789abcdefghij!$serviceid="exam_svc"
Both of the above resolve (dereference) to the same URI/URL:
https://example.com/endpoint/8377464
did:sov:123456789abcdefghij;exam_svc/foo/bar?a=1#flip
did:sov:123456789abcdefghij!$serviceid="exam_svc"/foo/bar?a=1#flip
Both of the above resolve (dereference) to the same URI/URL:
https://example.com/endpoint/8377464/foo/bar?a=1#flip
NOTE: DID schemes and/or DID Resolvers can define additional transform options. They are not limited by the syntax specification.
NOTE: The ";" token is no longer used anywhere in DID syntax patterns represented across all of the use case categories.
NOTE: Related (and reflecting the views of @dhh128 in comment https://github.com/w3c-ccg/did-spec/pull/168#issuecomment-471655338), there should no longer be a need to use ";' or any special symbol (other than "#") in the
id
attribute of a service endpoint in a DID Document.did-url
Syntax Exampledid:xyz:1234!$serviceid="bops"?
http://uniresolver.io/did:xyz:1234!$serviceid="bops"?
did:xyz:1234/foo/bar?a=1#flip!$serviceid="bops"
http://uniresolver.io/did:xyz:1234did:xyz:1234/foo/bar?a=1#flip!serviceid="bops"
I. DID URL Service Endpoint Dereferencing Use Cases (using "$serviceid" selector option)
These are alternatives (replacements) for use cases 2b1 and 4b1. These use cases use the "$serviceid" selector option which follows the "?" query option.
did-url
Syntax Exampleservice-id
to return the JSON description (fragment) of the service endpoint.did:xyz:1234?$serviceid="bops"
http://uniresolver.io/did:xyz:1234?$serviceid="bops"
service-id
resolvable by this DID Resolverdid:xyz:1234?$serviceid="bops"&$exists
http://uniresolver.io/ddid:xyz:1234?$serviceid="bops"&$exists
Next Steps
Your thoughts? @peacekeeper @dmitrizagidulin
@talltree Please chime in