Authentication for Vaccine Passports
Posted by ekr on 02 May 2021
Via Ben Adida I learned about the Vaccine Credentials Initiative (VCI). I'm pleased to see that they provide a fairly complete set of specification for their credential. last week. At a high level, it's a digitally signed credential using conventional cryptograpy, (JSON Web Signatures, signed with ECDSA and P-256), and encoded into a QR code. This allows it to be printed on paper and just carried around without some kind of smart phone app. This seems like a pretty sensible design and roughly matches the kind of system I argued was reasonable.
However, as I was reading the specification, I started to think about the key management problem, which seems kind of unsolved: we're going to have a lot of different groups/organizations giving shots to different people and we need somehow to turn that information into credentials that people can use. Moroever, we need those credentials to be interoperable: any valid credential should be accepted by any verifier. It would be very undesirable if you got vaccinated at CVS and I got vaccinated at Walgreens and then when we went to get on a plane, only my credential was accepted and you were stuck in the airport.
A Vaccine Credential PKI #
There's a rough parallel here to the public key infrastructure which powers secure transactions at the Web, and we can take a generaly similar approach: The verifier's software trusts some set of entities (e.g., the CDC, state governments) which either directly issue credentials or authorize other entities (e.g., Walgreens) to issue credentials. The top-level entities are conventionally called trust anchors (TAs) As an operational matter, of course, the TAs will not by giving every shot, so what happens if I instead get my shot at Walgreens. There are two basic ways to handle this situation:
-
The TA issues the credential but operates some service which allows the clinic to request a credential for an individual patient (in WebPKI terms, this would be called a registration authority). This has the advantage of simplicity but the disadvantage that the TA needs to be involved in every transaction.[1]
-
Rather than issuing the credential directly, the TA delegates the right to issue credentials to the clinic and then the clinic just issues the credentials directly. In the WebPKI world, this is done by giving the clinic an "intermediate certificate".
Each of these models has advantages and it's likely we'll see a mix. For instance, the state might issue credentials issued at its own clinics but delegate signing to Walgreens. And Walgreens might issue all its credentials centrally but have each store act as a registration authority, contacting the Walgreens central server to issue. What we want is a flexible model that has the following properties:
- A common set of trust anchors that everyone agrees on.
- A method to delegate the right to issue credentials to other entities.
With these basic pieces, we don't need to be too prescriptive about the overall structure because different organizations can figure out the right structure for themselves.
Aside: Manufacturer Trust Anchors #
One sort of interesting variation I thought of while writing this was to have the vaccine manufacturers serve as the trust anchors. For instance, each box of vaccine could have a code printed on it and then the clinic could scan the code when they injected someone and then phone home to the manufacturer to get an issued credential. [Yes, this has bad privacy properties but you can fix those with blind signatures.] This won't work offline, which isn't ideal, though probably not that big a deal in a lot of places. Alternately, you could have each box of vaccine have a code with a private key + certificate pair and then you could scan the code and use that to sign, which would work offline.[2] The advantage of a system like this is that it wouldn't require the issuers to have any real contact with the PKI; they could just have simple stateless software which scanned the box. Obviously it's too late for this given that we've vaccinated a lot of people and it doesn't work well retroactively, but an interesting thought experiment nevertheless.
The VCI Approach #
VCI seems to have settled on some of the pieces of key management.
The way that their key management works is that
each issuer publishes the public keys that they use for signing at a
well-known URL (/.well-known/jwks.json
) and each token contains
the issuer's URL in the iss
field of the encoded JWS. When
the verifier processes a credential it retrieves the
keys from the issuer's site and uses them to verify the signature
on the JWS. I.e.:
This takes care of the delegation piece (sort of) but not of the trust anchor piece. Here's what they say about that:
- We'll work with a willing set of issuers and define expectations/requirements
- Verifiers will learn the list of participating issuers out of band; each issuer will be associated with a public URL
- Verifiers will discover public keys associated with an issuer via
/.well-known/jwks.json
URLs - For transparency, we'll publish a list of participating organizations in a public directory
- In a post-pilot deployment, a network of participants would define and agree to a formal Trust Framework
IOW, in the initial design the trust anchors will be a set of domain names which is then mapped to the keying material via HTTPS (and thus anchored in the WebPKI). In the post-pilot period, it seems like they are contemplating a separate PKI (it's a little unclear if the keys will still be on the Web in this case). This seems generally sensible, although there needs to be some way of ensuring that everyone has the same list of issuers. In the WebPKI this is accomplished[3] by having software vendors remotely update the list of trust anchors, so you'd need something like that here.
One difficulty with the "retrieve the keys from a well-known URL" approach is that in order to have reliable results it requires that the verifier be online in order to get the issuer's public key. Even if the issuer preloads the public key list by contacting every issuer, the issuer is free to add a new key, which will cause failures until the issuer re-contacts them. By contrast, in a system like the WebPKI, the delegations are all self-contained (in certificates) so you can verify the issuer's key without contacting them.[4] This means that if the verifier is offline it may not be able to verify some credentials, which is suboptimal. Depending exactly on how this is all implemented, this check might also be some kind of tracking vector, though the design in which the list of issuers is preconfigured seems to mostly mitigate that. Anyway, this is a generally reasonable kind of design though of course the details need to be worked out.
Interoperability Again #
I said at the beginning, it's very important to have a system which is interoperable. This means we need a single solid specification that is flexible enough to work for most if not all any applications. Obviously, details do matter, but there are a lot of ways of doing this, and it's more important to pick one. To that end, I'm glad to see organizations like VCI publishing open specifications which can serve as input to future standards
Note that in principle the TA could duplicate their signing key and give the clinic a copy so they could issue credentials directly, but this is brittle for a variety of reasons. ↩︎
Of course, now you have to worry about those keys leaking, which you don't with a more centralized system as you can just count the number of doses assigned to a given box. ↩︎
WebPKI relying parties may still contact the issuer to check whether the credential is revoked. This doesn't have awesome reliability, security, or privacy properties and browsers are gradually deprecating it. It seems unlikely there will be much revocation in this system and so a central revocation list is probably enough. ↩︎