- From: Manu Sporny <msporny@digitalbazaar.com>
- Date: Sat, 3 Jan 2026 15:59:16 -0500
- To: Stephen Curran <swcurran@cloudcompass.ca>
- Cc: W3C Credentials CG <public-credentials@w3.org>
On Wed, Dec 17, 2025 at 7:47 PM Stephen Curran <swcurran@cloudcompass.ca> wrote: > I wanted to add my perspective as an editor of the did:webvh spec on the recent did:cel announcement and this discussion. Hey Stephen, thank you for your input and careful consideration of the topic, as always. I delayed this response to give all of us some peace throughout the holidays instead of trying to launch into a big back and forth analysis of did:webvh vs. did:scid vs. did:cel. One thing that is emerging in this thread is a common feature set, which is a good sign -- we didn't have that for a fully decentralized DID Method many years ago when we started down this path. I do hope we can align as many things as possible, ideally landing on a single DID Method that achieves each of our goals (more or less). With that said, let me try to elaborate on places where I think there might not be philosophical alignment (yet) and why that matters. > Given how close the two methods are in design and intent, I’m concerned about the risk of unnecessary fragmentation Yes, I share the same concerns, which is why this discussion is good and timely -- before we head into the DID Methods standardization work. > The "heartbeat" idea is useful and an easy addition to did:webvh because of the existing "parameters" concept, It's good to hear that you think the "heartbeat" idea is useful. I wish we didn't need it, and cringed at the concept when Dave Longley initially noted that the whole concept of did:cel is broken without it. The thing that it does, that I don't like, is it "bloats" the log. Granted, it's not real bloat because it serves a purpose, but the heartbeats can be many times more frequent than key rotations. I can't think of any way around it (other than anchoring to an external log, which creates its own dependencies). That said, I want to focus on this concept of "it's an easy addition to did:webvh" -- that's where I think there is philosophical divergence. The approach did:cel is taking is the bare minimum necessary to achieve "fully decentralized", which means that it tries very hard to eliminate optionality. It attempts to eliminate as much optionality as possible to reduce the attack surface as much as possible. For example, we are seriously considering eliminating the usage of domain names entirely from the specification to avoid a binding to DNS. If we do that, we eliminate all of the DNS-based attacks on the system. did:webvh, on the other hand, has enough optionality to be more open to attack in certain scenarios. For example, the domain portability feature, and the ability to turn domain portability off is a significant attack vector. I do get why it is a nice feature to have when you want to go from one domain to the next, and I'm on the fence about whether or not did:webvh should have it, but I sure don't want that feature for did:cel (because it doesn't need it). I know there will be a propensity for any DID Method to say: "We can add that feature!" -- but that is where there is a difference in philosophy. There are features that I don't think did:cel should have, even as options. > Making the DNS part of a did:webvh DID optional is a topic we have discussed several times in the did:webvh Working Group and are already considering for the next version. Two thoughts on that: If DNS were optional in did:webvh, it would make it equivalent to the current version of did:cel (which might drop DNS entirely). Again, this sort of optionality is (per the philosophy of did:cel) -- a bad thing. IMHO, this all has to do with where the root of trust resides. In did:web, the root of trust is in the domain itself -- the threat model there is well known. did:webvh changes that where the identifier contains the domain as the root of trust but sometimes you ignore that value and at other times you don't. That optionality makes things more difficult to reason about and I expect implementers to misimplement that optionality in dangerous ways. For example, I can imagine a developer seeing a domain name as a part of a did:webvh identifier and then performing business logic based off of that domain name without checking to see if the domain name is valid at the head of the current log file. That behavior is very different than did:web, which is why the optionality it's problematic... it leads developers to wrong conclusions about the threat model. > That said, we did put in the spec that the witness "must verify the log entry being witnessed", but we can (and will likely) remove that line, as that is a governance -- and we should not dictate that. With that, we have oblivious witnesses. Yes, if that feature is removed from did:webvh, you'll have oblivious witnesses, which would benefit the specification, IMHO. At that point, I wonder if the Watchers feature should be externalized so that other DID Methods could use it? > So these are all easy changes to the did:webvh spec. Requires a new version, but easily fitting in the design and we definitely appreciate the ideas! Good to hear that some positive sharing of ideas and adoption of common technology primitives is occurring! That's a positive outcome from this thread alone. > "did:webvh identifiers are not stable". If a did:webvh DID is portable and "moved", it is by definition a new DID, but retains its SCID and verifiable history. This opens new use cases (porting the DIDs reputation when moving DID publishing platforms) and eases the transition when its storage location must change. Portability is thus an optional feature, not a bug. As I mentioned above, I don't think it's as simple as saying it's a "feature" -- there are downsides to every feature and the portability of did:webvh has both significant upsides and downsides. I tend to think it has more downsides than upsides right now (though am still thinking through it). At a high level, I wish I didn't have to think about all the sorts of attacks one could do with both DNS and portability in play. There is also much to consider with "it is by definition a new DID" -- that tells me that "it's portable" has a pretty big caveat -- are people that use did:webvh going to understand the ramifications of that nuance? What do I store in the database table for the account identifier? The SCID+domain or just the SCID itself -- because one of those things breaks when you try to port domains and some poor developer implemented the wrong thing. > Counter -- what happens when a did:cel uses the ?storage... form when issuing millions of credentials, and the storage location goes away? It's a good question. A couple of loosely formed thoughts for now: 1. Don't use did:cel to issue millions of credentials. It's not designed for that. Use did:web instead. :) 2. `?storage` is NOT a part of the DID (it's a DID URL, not a DID), so at no point should you fully rely on the query parameter. The protocols can hint at new storage locations, and clients can nudge servers that only have the old storage location cached. I'm not entirely happy with this response, because there's a lot of handwaving there around things we haven't deployed in practice yet... but the bottom line is, you shouldn't rely on `storage` in the same way you rely on the domain in did:webvh today. > "did:webvh has pre-rotation commitments". That is a feature that did:cel should consider. Easy to specify, optional, and adds security -- if it is wanted/needed. Yes, agreed. I do think did:cel is weaker than did:webvh in that regard. That said, I'm wondering if it is a good idea to separate the key that updates the DID Document log from an assertion method key in the DID Document (which is supposed to be used to assert things by the controller). There's a key management concern here that I'm not sure we've explored yet. For example, if those pre-rotation keys live in HSMs, that's a significant cost. If they live outside of HSMs that's a significant security concern. I don't think "which one is safer" is as clear cut as it might seem at first, especially if you have a recovery key as a "big red button" if things go wrong. IOW, it might be that you don't need to do that pre-rotation thing if you have a recovery key offline or in an HSM somewhere. This might be an either/or thing, and if it is, pre-rotation is the more brittle choice from a security perspective. > "did:webvh requires heavier, stateful infrastructure (witnesses, domains, and watchers)". Leaving domains aside for now, did:webvh does not require that infrastructure -- it is up to the ecosystem using did:webvh. For ecosystems that require external verification, and longevity (decades), did:webvh provides technically simple approaches that enable ecosystems to decide on how to use (or not) those features. This might be where we differ in our opinions the most. I read "it's up to the ecosystem" as "the threat model is complex". Here are just some of the potential future choices with did:webvh (per this thread): * Do or don't use DNS * Do or don't use heartbeats * Do or don't use oblivious witnesses * Do or don't use domain portability * Do or don't use Watchers * Do or don't use a parallel did:web document There are 64 combinations there, and if we make the changes to did:cel discussed in this thread, we eliminate all of those combinations, which means developers don't have to think about all of those combinations when they use did:cel and implementers don't have to include mitigations for a subset of those combinations. That is the primary thing I'm trying to highlight wrt. differences between did:cel and did:webvh and did:scid. It's the security complexity added by the optionality that is of greatest concern. > If an ecosystem (such as the Pharma industry) requires that watchers be in place for decades in case the DID Controller goes out of business, did:webvh gives them a method to do so. Isn't that problem solved with long-lived, well-known CEL storage services? You don't necessarily need the additional complexity of Watchers to achieve that use case? > If an enterprise wants to apply governance/policy rules about DIDs published by their sub-entities, they can require they witness DID Log Entries before publication (as BC Gov is doing now with did:webvh). Sure, but you can do the same w/ did:cel, no? > Regarding domains -- did:cel acknowledges that "storage" is necessary--some place to store the DID Doc. That's infrastructure and did:webvh's can be just as light or heavy. Until did:webvh is "just as light", it's going to add optionality that is going to require more analysis and thinking wrt. implementations. > "the use of JSON Lines requires state". This is a benefit -- a DID resolver can choose to trade off state for speed with JSON Lines. With did:cel's structure, there is not such an option -- you have to retrieve/process the entire log. What are you depending on to do partial transfers? I expect you're using Range? If so, are you aware of the list of issues with the Range header? Again, this is extra security attack surface where I'm not sure that the benefits outweigh the drawbacks. > That said, we're likewise pretty happy with the performance of did:webvh -- here's a benchmark for a 10 year-old DID, updated monthly, with multiple witnesses: https://didwebvh.info/latest/faq/Performance/ For an "organizational" DID that rotates keys every 3 months and never deletes the keys over a 30 year period, the very preliminary numbers we have show that did:cel's log file is 3x larger at 600KB (because the entire DID Document is written for every update), and most of the size in that log file is uncompressible public key information and signatures. For a "personal" DID that rotates keys every year with a 3 month heartbeat period, the log is roughly 47KB in size for a 30-year log. I expect the memory and processing overhead is going to be greater for did:cel (gzip decompression, which can be streamed, and JSON processing, which can be streamed for did:cel -- neither of which is implemented right now). All that to say -- we're within an order of magnitude of each other and those file sizes and processing times are so miniscule these days that I don't think either are an issue. > "did:webvh...fully backwards compatible set of extensions to did:web" -- I'm not sure where that came from. It was based on John Jordan's summary that I heard years ago, which I probably misheard due to wishful thinking. :P > A DID Controller can easily transition to from did:web to did:webvh by publishing a did:webvh and applying the mechanical steps to publish the corresponding did:web in parallel. Yes, well that presumes others will allow did:webvh. What I was really hoping for was an additional mechanism to get a higher assurance did:web without all of this extra optionality. I think we can still get that with a subset of features that did:webvh has, but it's the optionality that I'm questioning. IOW, I wish did:webvh was split into two distinct things w/o all the optionality -- an improvement to did:web where the root of trust is the DNS and the web server (with a witness log file), and the portions of did:webvh that are effectively the same as did:cel. I think that would create two DID Methods that have clear security boundaries that excel for what they are intended to be. > I hope we can get together and discuss these in the future -- hopefully in a W3C DID Methods Standardization Working Group. Yes, +1 to that. I'm curious to see your responses (as well as others on this mailing list) to all of the above (apologies, it's long, which is why I didn't send it before the holidays). Perhaps we should schedule a call or three after that, though waiting until the DID Methods WG kicks off would be fine as well. -- manu -- Manu Sporny - https://www.linkedin.com/in/manusporny/ Founder/CEO - Digital Bazaar, Inc. https://www.digitalbazaar.com/
Received on Saturday, 3 January 2026 20:59:57 UTC