W3C home > Mailing lists > Public > public-credentials@w3.org > June 2020

Re: Verifying JWT Verifiable Credentials

From: Orie Steele <orie@transmute.industries>
Date: Tue, 9 Jun 2020 14:42:12 -0500
Message-ID: <CAN8C-_+J+nsCNP=Uo2Pu5Xs7yqdPKdKN8y3Xh9nc4WmN=NHXrQ@mail.gmail.com>
To: Dominic Wörner <dom.woe@gmail.com>
Cc: "W3C Credentials CG (Public List)" <public-credentials@w3.org>
There is no consensus on key resolution for JWT with VC Data Model.... it's
been a huge problem, and has been discussed many times... We were finally
able to add this language to did core, which hints at a standard way of
resolving a public key from a kid...

It is RECOMMENDED that JWK kid values are set to the public key
fingerprint. It is RECOMMENDED that verification methods that use JWKs to
represent their public keys utilize the value of kid as their fragment
identifier. See the first key in EXAMPLE 15 for an example of a public key
with a compound key identifier.


however the value of kid in the JWS can either be `did:example:123#kid` or
`kid`... I strongly urge everyone to use `did:example:123#kid` and not rely
on an undocumented / non standard combination of `iss` and `kid`... unlike
JWT in OAuth... there is no spec for doing what did-jwt does... consider
also that `iss` and `vc.issuer` might both be used, or only 1 might be
used... because VC-JWT says:

For backward compatibility with JWT processors, the following
JWT-registered claim names MUST be used *instead of, or in addition to*,
their respective standard verifiable credential counterparts

So semi-safe verify JWS from a did logic logic based on did-core and
vc-data-model today looks like this:

If its a vanilla JWS (not a VC-JWT) check the JWS header for `kid`... if
its a VC-JWT, check the payload `iss` or `vc.iss`... figure out which did
is the issuer... resolve the issuer did... or `kid`.

If its a vanilla JWS, search all the
https://w3c.github.io/did-core/#verification-relationships for the public
key to use to verify.

If its a VC-JWT, search assertionMethod for the public key to verify

If its a VP of a VC-JWT also encoded as a JWT, search authentication for
the key to verify...

Someday, we will have this documented somewhere... and we can just
reference it... I think it's high time we updated the vc-data-model to
explain how to use VC-JWT correctly, and in particular how to use JWS / JWE
with DIDs... when the payload IS NOT a VC.


On Tue, Jun 9, 2020 at 7:52 AM Dominic Wörner <dom.woe@gmail.com> wrote:

> Hi,
> We currently work with JWT VC because of the lack of proper JSON-LD
> tooling in Java.
> The iss property of VCs is a DID and I have a question on the verification
> algorithm since it's not well defined in the data model spec because it is
> out of scope.
> After reading the spec, we implemented the following approach:
> * Resolve issuer DID
> * If kid in header then get pubkey with kid form did doc. If not found =>
> abort
> * If no kid in header then there must be only one public key
> Now, I've looked at the code of
> https://github.com/decentralized-identity/did-jwt
> There the following approach is taken (if I'm correct)
> * Resolve issuer DID
> * Get authenticators (pub keys referenced in authentication array in DID
> doc)
> * Try all authenticators. Fail only of none of the authenticators work
> I don't think the library handles the usage of a kid in the header.
> This leaves me with the question, is there consensus about the
> approach taken in did jwt? ;)
> * Public Keys to verify VCs, need to be referenced in the authentication
> block of the DID doc
> * It's not required to reference a specific key in the VC if there are
> multiple keys in the DID doc?
> I can see that the second point has some advantages. Given I have a DID
> doc with a single public key and I create a VC without specifying the kid,
> I would invalidate the VC by adding another key to the DID doc, if the
> verifier would not try all keys.
> Best,
> Dominic

Chief Technical Officer

Received on Tuesday, 9 June 2020 19:42:37 UTC

This archive was generated by hypermail 2.4.0 : Tuesday, 9 June 2020 19:42:37 UTC