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

Brian Campbell bcampbell at pingidentity.com
Tue Feb 5 21:01:16 UTC 2013

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 is.

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 JOSE).

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
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openid.net/pipermail/openid-specs-ab/attachments/20130205/774672a2/attachment-0001.html>

More information about the Openid-specs-ab mailing list