Are duplicate "kid"s in jwks permitted under OpenID Connect

Issue #1127 resolved
Joseph Heenan created an issue

The method for selecting in a key from a JWKS using kid under OpenID Connect is not really documented, and different RP libraries appear to take slightly different strategies.

The certification team recently discovered that in some cases the tests were effectively rejecting OPs where the JWKS contained multiple keys that contained the same kid.

https://tools.ietf.org/html/rfc7517#section-4.5 says:

When "kid" values are used within a JWK Set, different keys within the JWK Set SHOULD use distinct "kid" values.

and:

(One example in which different keys might use the same "kid" value is if they have different "kty" (key type) values but are considered to be equivalent alternatives by the application using them.)

For interoperability purpose it would seem sane to suggest that all keys should have a unique kid, allowing the RP to very easily identify the correct key to use for verification. (although RFC7517 suggests it is okay to have duplicate kids if the kty field is different between the keys.)

The certification would like to know how the Connect working group view this, in particular, should the certification suite:

  1. Raise a warning if it finds duplicate kids in the JWKS, but allow certification
  2. Raise an error if it finds duplicate in the JWKS, preventing such implementations from certifying

(For related background, the certification profiles already require that a kid is provided in the id_token if RS256 is in use, regardless of the number of keys in the JWKS.)

Comments (10)

  1. Michael Jones

    Thanks for filing this, Joseph. To increase interoperability, I believe we should consider it an certification error if a JWK Set has duplicate Key IDs. If we don’t enforce this, RPs using “kid” to match keys will break in unpredictable and surprising ways.

  2. Joseph Heenan reporter

    @Vladimir Dzhuvinov The JWK spec seems to explicitly allow multiple keys to have the same kid though:

    (One example in which different keys might use the same "kid" value is if they have different "kty" (key type) values but are considered to be equivalent alternatives by the application using them.)

    Although to be honest I’m not 100% sure how to interpret “considered to be equivalent alternatives by the application using them” within the context of oauth2/openid connect.

  3. Filip Skokan

    Although to be honest I’m not 100% sure how to interpret “considered to be equivalent alternatives by the application using them” within the context of oauth2/openid connect.

    I assume something like this where kid is shared amongst “rotations” but each is a unique kty / alg combination?

    {
      "keys":[
        {
          "e":"AQAB",
          "n":"0g2AvuVgeMFHzllEFD6Degl3nzQls7yEHsjCxix7Li-UBM6plYra86hMHkRc3linyn4RfLgejUmV5rBCQMbjKgfpREcks6ElUrY0fAxsu5y-e1Q9Ic-f1FTbQr5Fo9Gy_QhgfwRtJyh5e3ooh68ji-s5GYQupE0Mr3oVsexCtnb3n2vufhfHGN-3yCoUwVNZ0G6PrSFPTLD_bMIW5h2KZStWCJxByRRoUAw1aaUOPrQ1BKcxyVsImqlnydn3mcZTt7Tx7ORmn_sk3-aqROevW7gkyihMPZMt3sYE6ghk5GA3ych-cnQOXOkO8Jfhb2ErzjWXRU4X7YgBDXYNCw_-kQ",
          "kty":"RSA",
          "kid":"nov-2019",
          "alg":"PS256"
        },
        {
          "crv":"Ed25519",
          "x":"oZUj_bwZuWqcVFUC7_rpWxKyTx5fHEx8sSUm3vH12fw",
          "kty":"OKP",
          "kid":"nov-2019",
          "alg":"EdDSA"
        },
        {
          "crv":"P-256",
          "x":"EfRdhXNJegLt9G2m0_Gbl4y7GfJWBiynu3AhU1muBb0",
          "y":"hIQlazpnsRuOSh4sUqjw8QdYz1hwEC7SGWbZ0HjhntY",
          "kty":"EC",
          "kid":"nov-2019",
          "alg":"ES256"
        },
        {
          "crv":"P-256",
          "x":"TreVPBTT9YY5pnKObggj8CbQB3gp4QEoGp7-3hWmXVo",
          "y":"bDNdLHjnFOoMPAjG-n4VQoViByG8nhmYEtbyZ91-3sM",
          "kty":"EC",
          "kid":"oct-2019",
          "alg":"ES256"
        },
        {
          "crv":"Ed25519",
          "x":"LZi6iLj_aLVXEdfeiWjkXDwGqS-xbYczDKadeedGPeY",
          "kty":"OKP",
          "kid":"oct-2019",
          "alg":"EdDSA"
        },
        {
          "e":"AQAB",
          "n":"rp6VJ11g7CKszNL-kkUlEJLNiU1iAWW9Cc0E2bh87sPQP3ECLXFZHhaBuCgAEnpUacIkz01GbmLQTWycomjZe23K80aHoSE46O55tVJti0ZDM9PO9fy4C40yJmm5Bc9MH3LVDuG1DsEDSYv_TMr1yrvgs6C8Mx1tGATjukaah4yemoFB1cO8G1hB5TL-M8JKgRp4ujJANSP1MLtY5rplrNF8fmlTpa17Fn1ngHG47xaWep8DRfyyYuwQ-J_re9bbjz9RPp2CIyQxJgxXutz7ma02gFFZpZ5gP8dA5miyOCiqBHXCH-9-pGZY614w14m0d3ns7hTOKEGX8BVUdxV4UQ",
          "kty":"RSA",
          "kid":"oct-2019",
          "alg":"PS256"
        }
      ]
    }
    

  4. Daniel Keijsers

    This would force OPs not to use the alg member at all, to support only one algorithm per kty, or to use a separate key for each algorithm. In my humble opinion it would be better to fill the specification gap in https://tools.ietf.org/html/rfc7517. It lacks clarification on uniqueness of entries and on how to identify the correct entry like https://bitbucket.org/openid/fapi/pull-requests/167/add-duplicate-kid-key-selection-alg/diff. Most libraries tend to use the first entry with matching kid but not all. https://knowledge.broadcom.com/external/article/138833/duplicate-kid-field-in-jwks-fails-decode.html is an example for the latter and shows clearly the misinterpretation of RFC7517.

  5. Log in to comment