Summary
JWT::JWK::Set.new(existing_set) reuses existing_set.keys by reference, although the constructor describes this path as duplication.
Reproduction
original = JWT::JWK::Set.new([JWT::JWK.new(OpenSSL::PKey::RSA.generate(2048))])
copy = JWT::JWK::Set.new(original)
copy.keys.clear
raise if original.keys.empty?
The mutation currently empties both sets. Copying the array with jwks.keys.dup preserves key objects while giving each mutable set independent collection ownership.
Verification
A source-only candidate passes the focused failing/passing ownership model, the 554-example release suite (12 expected OpenSSL 3 pending), focused RuboCop, gem build and Rails 8.1.3.1 JWT integration. No repository tests or changelog were changed during the audit, so this is issue-first for the contribution policy.
Prepared with AI-assisted source review.
Summary
JWT::JWK::Set.new(existing_set)reusesexisting_set.keysby reference, although the constructor describes this path as duplication.Reproduction
The mutation currently empties both sets. Copying the array with
jwks.keys.duppreserves key objects while giving each mutable set independent collection ownership.Verification
A source-only candidate passes the focused failing/passing ownership model, the 554-example release suite (12 expected OpenSSL 3 pending), focused RuboCop, gem build and Rails 8.1.3.1 JWT integration. No repository tests or changelog were changed during the audit, so this is issue-first for the contribution policy.
Prepared with AI-assisted source review.