A new internet draft we submitted to the IETF
A few days ago, Richard Barnes (from Cisco) and I submitted a new internet draft to the Internet Engineering Task Force (IETF)’s OAuth working group. (This is the very first step on the long road to publishing an RFC in the IETF internet standards process.) In the draft we introduce PIKA: Proof of Issue Key Authority, to solve a problem relevant to OpenPubkey, OpenID Connect (OIDC) and JWTs (JSON Web Tokens) in general.
PIKAs allow us to cache and redistribute an OpenID Provider (OP)’s public keys. In this blog, I’ll introduce the OpenPubkey issue that led me to get interested and start working on PIKAs, explain what PIKAs are, and show how they allow OPs to provide long-lived bindings of public keys to identities. And why PIKAs apply to much more than just OpenPubkey.
Why should the OpenPubkey community care about PIKAs?
PK Tokens add public keys to ID Tokens issued by an OpenID Provider (OP). This way, user- and machine- identities can produce signatures which are cryptographically bound to their identity in the ID Token. We can use a PK Token to, for example, allow anyone to validate that alice@gmail.com signed a code commit in GitHub.
Here’s the question that the OpenPubkey community wanted to answer: can we validate a signature generated by the public key in a PK Token, several days or even months after the PK Token was issued?
As a concrete example, suppose we want a GitHub Action to sign a container that is then published in a repository. The GitHub Action:
- Generates an ephemeral public-private key pair,
- Signs the container using the private key,
- Binds its public key to the GitHub Action’s identity by creating a PK Token using GitHub’s OP,
- Publishes the container, the signature and the PK Token to the repository.
Now any party can validate the provenance of the container and that it was indeed signed by the correct GitHub Action (i.e., the GitHub Action that built and published the artifact). Ideally, we’d like to allow any party to be able to verify this signature months or even years after the container was signed.
So what’s the problem?
Well, PK Tokens are signed by the OP's signing keys. But OP's rotate their signing keys over time (e.g., biweekly). What happens if we need to validate a PK Token *after* the OP rotates its signing key?
This is where PIKAs come in.
What's a PIKA?
A PIKA is a signed object that allows you to cache and redistribute an OpenID Provider’s public key.
Today, if you want to verify any object issued by an OP, you need to request the OP public keys by making a request to an HTTPS endpoint. The OP has to be online and the HTTPS endpoint has to be available.
Notice that security of this approach comes from TLS. You are using TLS to be certain that you are hitting the OP’s actual endpoint and receiving the OP’s actual public key. Because this is TLS, the TLS handshake contains an X.509 certificate that chains to a root of the WebPKI (Web Public Key Infrastructure). It’s this certificate chain that ultimately ensures that you are receiving the legitimate OP’s public key.
PIKAs introduce a new reality where the process of obtaining the OP's public key can be done offline rather than being restricted to online only.
Instead of hitting a OP’s HTTPS endpoint to obtain the OP’s public key, a PIKA is a signed object where:
- The payload contains the OP’s public key, and
- The header contains an X.509 certificate chain proving that the key signing the PIKA chains up to the root of the WebPKI.
In other words, this X.509 certificate chain proves that the PIKA-signing key is authoritative for the OP’s domain name. Since the PIKA-signing key both signs the OP’s public key and can be chained to a root certificate authority (CA) in the Web PKI, the Web PKI can be used to prove that an OP public key really was issued by that OP.
We no longer need to use TLS to hit a live HTTPS endpoint to securely obtain the OP’s public key. Instead, we can use the PIKA and its contained chain of X.509 certificates, to securely validate the OP’s key.
The security posture remains the same. But now, we can use PIKAs to redistribute and cache OP public keys. So, you can imagine providing a third-party with a PK Token and PIKA, to allow them to verify the binding between a public key and an identity, without interacting with the OP at all.
If you think about it, this is a pretty normal way to do things; rarely do we interact directly with a Certificate Authority when verifying a certificate. With PIKA, we no longer need to interact with an OP in order to verify objects issued by an OP.
PIKAs therefore have the benefit of reducing the load on the OP, thus improving performance.
PIKA also introduces some privacy benefits; namely, third parties verifying objects signed by an OP do not need to interact with (and thus reveal their identity to) the OP at all.
PIKAs are not just for OpenPubkey
PIKAs are generic objects.
While I started working on them because of OpenPubkey, they can be easily used to verify the signature on any object issued by an OP. You can use them to verify generic OIDC ID Tokens. Richard Barnes, my coauthor on this draft, wants to use them to verify signatures on SD-JWTs (Selective Disclosure for JWTs). You can use them to replace the “request a public key from a TLS endpoint” step that is inherent in validating many types of JWTs.
Using PIKAs to validate a PK Token after an OP rotates its key
So far, I’ve focused on the ability to cache and redistribute the PIKA. But how can we use PIKA to support validating PK Tokens even after an OP has rotated its signing key?
Let’s go back to our container-signing use case and see how PIKAs can solve the problem. Suppose the container registry stores the following information for each container:
- A signature by the GitHub Action over the container
- A PK Token attesting to the GitHub Action’s identity and public key
- A PIKA providing the public key of the GitHub OP that issued the PK Token
- An assertion by the timestamping authority that all of the above artifacts existed at a time in the past when all of them were valid
Based on the timestamping authority's assertion, a relying party can validate that at the specified time, the container was signed by the GitHub Action with the specified identity, and that the public key was bound to that GitHub action by the GitHub OP.
The combination of the timestamping authority and the distributable-nature of the PIKA allows us to solve the problem of verifying a signature associated with an identity in a PK Token, after the OP’s public key has been rotated.
And that's why I got interested in this work.
Path to the PIKA
You probably noticed that PIKAs require support from OPs. Someone has to chain the OP’s key to root the WebPKI, and the only party that can do that is the OP itself.
PIKAs are not something that we at BastionZero can build ourselves. We are not running our own OP; rather we integrate against existing OPs like Google, AzureAD, Okta and OneLogin.
That’s why we took this draft to the IETF; in hopes that OPs find this interesting and consider including it in their offerings. Especially because the PIKA is generic and widely applicable to many signed objects, not just OpenPubkey.
What else are PIKAs good for?
PIKAs allow the verification of JWTs and other OIDC Tokens without querying the OP directly. You can use them to reduce the load on an OP or to build applications that require caching or historical information about OP keys. As noted above, historical information about a signing key is a particularly important feature in software supply chain security.
Get involved!
We're still digesting all the different ways that PIKAs can be used. Here’s a link to the draft, feel free to get in touch if you have any feedback; you might even be able to help us with the IETF process :)
And of course, we invite anyone who wants to contribute to OpenPubkey to visit and star our GitHub repo. We are building an open and friendly community and welcome pull requests and other protocol contributions or feedback from anyone — see the contribution guidelines or this list of Good First Issues to learn more.