Subject: Re: [jose] #16: URI identifying a specific key in a JWK set

From: "Manger, James H" <[email-masked]>
Date: Mon, 1 Apr 2013 22:31:25 +1100

> #16: URI identifying a specific key in a JWK set
> 
> 
> Comment (by [email-masked]):
> 
>  First, having just a "jku" value is often sufficient to determine which
>  key to use, as other parameters in the JWK Set such as the "use" or "alg"
>  parameters may be used to unambiguously determine which key to use. There
>  may also be only one key in the set.

Requiring recipients to try a bunch of extra parameters and heuristics in the hope of witling down a set of keys to the single public key needed to process a JOSE message is a poor "solution" for "jku" not being fit-for-purpose.

The originator knows which specific key is required (ie the pair for the private key the originator used) so why bother only telling the recipient which set contains the key, instead of which specific key to use?

Lets just make "jku" fit-for-purpose (of identifying the public key required to process a JOSE message). 

>  Second, we already support more than one means of disambiguating keys
>  within JWK Sets, including using the "kty", "kid", "use", and "alg" values
>  as inputs to this decision.

"kty" -- unless there are 2 RSA keys in the set
"use" -- unless there are 2 keys that can be used to sign
"alg" -- unless there are 2 keys that work with "RS256"
[Rollover a key and "kty", "use", and "alg" are all likely to be the same for old and new keys]
"kid" -- works, but 1 fit-for-purpose "jku" field would be much better than 2 jku+kid

>  And once the spec says that other fields must
>  be ignored if not understood, I'm sure that people will use other key
>  properties they'll invent such as ("current": true) to aid in the key
>  selection process for their applications.

That's great if it helps an originator discover a key. The recipient shouldn't have to use such heuristics.

>  I understand that the request may seem simple on the face of it, but doing
>  this in a general way would involve more than just using a "kid" value as
>  a fragment identifier for a "jku" value.  As such, the proposal seems
>  underspecified to me.

The item in the issue tracker deliberately focuses on the issue, without being prescriptive about the solution.

>  Furthermore, if all that's being conveyed is a "jku" value and a "kid"
>  value pair - we already have a straightforward way of doing that - include
>  both parameters in the header.  Whereas requiring implementations to
>  support two ways of accepting the same information doesn't seem like a
>  good cost/benefit tradeoff.

Trying "jku" + ("kty" or "use" or "alg" or "kid") feels even worse than "two ways".

Drop "kid" in this context (identifying the public key a recipient needs to use to process a JOSE message) and only use "jku" -- that gives one way. This also solves Dick Hardt's point that a "kid" can be ambiguous without an issuer (the URI is effectively the issuer).

--
James Manger

---

From: "jose issue tracker" <[email-masked]>
Date: Thu, 04 Apr 2013 16:42:06 -0000

Comment (by [email-masked]):

 In order to evaluate this, we need to get a more detailed proposal than
 what we currently have.  Examples of issues that have not been dealt with
 at this point are
 1.  Syntax of the fragment
 2.  dealing with duplicate values within a JWK structure
 3.  Definition of a new media type - is this required or not - justify
 either postion
 4.  Explain why the proposal is "better" than the current ability to have
 a url plus the kid in the message.
 5.  Discuss what happens if the fragment is not present on the url or if
 the fragment is not findable in the resultant document.  If the fragment
 is going to be manditory does them mean that we should be doing a new
 scheme instead as fragments cannot be required under the current URL
 syntax defintions (or at least that is my reading).

 Please flesh out your proposal more so that it can be fully evaluated.

-- 
-------------------------+-------------------------------------------------
 Reporter:               |       Owner:  draft-ietf-jose-json-web-
  [email-masked]    |  [email-masked]
     Type:  defect       |      Status:  new
 Priority:  major        |   Milestone:
Component:  json-web-    |     Version:
  key                    |  Resolution:
 Severity:  -            |
 Keywords:               |
-------------------------+-------------------------------------------------

Ticket URL: <http://trac.tools.ietf.org/wg/jose/trac/ticket/16#comment:2>
jose <http://tools.ietf.org/jose/>

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 15 Apr 2013 10:35:04 +1000

>> http://trac.tools.ietf.org/wg/jose/trac/ticket/16

>  In order to evaluate this, we need to get a more detailed proposal

Below is a more detailed proposal. The basic idea is to make the JWK key set syntax a bit more sensible (keys named by their ids; instead of a "keys" element holding an array of keys); give key sets a media type; and define the fragment to be a JSON pointer [RFC 6901]. Then a URI can identify a specific key. A "jku" value can precisely indicate the key needed to process a JOSE message, eg "jku":"https://example.com/alice.keys#/k1".

>  1.  Syntax of the fragment

The fragment, if present, identifies a specific key in the JWK key set.

The fragment SHALL be a JSON Pointer [RFC 6901], pointing to the JSON object holding the specific key of interest within the set of keys.

The fragment SHALL be a "/" character followed by the key identifier ("kid" value) for the specific key.

[This implies the top-level structure of a JWK key set is changed to be a JSON object whose elements are individual keys. An element's name is the identifier of the key ("kid" value); an element's value is a single JWK object. One element (named "meta") is special: it is not a "kid" value, but a place to hold any metadata about the whole set of keys.

Example:
  {
    "k1" : {"kty":"EC","crv":"P-256","x":…,"y":…},
     2011-04-29" : {"kty":RSA","n":…,"e":"AQAB"}
  }
]

>  2.  dealing with duplicate values within a JWK structure

I'm not sure what this issue is. I suspect it is solved by storing keys as object elements as opposed to array items.

>  3.  Definition of a new media type - is this required or not - justify

The JWK spec should define a media type, such as application/keys+json.
Fragments are specific to a media type so a media type needs to be defined.

>  4.  Explain why the proposal is "better" than the current ability to
> have a url plus the kid in the message.

The whole concept of a URI is to be an identifier itself (not just when combined with a second field). Many, many systems and protocols that support URIs assume that the URI alone is sufficient to identify the item of interest.
It simplifies APIs and protocols: just pass 1 value.

>  5.  Discuss what happens if the fragment is not present on the url

The specs should be written so that if there is no fragment but there is only 1 key in the identified JWK key set, then things still work.

I suggest saying a *creator* of a "jku" URI value (to identify the specific key required to process a JOSE message) MUST include a fragment to identify a single key. When a key set has only 1 key, a *receiver* MUST accept a "jku" URI as an identifier of that 1 key even if the URI has no fragment.

> or if the fragment is not findable in the resultant document.

Then the URI identifies a key that is not present so an error results (similar to getting a 404 Not Found for the whole key set).

>  If the fragment

Definitely no new URI scheme.
A URI without a fragment is still a valid URI. That doesn't stop us saying a "jku" URI value MUST contain a fragment.

>  Please flesh out your proposal more so that it can be fully evaluated.

I hope this email has fleshed out a proposal sufficiently.

--
James Manger

---

From: Justin Richer <[email-masked]>
Date: Mon, 15 Apr 2013 10:00:14 -0400

I like this structural proposal with one caveat: moving the key ID out 
of the key structure means that a JWK can no longer be a self-contained 
unit with all of the metadata that it contains today. Is that what we 
want? Do we want to declare that a key id only makes sense in the 
context of a JWK Set and not an individual JWK? A simple workaround 
would be to have both the object-based structure as well as the value 
within the JWK itself and that they MUST match.

  -- Justin

On 04/14/2013 08:35 PM, Manger, James H wrote:
> _______________________________________________
> jose mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/jose

---

From: Mike Jones <[email-masked]>
Date: Mon, 15 Apr 2013 16:24:45 +0000

Requiring implementation of JSON-Pointer http://tools.ietf.org/html/rfc6901 just to use a JWK Set seems WAY over the top to me.  Please have some consideration for the developers who want to actually build and use the JOSE specs!  Actual implementation and deployment is a goal here.

I object to moving the Key ID field out of the JWK for the reasons identified by Justin.  Specifically, we want the Key ID to be usable for JWKs - not just JWK Sets.

I also object to the asymmetry of this proposal.  Having one key attribute (the Key ID) not be part of the JWK, where others such as "use" and "alg" are just makes things more complicated.  All attributes should be part of the JWK structure - not just some of them.

That's how I see it, anyway...

				-- Mike

-----Original Message-----
From: [email-masked] [mailto:[email-masked]] On Behalf Of Justin Richer
Sent: Monday, April 15, 2013 7:00 AM
To: Manger, James H
Cc: [email-masked]
Subject: Re: [jose] #16: URI identifying a specific key in a JWK set

I like this structural proposal with one caveat: moving the key ID out of the key structure means that a JWK can no longer be a self-contained unit with all of the metadata that it contains today. Is that what we want? Do we want to declare that a key id only makes sense in the context of a JWK Set and not an individual JWK? A simple workaround would be to have both the object-based structure as well as the value within the JWK itself and that they MUST match.

  -- Justin

Example:
   {

>>   4.  Explain why the proposal is "better" than the current ability 
>> to have a url plus the kid in the message.

---

From: "Manger, James H" <[email-masked]>
Date: Tue, 16 Apr 2013 14:07:17 +1000

> Requiring implementation of JSON-Pointer
> http://tools.ietf.org/html/rfc6901 just to use a JWK Set seems WAY over
> the top to me.  Please have some consideration for the developers who
> want to actually build and use the JOSE specs!  Actual implementation
> and deployment is a goal here.

Mike, this objection is “WAY over the top”.
I proposed that the fragment field of a jku URI should be: a "/" character followed by the key-id ("kid" value).
How simple do you need it?

The fact that this syntax matches RFC 6901 "JSON Pointer" (8 pages, including boilerplate, references, examples) is not going to scare any developer, nor hold them up for more than an hour. It will probably be built-in to many JSON libraries shortly.
One line of code would suffice to get the key-id from a "jku" URI (example in Java):
  String kid = uri.getFragment().substring(1).replaceAll("~1","/").replaceAll("~0","~");
[real code should add an extra line to do a bit more input validation]

How does the current system show consideration for developers? They have to make up their own heuristics based on "kid", or "alg", or "use", or "kty", or "exp", or trial-and-error to find the right key from a set?

> I object to moving the Key ID field out of the JWK for the reasons
> identified by Justin.  Specifically, we want the Key ID to be usable
> for JWKs - not just JWK Sets.

I have no problem with defining "kid" as a field that can convey the key-id inside a single JWK. It would be unnecessary to include this field when the JWK was named by the key-id as part of a JWK set, but not harmful.

> I also object to the asymmetry of this proposal.  Having one key
> attribute (the Key ID) not be part of the JWK, where others such as
> "use" and "alg" are just makes things more complicated.  All attributes
> should be part of the JWK structure - not just some of them.

Key-id is singled out as it is the identifier for the key. A filename isn't in a file’s content; a document’s web address isn’t in its body.

--
James Manger

> Below is a more detailed proposal. The basic idea is to make the JWK
> key set syntax a bit more sensible (keys named by their ids; instead of
> a "keys" element holding an array of keys); give key sets a media type;
> and define the fragment to be a JSON pointer [RFC 6901]. Then a URI can
> identify a specific key. A "jku" value can precisely indicate the key
> needed to process a JOSE message, eg
> "jku":"https://example.com/alice.keys#/k1".
> 
> 
> The fragment SHALL be a JSON Pointer [RFC 6901], pointing to the JSON
> object holding the specific key of interest within the set of keys.
> 
> [This implies the top-level structure of a JWK key set is changed to be
> a JSON object whose elements are individual keys. An element's name is
> the identifier of the key ("kid" value); an element's value is a single
> JWK object. One element (named "meta") is special: it is not a "kid"
> value, but a place to hold any metadata about the whole set of keys.
> 
> Example:
>    {
> I'm not sure what this issue is. I suspect it is solved by storing keys
> as object elements as opposed to array items.
> 
> The whole concept of a URI is to be an identifier itself (not just when
> combined with a second field). Many, many systems and protocols that
> support URIs assume that the URI alone is sufficient to identify the
> item of interest.
> The specs should be written so that if there is no fragment but there
> is only 1 key in the identified JWK key set, then things still work.
> 
> I suggest saying a *creator* of a "jku" URI value (to identify the
> specific key required to process a JOSE message) MUST include a
> fragment to identify a single key. When a key set has only 1 key, a
> *receiver* MUST accept a "jku" URI as an identifier of that 1 key even
> if the URI has no fragment.
> 
> Then the URI identifies a key that is not present so an error results
> (similar to getting a 404 Not Found for the whole key set).
> 
> >>   If the fragment
> A URI without a fragment is still a valid URI. That doesn't stop us
> saying a "jku" URI value MUST contain a fragment.
>