Summary
JWKS is Decodable, and the key-type enum has no unknown case, so decoding a key set that contains a key with an unrecognised kty throws DecodingError.dataCorrupted and the whole set fails to decode. Per RFC 7517 section 5 an unrecognised key should be ignored, not fatal, so one post-quantum key in a published JWKS takes down the classical keys with it.
Reproduction
A JWKS with classical keys and one post-quantum ML-DSA key (kty: "AKP", RFC 9964, third entry):
let jwks = try JSONDecoder().decode(JWKS.self, from: mixedJWKS)
// DecodingError.dataCorrupted: Path keys[2].kty,
// "Cannot initialize Backing from invalid String value AKP"
Measured against jwt-kit 5.6.0. The set decodes fine once the AKP key is removed. Fixture and probe available on request.
Why this matters
RFC 7517 section 5: "Implementations SHOULD ignore JWKs within a JWK Set that use kty values that are not understood by them." ML-DSA (FIPS 204 / RFC 9964, kty: "AKP") key publication is beginning across the ecosystem. When an issuer adds an ML-DSA key to a JWKS that a jwt-kit consumer reads, the whole JWKS fails to decode, so the consumer stops verifying every signature from that issuer, including classical RS256/ES256, on a spec-compliant key publication it does not control. For Vapor services fetching a remote JWKS (OIDC, open banking) that is an externally triggered outage.
Suggested fix
Make JWKS decode leniently: decode keys element by element and skip entries that fail to decode into a JWK (optionally record them), rather than failing the container. Alternatively add an unknown case to the key-type enum so an unrecognised key decodes into an inert JWK that is never selected by kid. Either implements the RFC section 5 SHOULD.
Offer
Happy to share the reproduction harness (mixed classical + AKP JWKS plus a control) and to open a PR.
Summary
JWKSisDecodable, and the key-type enum has no unknown case, so decoding a key set that contains a key with an unrecognisedktythrowsDecodingError.dataCorruptedand the whole set fails to decode. Per RFC 7517 section 5 an unrecognised key should be ignored, not fatal, so one post-quantum key in a published JWKS takes down the classical keys with it.Reproduction
A JWKS with classical keys and one post-quantum ML-DSA key (
kty: "AKP", RFC 9964, third entry):Measured against jwt-kit 5.6.0. The set decodes fine once the AKP key is removed. Fixture and probe available on request.
Why this matters
RFC 7517 section 5: "Implementations SHOULD ignore JWKs within a JWK Set that use
ktyvalues that are not understood by them." ML-DSA (FIPS 204 / RFC 9964,kty: "AKP") key publication is beginning across the ecosystem. When an issuer adds an ML-DSA key to a JWKS that a jwt-kit consumer reads, the wholeJWKSfails to decode, so the consumer stops verifying every signature from that issuer, including classical RS256/ES256, on a spec-compliant key publication it does not control. For Vapor services fetching a remote JWKS (OIDC, open banking) that is an externally triggered outage.Suggested fix
Make
JWKSdecode leniently: decodekeyselement by element and skip entries that fail to decode into aJWK(optionally record them), rather than failing the container. Alternatively add an unknown case to the key-type enum so an unrecognised key decodes into an inertJWKthat is never selected bykid. Either implements the RFC section 5 SHOULD.Offer
Happy to share the reproduction harness (mixed classical + AKP JWKS plus a control) and to open a PR.