Re: did:cel - a cryptographic event log-based DID Method

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