Hi Hannes,


My replies to your comments follow in-line.  Thanks again for writing these up.



                                                            -- Mike



-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of 
Tschofenig, Hannes (NSN - FI/Espoo)
Sent: Thursday, September 12, 2013 1:07 AM
To: oauth mailing list
Subject: [OAUTH-WG] My review of draft-ietf-oauth-json-web-token-11



Hi Mike, Hi all,



As part of preparing the shepherd write-up I have read the draft and here are a 
few comments.



In general, the draft looks good. The comments are fairly minor.



1. Section 4: JWT Claims



In the first paragraph you write:

"

The Claim Names within a JWT Claims Set MUST be unique; recipients MUST either 
reject JWTs with duplicate Claim Names or use a JSON parser that returns only 
the lexically last duplicate member name "



I think what you want to write here is that the sender of a JWT must ensure 
that the claims are unique. If a JWT is, however, received with non-unique 
claims then some decision must be taken. You list two choices and I am 
wondering why not just have one. Let's just reject the JWT if that happens to 
ensure consistent behavior.



This was extensively discussed within JOSE and the language used is the same.  
Ideally, yes, we'd reject duplicate names, but both the old and new JSON specs 
allow duplication, so if we're to use existing deployed parsers, that isn't 
really a practical option.  (We used to require rejection of duplicate names, 
but objections were raised to that.)



I believe it might be good to clarify that unique here means that claims may 
appear more than once in a JWT but you are concerned about having two claims 
that actually have a different semantic. Correct?



No, the issue is that either parsers will only return one (they will overwrite 
each other) or duplicates will cause a parsing error.  Therefore, for things to 
always work regardless of parser, producers can't include any duplicates.



You write: "However, in the absence of such requirements, all claims that are 
not understood by implementations SHOULD be ignored."



The 'SHOULD' is not good enough here. Either you ignore claims that you don't 
understand or you do something else. Since there does not seem to be a way to 
declare claims as "critical" to understand I suggest to turn this into a MUST.



Agreed.  I made this change in -18.



With every claim you add "Use of this claim is OPTIONAL.". I would suggest to 
move that sentence to the front and avoid repeating it with every claim. In 
fact you have that necessary sentence currently in Section 4.1 "None of the 
claims defined below are intended to be mandatory to use, but rather, provide a 
starting point for a set of useful, interoperable claims."



For what it's worth, Jim Schaad had requested the opposite - that the 
"OPTIONAL" statements be on a per-name basis - so each definition could be 
easily read in isolation.



Since you describe the "use" there is obviously the question about the 
"implementation". So, what claims in this document are mandatory to implement? 
All? None?



None.  It's up to the application what claims are MTI for its use case.  I 
added text clarifying this.



Claim Types: You distinguish between three types of claims, namely Reserved 
Claim Names, Public Claim Names, and Private Claim Names.



- Reserved claims are those that are registered with IANA.

 - Public Claims are (interestingly enough) also registered via IANA or use a 
Collision Resistant Namespace.

 - Private Claims are those that may produce collisions



Clear I would suggest to change the definition of a public claim. Let's just 
call the claims that are registered via IANA reserved claims.



"Reserved" was changed to "registered", both here and in JOSE, as a result of 
review comments from both working groups.



I also wonder why we need private claims at all when it is so easy to construct 
public claims?



In practice, people will use unregistered names in some contexts.  (There was a 
1/2 hour presentation in AppsAWG today about this very thing!)  Given we really 
can't prevent this and it will happen, it's better to clearly describe the 
downsides and alternatives than to pretend that private names won't be used.  
At least this way, people will have been warned about the consequences of their 
choices.



Section 4.1.1: "iss" (Issuer) Claim



You write:

"

The iss (issuer) claim identifies the principal that issued the JWT. The 
processing of this claim is generally application specific.

"



Would it be useful to say what people use this claim for. It might also be 
useful to indicate that this value cannot be relied on for any trust or access 
control decisions without proper cryptographic assurance. I can already see 
people who base their security decisions on this value without any relationship 
to the actual crypto of the JWT. So, one might wonder what the relationship of 
the crypto and the iss claim is.



I added language about making trust decisions in the Security Considerations 
section.  Did you have particular language in mind about what the claim is used 
for, beyond stating that it identifies the issuer?



Section 4.1.3: "aud" (Audience) Claim



You write:

"

The aud (audience) claim identifies the audiences that the JWT is intended for.

"



That's not a good description. You could instead write: "The aud (audience) 
claim identifies the recipient the JWT is intended for."



Agreed - done.



You write:

"

In the special case when the JWT has one audience, the aud value MAY be a 
single case sensitive string containing a StringOrURI value.

"



Shouldn't this read:

"

In the special case when the JWT has one audience, the aud value is a single 
case sensitive string containing a StringOrURI value.

"



No - because either "aud":"foo" or "aud":["foo"] are legal and mean the same 
thing.



Section 4.1.8. "typ" (Type) Claim



You write:

"

The typ (type) claim MAY be used to declare a type for the contents of this JWT 
Claims Set in an application-specific manner in contexts where this is useful 
to the application. The typ value is a case sensitive string. Use of this claim 
is OPTIONAL.



The values used for the typ claim come from the same value space as the typ 
header parameter, with the same rules applying.

"



I believe the first sentence should say: "The typ (type) claim is used to 
declare a type for the contents of this JWT Claims Set ....". I don't 
understand what the "MAY" here was supposed to indicate since if it does not 
declare the type of the claims then what else does it do?



Why is the typ claim actually there when there is already the same claim in the 
header?



The "typ" claim was removed as part of the JOSE change to use MIME type names 
for "typ" and "cty" header parameter values.


Section 5.1. "typ" (Type) Header Parameter



You write:

"

The typ (type) header parameter MAY be used to declare the type of this JWT in 
an application-specific manner in contexts where this is useful to the 
application. This parameter has no effect upon the JWT processing. If present, 
it is RECOMMENDED that its value be either JWT or 
urn:ietf:params:oauth:token-type:jwt to indicate that this object is a JWT.

"



Here again I would write: " The typ (type) header parameter is used to declare 
the type of this JWT in an application-specific manner in contexts where this 
is useful to the application."



Why doesn't this value have any impact on the processing? It appears to be 
useless? Would it be good to mandate that it is set to JWT or 
urn:ietf:params:oauth:token-type:jwt when the content is a JWT? Why do you 
leave two options for what the value is set to? Why would anyone use the longer 
string?



The URN value was removed as part of the JOSE change to use MIME type names for 
"typ" and "cty" header parameter values.



Section 5.2. "cty" (Content Type) Header Parameter



What is the relationship between cty and typ?



As described in the JOSE specs that define them, "typ" is the type of the 
entire object, whereas "cty" is the type of the message contained in the JWS or 
JWE.  Both are now MIME type values.  "cty" is used by JWTs in the specific way 
specified whereas "typ" can be used as needed by applications using JWTs.



Section 5.3. Replicating Claims as Header Parameters



I am not sure why you would want to have encryption of the claims and then 
again include them in cleartext. That would defeat the purpose of encryption. 
Then, you could as well just provide them in cleartext (only signed, for 
example).



Putting the sub value into the header does not seem to be a good idea since 
this may be personal data.



This showed up in a use case that Dick Hardt had, in which case he wanted to 
route the contents of the JWT to the recipient without being able to read the 
contents of the JWT itself.  In his case, there was an intermediary handling 
the JWT that did not have the decryption key.



It's application-specific whether the audience is private information or not.



Putting these fields into the header in general does not strike me as a good 
idea since you loose the ability to sign these values. They will be exposed to 
all security threats since they cannot be protected. Why not use a nested JWT 
instead?



They are still integrity-protected, because JWE uses only authenticated 
encryption.  They are protected from tampering or alteration.



The 'SHOULD' in this sentence particularly makes me nervous: "If such 
replicated Claims are present, the application receiving them SHOULD verify 
that their values are identical." This essentially means that if you have 
protected claims and someone adds unprotected stuff into the header it may mean 
that an application would accept that. Not a good idea!



Per the above, you can't add stuff, because of the authenticated encryption 
used.



Section 6 Plaintext JWTs



Why do we want plaintext JWTs? I thought that the threat analysis concluded 
that sending this stuff of information around without any security protection 
is a bad idea.



The JWT can either be cryptographically protected by a signature and/or 
encryption in the JWT itself or by signature and/or encryption of a data 
structure in which the JWT is conveyed.  For instance, if it is returned from 
an OAuth Token Endpoint, it is integrity protected by the channel's use of TLS 
and so may not need to be signed and/or encrypted in some application contexts. 
 OpenID Connect uses this capability in several places, for instance, as does 
Phil Hunt's OAuth Authentication draft.



Section 7. Rules for Creating and Validating a JWT



I am curious why this section is so extensive given that we are essentially 
just applying JWS and JWE here. Wouldn't a pointer to the JWS/JWE spec be 
sufficient?



It's longer because the JWT adds two things:  First, the contents can be either 
a JWS or JWE, and so there's logic described for the slightly different actions 
taken in the two cases.  Second, the JWT can be nested, so the logic for 
nesting and detecting nested JWTs is defined.  It *does* just rely on JWS and 
JWE for the creation and verification aspects of the JWS and JWE aspects of 
JWTs.



That said, I did remove a step that was actually a pure duplication of a 
corresponding JWS/JWE step.



Ciao

Hannes













_______________________________________________

OAuth mailing list

[email protected]

https://www.ietf.org/mailman/listinfo/oauth
_______________________________________________
OAuth mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to