[Openid-specs-ab] Proposal(s) on key publication and rotation

Vladimir Dzhuvinov / NimbusDS vladimir at nimbusds.com
Fri Feb 8 09:17:14 UTC 2013

The idea to have all sig+enc keys into a single JWK set is a good one.
Not only we'll reduce the number of reg parameters in case encryption is
used, but this will also reduce the number of HTTP requests between OP
and clients to get JWKs. I began to realise that we're already having a
significant amount of HTTP back and forth in a full OIDC suite
implementation and identifying ways to minimise the message exchange and
make it more efficient will make overall operation snappier.

When I worked on the Java JOSE+JWT library I realised there's potential
to use HTTP header hints to cache keys. If we choose to go this way
we'll have to be explicit on that of course. However, I don't assume
everyone would actually implement that properly. Some people may for
instance publish the JWK set as a static file and simply forget or omit
to specify the cache headers, which means the HTTP server will apply its
default policy. 


Vladimir Dzhuvinov : www.NimbusDS.com : vladimir at nimbusds.com

-------- Original Message --------
Subject: [Openid-specs-ab] Proposal(s) on key publication and rotation
From: Brian Campbell <bcampbell at pingidentity.com>
Date: Tue, February 05, 2013 9:01 pm
To: "<openid-specs-ab at lists.openid.net>"
<openid-specs-ab at lists.openid.net>
Cc: Matthew Miller <mamille2 at cisco.com>

What follows are a few different proposed approaches for addressing the
open key publication and rotation issues [0]. There are a variety of
different ideas here but they are all really just variation on a theme.
Clearly I think that some change has to be made and I hope this can
begin the process of driving to some consensus about what that something

Initially something needs to be done to address the asymmetry of
features between the jwk and x509 urls (basically allowing for multiple
keys in an x509_url) while also supporting certificate chains.

 One approach is to have the x509_url return JSON that is a collection
of x5c [1] type objects. That would allow the same keys and same number
of keys to be represented via the x509_urls as with jwk_urls. It also
allows for certificate chains to be used by entities that so desire.
That might look something like this:
  ["MIIE3j...+4=","MIIE+z...09VZw==", "MIIC5zC...9ViH0Pd"],

 A key rotation recommendation for signatures is then fairly
straightforward and goes something like the following. The signer
publishes its keys at the jwk_url or x509_url or both and includes a kid
or x5t or both in every message to indicate to the verifier which key is
to be used to check the signature. Keys can be rolled by periodically
adding new keys to the jwk_url/x509_url (and purging really old ones).
The signer begins using a new key and signals that to the verifier by
the kid and/or x5t header. If the verifier knows to go back to the
jwk_url or x509_url and re-get the keys when it sees an unfamiliar kid
or x5t (possibly with some protections against abuse).
A variation on the above would be to augment each x5c type object with a
"kid" parameter, which would allow a key to be identified the same way
across jwk_url and x509_urls. It could also make individual JWS/E
headers smaller by only needing to include one header to identify the
key, regardless of the format keys are in. Which is nice. That might
look something like this:
   "x5c":["MIIE3j...+4=","MIIE+z...09VZw==", "MIIC5zC...9ViH0Pd"]},

Taking it a bit further, the "use" [3] parameter could be added and,
with proper spec treatment across jwk and x509 urls, we could eliminate
jwk_encryption_url and x509_encryption_url and consolidate to just
having jwk_url and x509_url.
And with everything being in JSON, it's a small step to just having a
single URL with all the keys. That might look something like this:

   "x5c":["MIIE3j...+4=","MIIE+z...09VZw==", "MIIC5zC...9ViH0Pd"]},
    "n": "0xxcagodb….4Kpw",
    "n": "0vx7agoeb....DKgw",

That really seems to beg the question of some kind of X.509 support in
JWK itself.  Which is admittedly a bit odd at first but has come up on
the JOSE list [4] and might help address a number of issues. I spoke
with Matt Miller (cc'd and was part of the aforementioned JOSE thread)
yesterday about it and we are both generally in favor of exploring the
possibility. It seems there are two general approaches that could take:
1) Define an X509 "kty" (Key Type) that would define x5c (and/or maybe
x5u) as a JWK parameter. That might look something like:

  "x5c": ["...","..."]


2) Define x5c as parameter in JWK that could be an alternative
representation of the key. Something like:

   "x5c": ["...","..."]

There are tradeoffs either way but the first approach might make for a
cleaner extension to JWK as it is now (even that may or may not be good
but could allow work to proceed here with less direct dependency on
One last issue is key rotation for encryption, which unfortunately is a
bit more tricky that signing. The encrypting party starts the process
and thus cannot rely on a change in kid to signal to it that keys need
to change. The encrypting party still uses kid to tell the decrypting
party which private key to use to decrypt. But the encrypting party
needs a different way of knowing that a new key is available and is to
be used.  One way to do this is to get the jkw/x509/combined url fresh
on every transaction. But that's needlessly inefficient and could be
improved by the use of some kind of cache lifetime indicator on the url
or individual keys, which allow the encrypting party to cache encryption
keys while still checking for new ones on a schedule determined by the
decrypting party. It seems like it might be wise to use existing cache
control constructs provided by HTTP? But I'm honestly not familiar
enough with the various possible headers to know which one(s) is(are)
most appropriate. It might also be a tad awkward to write up given the
Messages/Standard split and goal of decoupling Messages from HTTP. 
Alternatively key life or cache duration could be indicated on the
individual keys themselves. The concept of a exp parameter that defines
an expiration parameter for keys has been mentioned before [5] - maybe
this could/should be formalized?

If you made this far, I appropriate it. I think this is important.



[0] Open Issues (at the time of writing) in Connect:

[1] It would be the general concept x5c though not necessarily the same
processing rules
(JWS definition of x5c)
[2] One definition of kid from JWK

[3] use from JWK

[4] JOSE mail archives on a thread that turned into x509 and jwk

[5] Doc history on JWK -06 that talks about exp 


Openid-specs-ab mailing list
Openid-specs-ab at lists.openid.net

More information about the Openid-specs-ab mailing list