Open Pubkey Frequently Asked Questions

How does OpenPubkey work?

OpenPubkey is more than just SSH. It’s the web's new technology for adding public keys to standard SSO interactions with IdPs that speak OpenID Connect (OIDC). OpenPubkey works by essentially turning an IdP into a Certificate Authority (CA). A CA is a trusted entity that issues certificates that cryptographically bind an identity with a cryptographic public key. With OpenPubkey, any IdP that supports OIDC can bind public keys to identities.

OpenPubkey introduces a new cryptographic object — the PK Token — that binds an identity (i.e., a user or a workload) to its public key. It works with today’s major IdPs because it doesn't require any changes to OIDC.

OpenPubkey can be used to build all sorts of lovely cryptographic systems. For instance, Docker will use the public keys in PK Tokens to sign Docker Official Images that will be hosted in the Docker Hub container registry. BastionZero uses the public keys in PK Tokens to enable remote access to infrastructure. You could also use OpenPubkey to have developers sign their commits to private code repositories, to establish end-to-end encrypted channels using the public keys in a PK token, to sign contracts, transactions or receipts and a myriad of other applications.

OpenPubkey:  An Explainer

Who’s behind OpenPubkey?

OpenPubkey is a Linux Foundation project, open sourced under the Apache 2.0 license. OpenPubkey was initially created by the PhD cryptographers and engineers at BastionZero as part of the Multi-Root Zero Trust Access Protocol (MrZAP). BastionZero uses OpenPubkey with MrZAP to provide zero trust passwordless access to servers, containers, clusters and databases. BastionZero recently extracted and generalized OpenPubkey to become its own standalone protocol, and then open sourced it under Apache 2.0. The Linux Foundation approved OpenPubkey as a project lead by BastionZero, Docker and others.

How does OpenPubkey work?

Let’s first see how OpenPubkey allows user Alice to use the acme.com IdP to bind her identity alice@acme.com to Alice’s public key. 

Let’s first look at the standard OpenID Connect protocol (OIDC). OpenID Connect has a field called “nonce,” which encodes a random value generated by Alice’s client. With OpenID Connect, once the client completes its authentication to the IdP (which includes generating and sending the nonce, along with the standard SSO flow of Alice’s username, password, etc.), the IdP provides the client with an ID Token that contains the IdP’s signature on the nonce field and on various other fields including the user’s email: alice@acme.com.

So, in OpenPubkey, Alice runs an OpenPubkey client that first generates a new public-private key pair. Then, when Alice’s client authenticates to the IdP, the client sets the nonce field equal to the cryptographic hash of Alice’s public key along with some random noise. This works because, from the perspective of the IdP, the output of the cryptographic hash looks just like a random value. 

Now the ID Token provided by the IdP now contains the IdP’s signature on alice@acme.com and on the hash of Alice’s public key.  This is most of what we need in order to have the IdP certify the user’s public key. The PK Token is a JSON Web Signature (JWS) which roughly consists of:
☑️ the ID Token, including the nonce field, which contains a hash of user’s public key.
☑️ The user’s public key.
☑️ The random noise used to compute the hash of the user’s public key.
☑️ A signature, under the user’s public key, of all the information in the PK Token. (This signature acts as a cryptographic proof that the user has access to the user-held secret signing key that is certified in the PK token.)

The PK token is then presented to an OpenPubkey verifier, which uses OpenID Connect to obtain the IdP’s public key. The verifier validates the ID Token using the IdP’s public key, and the rest of the other fields in the PK token using the user’s public key.That’s the high level view.  But there are still several details to work through. So keep reading!

Does OpenPubkey support workload identities?

Yes, just like OpenID Connect, OpenPubkey supports both user identity and workload identity.

This means that any OpenID Provider that supports authenticating workloads can also use OpenPubkey to bind a public key to the workload’s identity. For instance, a Github Action can sign the software artifact it created under the identity assigned to it by Github’s IdP. 

OpenPubkey for workloads works the same way as OpenPubkey for users.  The only minor difference is that certain IdPs (e.g. GitHub’s IdP) don’t support signing a nonce as part of the OIDC ID Token for workloads. For these IdPs,  we use the audience field in the ID Token the same way we used the nonce field described above. 

Note:  You might be wondering how an IdP knows how to use OpenID Connect to authenticate workloads. Here’s how it works with GitHub Actions workloads and GitHub’s IdP. When a new GitHub Action is spun up, GitHub assigns it a fresh API key and secret. Then, it uses the API key and secret to authenticate to GitHub’s IdP. GitHub can validate this API key and secret because it knows that it was assigned to the new GitHub action. The GitHub IdP then provides the GitHub Action with an ID Token.

How does BastionZero use OpenPubkey?

BastionZero has been using OpenPubkey as part of their MrZAP protocol providing zero trust passwordless access to infrastructure. The PK Tokens are in use for less than 24 hours, and only made available to the specific infrastructure target (server, container, cluster, etc.) to which a given user or workload requests access.

How will Docker use OpenPubkey?

Docker will be using OpenPubkey as part of their solution for signing Docker Official Images (DOI) that are made available on the Docker Hub container registry. The PK Tokens used in Docker’s usecase will be broadly available to the public. Every PK Token is only used for signing a single container image (read more about this when we discuss ephemeral keys). The Docker usecase also relies heavily on a The Updated Framework (TUF), another Linux Foundation open source project. Check out Docker’s blog post for more details.

Aren’t ID Tokens supposed to remain private?

You might worry about applications of OpenPubkey where the OpenID ID Token is broadly exposed  to the public inside the PK Token. For example, in Docker’s container signing usecase, the PK Tokens are exposed in the container registry. If the ID Token is broadly exposed to the public, there is a risk that the ID Token could be replayed and used for unauthorized access to other services. 

This is why we have a slightly different PK Token for applications where the PK Token is made broadly available to the public. For those applications, OpenPubkey strips the IdP’s signature from the ID Token before including it the PK token. The IdP’s signature is replaced with an Guillou-Quisquater (GQ) non-interactive proof-of-knowledge for an RSA signature (which, for short, is also known as a “GQ signature”). Now, the ID Token cannot be replayed against other services, because the IdP’s signature is removed. An ID Token without a signature is useless. 

So, in applications where the PK Token must be broadly exposed to the public, the PK Token is a JSON Web Signature (JWS) which consists of:
☑️ The ID Token excluding the IdP’s signature
☑️ A GQ signature on the ID Token
☑️ The user’s public key
☑️ The random noise used to compute the hash of the user’s public key
☑️ A signature, under the user’s public key, of all the information in the PK token 

The QC signature allows the client to prove that the ID Token was validly signed by the IdP, without revealing the IdP’s signature. The OpenPubkey client generates the QC signature to cryptographically prove that the client knows the IdP’s signature on the ID Token, while still keeping the IdP’s signature secret. GQ signatures only work with RSA, but this is fine because every OpenID Connect provider is required to support RSA.

Because GC signatures are larger and slower than regular signatures, we recommend using them only for usecases where the PK Token must be made broadly available to the  public. BastionZero’s infrastructure access usecase does not use GQ signatures because it does not require the PK Token to be made public. Instead, the user only exposes their PK Token to the target (e.g. server, container, cluster, database) that they want to access; this is the same way an ID Token is usually exposed with OpenID Connect. 

Finally, we note that most IdPs that use OpenID Connect allow you to scope the fields in the ID Tokens. For instance, Google’s IdP is by default scoped to only include userinfo-email claims: name, email address and icon. However, some IdPs may include additional claims in the ID Token that the application may wish to keep private. For this reason, when you build an application with OpenPubkey, we recommend that you carefully consider which OpenID Connect providers you will choose to integrate, and what they expose in the ID Token.

Which IdP should the OpenPubkey verifier trust?

When verifying a PK Token, the OpenPubkey verifier needs to know which IdP should be trusted to issue the PK Token. 

In some applications, the choice of IdP is completely obvious.  For instance, with BastionZero, the OpenPubkey verifier is on a server, container, cluster or database inside an organization’s cloud or data center environment. So, the OpenPubkey verifier should only trust PK Tokens issued by that organization’s IdP. 

For instance, if Acme Co uses Google as its IdP, the OpenPubkey verifier should check that the PK Token was issued by Google, that it was issued for Acme Co and that it was issued to be used by MyOpenPubkeyApp. Thus, the ID Token inside the PK token should have the following values:

issuer=Google,
org=acmeco
audience=MyOpenPubkeyApp

But there are other applications where an OpenPubkey verifier may need to verify against multiple different organizations or multiple different IdPs.

For instance, in Docker’s container signing application, the container registry will contain container images signed by multiple organizations. More concretely, the MariaDB image will be created from https://github.com/MariaDB/mariadb-docker and the consul image is created from https://hub.docker.com/r/hashicorp/consul. These are different organizations so we wouldn’t want to use a consul image signed by the MariaDB organization. In such a situation, an additional mechanism that is not part of OpenPubkey is required to allow the verifier to know which organization to trust when issuing PK tokens for a given user or workload. Docker’s container signing application uses a TUF to allow verifiers to know which organization to trust to issue PK tokens for a given user or workload. 

Other solutions for disambiguating different IdPs at an OpenPubkey verifier are possible, but these are currently outside the scope of OpenPubkey.

What happens when the IdP rotates its OpenID Connect key? And what if an ID Token expires?

IdPs have OpenID Connect signing keys that change over time (e.g. every two weeks). Also, ID Tokens in OpenID Connect have an expiry time. What happens if we need a PK Token to be used after the IdP rotates its OpenID Connect key, or after the ID token expires?

For some usecases, the lifetime of a PK Token is typically short. With BastionZero’s infrastructure access usecase, for instance, a PK Token will not be used for longer than 24 hours. In this usecase, these timing problems are solved by (1) having user re-authenticate to the IdP and create a new PK Token whenever the IdP rotates it’s key, and (2) having the OpenPubkey verifier check that the client also has a valid OIDC Refresh Token along with the PK Token whenever the ID Token expires.

For some usecases, the PK Token has a long life, so we do need to worry about IdP rotating their OpenID Connect keys. With Docker’s container signing usecase, this problem is solved by having the TUF additionally store a historical log of the IdP’s signing key. Anyone can keep an historical log of the IdP public keys for use after they expire. In the future, IdPs might do this themselves.

Can you use ephemeral keys with OpenPubkey?

Yes! An ephemeral key is a key that is only used once. Ephemeral keys are nice because there is no need to store the private key anywhere, which improves security and reduces operational overhead.

Here’s how to do this with OpenPubkey. You simply choose a public-private key pair, then authenticate to the IdP to obtain a PK Token for the public key, then sign your object using the private key, and finally throw away the private key. 

In fact, we can take this one step further and ensure the PK Token may only be associated with a single signed object. Here’s how it works. First, we take a hash of the object to be signed. Then, when the OpenPubkey client authenticates to the IdP, the client sets the nonce field to equal to the cryptographic hash of the following items:
☑️ The user’s public key 
☑️ The hash of the object to be signed
☑️ Some random noise

Finally, OpenPubkey verifier obtains the signed object and its one-time-use PK Token, and then validates the PK Token by additionally checking that the hash of the signed object is included in the nonce. Now you have a one-time-use PK Token!

OpenPubkey places a lot of trust in the IdP.  What if the IdP is compromised? 

It’s true.  If the IdP is compromised, you can no longer trust its OIDC ID Token, which means you cannot trust the derived PK Token. That said, IdP compromise is also a problem with OpenID Connect, which powers most of the SSO interactions on the web.

It’s also a problem with traditional Certificate Authorities (CA), which deal with this by adding Certificate Transparency (CT) Logs, a parallel system for logging and verifying certificate issuance by CAs. One can imagine a similar system added to OpenPubkey for applications where protection against a compromised IdP is an additional requirement. 

Finally, we also want to call your attention to an orthogonal solution to this problem that was developed by BastionZero, called the MFA Cosigner. The MFA cosigner is an additional entity, that is independent of the IdP, that signs the PK Token once it authenticates the user via independent multi-factor authentication (MFA). The OpenPubkey verifier must then verify the PK Token using the keys of both the IdP and the MFA Cosigner. By requiring the user to authenticate to both the IdP AND the MFA Cosigner, we eliminate the single point of compromise around IdP.

In fact, BastionZero uses a cloud-based MFA Cosigner that cosigns on PK Token as long as (1) the user completes an MFA that is independent of the user’s authentication to the IdP, AND (2) if the user is currently authorized to access the particular infrastructure target (server, container, cluster, database, etc) that it wishes to connect to. In this way, the MFA cosigner eliminates the single point of compromise around the IdP, while also acting as policy enforcement point to ensure that a user is authorized to access a specific target.

What is the difference between OpenPubkey and OpenID Connect?

Today’s IdPs use OpenID Connect to issue bearer tokens. A bearer token is NOT a cryptographic signing key, it’s just a secret that a user presents in order to gain access to a service. In OpenID Connect, the secret is the ID Token. Importantly, a bearer token cannot be used to cryptographically sign statements. This means you cannot use OpenID Connect as is to sign commits, deployments and build artifacts to establish authenticated channels. Also, bearer tokens are a secret that must be revealed to the service in order to be used, which creates other security issues including subtle replay attacks.

What is the difference between Sigstore and OpenPubkey?

Sigstore is an end-to-end artifact signing solution, whereas OpenPubkey is a generic solution for binding public keys to OpenID Connect identities for use as part of a larger signing solution. OpenPubkey can be used to complement Sigstore; see for example sigstore/fulcio#1056.

With Sigstore, users can sign under their OpenID Connect identity by using the Fulcio Certificate Authority (CA). Fulcio can bind an OpenID Connect identity (i.e. an ID Token) to a public key because the Fulcio CA is trusted. (See this proposal to reduce the trust in CAs like Fulcio.) Sigstore additionally uses a certificate transparency log for timestamping signatures and detecting abuse.

Sigstore could use OpenPubkey to eliminate the trust in the Fulcio CA, because OpenPubkey does not need a trusted party to map ID Tokens to public keys. In turn, the Fulcio CA could support OpenPubkey by acting as a public OpenPubkey verifier and if used as JWT Ledger (see this proposal) as a historical database of public keys used by OpenID Providers. 

What is the difference between FIDO2 and OpenPubkey?

FIDO2 provides cryptographic login credentials that are unique across every website, never leave the user’s device and are never stored on a server.   FIDO2 credentials are typically used for Multi-Factor Authentication (MFA) in protocols like Webauthn, or a part of a passwordless login scheme like passkeys. 

But, just like the keys in an OpenPubkey PK Token, FIDO2 cryptographic credentials can also be used to cryptographically sign statements.

So how is OpenPubkey different?  OpenPubkey binds public keys to user identities in a manner that is verifiable to any third party that knows user’s Identity Provider. So, a user’s PK Token can be shared across organizations, or between parties that are part of different organizations.  For example, you could use OpenPubkey to enable Alice at acme.co to sign a contract with Eric at a different organization example.com, as long as Eric (and everyone else who needs to verify the contract) knows about Alice’s Identity Provider.

Meanwhile, FIDO2 does not provide an in-band mechanism for associating Alice’s signing keys with her identity at acme.com.  Going back to our example, this means that while Alice can use her FIDO2 key to sign the contract, there is no in-band FIDO2 mechanism for verifying that the signature Alice produces is associated with Alice’s identity. 

Therefore, we view OpenPubkey as complementary to FIDO2, in that the OpenPubkey PK Tokens can be used to bind FIDO2 keys to identities.  That is, OpenPubkey allows you to create authenticated session secured both by OpenID Connect and FIDO2 with the identity attestation coming from the OpenPubkey PK Token, and the signature coming from the FIDO2 hardware device.

Also, FIDO can be used to provide Multi-Factor Authentication (MFA) to an OpenPubkey MFA Cosigner that can be used to eliminate the single point of compromise around using an IdP alone to issue PK Tokens binding keys to identities.

How do I get started with OpenPubkey?

We’re glad you asked! You can: