Review Release Process and Backporting Policies

Issue #375 new
Josh Cummings created an issue

Congratulations on the 9.0 release!

Now seems like it might be a good time to review Nimbus's release process and backporting policies for potential improvements.

Spring Security is a project that depends on Nimbus and also follows semantic versioning. The two projects release at different paces and with different support guarantees.

For example, Spring Security releases a minor version every six months. Nimbus, it appears, releases with just about every PR merge. Spring Security supports minor releases for 18 months from the release date. It's not clear to me to which minor versions, if any, Nimbus regularly backports fixes nor for how long they'll do it.

These factors together introduce some challenges with Spring Security users getting Nimbus's bug fixes and security patches.

For example, Spring Security 5.3.0 released in March 2020 and depends on nimbus-jose-jwt 8.9. Ideally, Spring Security 5.3.x would only make maintenance upgrades from 8.9.x. But, up to this point, we've been taking minor version Nimbus upgrades in our 5.3.x release to simplify getting bug fixes and security patches introduced in future Nimbus versions.

As another example, Spring Security 5.4 releases in September and would ideally upgrade to 8.20 since that is the next 8.x minor release. However, now that 9 is released, I wonder how simple it will be to get bug fixes and security patches regularly applied to 8.20.x over the next 18 months.

Is there a way to improve how Nimbus releases or how it supports older versions? Some things that would be nice to consider would be a release calendar and a clearer understanding of which minor versions will get fixes and security patches over a longer period of time.

Comments (6)

  1. Vladimir Dzhuvinov

    Thanks Josh!

    The Nimbus lib follows semantic versioning (x.y.z) too, z = bug fixes, y = new features without breaking APIs, x = significant API changes, incl breaking changes.

    Merged feature PRs do indeed result, almost always, in a new y release and so do bug fixes, so people can benefit from the contribution as soon as possible, this is also crucial for our internal development where we aim to have a new feature release of the Connect2id server every month.

    Regarding Nimbus lib support and backporting, right now there is no explicit policy about that.

    What we can do to help you is to apply security patches to 8.20.x over the next 18 months, until March 2022. Is that going to work for you? Some features may also get backported to 8.x because the 9.x introduced a breaking change which will take some time to upgrade to in all our products.

  2. Stuart Low

    Can confirm that this release immediately breaks Spring Security:

    2020-09-19 15:01:59.491 ERROR 26255 [nio-8050-exec-2] o.a.j.l.DirectJDKLog                     : Servlet.service() for servlet [dispatcherServlet] in context with path [/dio-au] threw exception [Filter execution threw an exception] with root cause
    
    java.lang.NoSuchMethodError: 'net.minidev.json.JSONObject com.nimbusds.jose.Header.toJSONObject()'
        at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.createJwt(NimbusJwtDecoder.java:146)
        at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.decode(NimbusJwtDecoder.java:129)
        at org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider.authenticate(JwtAuthenticationProvider.java:84)
    

    While we can downgrade we have some code (both using a parent bom) which uses Nimbus directly (which we have upgraded) and other code which uses Spring Security (which now breaks as per above).

    I guess it would have been ideal if the retired methods could have been marked @Deprecated for a few revisions so that upstream software could have time to adjust or port over a backward compatibility layer?

    While the shading fix mentioned in the release notes works it only does so during packaging (which spring-boot:run does not do).

    FWIW: We found we could resolve this with the new Nimbus version by creating a replica of NimbusJwtDecoder in the same package location but in our upstream code base (so classpath finds our new Nimbus instead). Unfortunately (although, understandably) NimbusJwtDecoderis marked final so we couldn’t just arbitrarily extend it.

  3. Yavor Vasilev

    Hi Stuart,

    You can revert to 8.20.1 (released five days ago). The 8.x is going to be maintained for a period of time.

    The @Deprecated had been considered, but given the number of API calls (toJSON{Object|…} / parse) that needed to be doubled (and complicating the new method naming), the change was made without a transition.

    I hope your Spring Security tip can be of help to others.

  4. Josh Cummings reporter

    Thanks for your response and offer!

    I think the idea of supporting a given minor version for a longer period of time is good. Yes, applying patches to 8.20.x will be helpful.

    One concern is security patches. Since Spring Security releases a minor version every six months, that means that every six months Spring Security selects a Nimbus minor version to ideally stick with.

    Given that, what would you think of applying security patches long-term to an identified list of minor versions? 8.20.x seems like an example of this that you’ve suggested. From Spring Security’s perspective, another would come up in March 2021 when Spring Security 5.5 releases.

    Others would be 7.8.x and 6.0.x, which are the versions that Spring Security 5.2.x and 5.1.x use, respectively. If these versions also get security patches, then there’s a reduced risk of those versions needing to do a dramatic Nimbus upgrade in order to capture security fixes.

  5. Vladimir Dzhuvinov

    Today I pushed a patched up 8.x:

    version 8.20.2 (2021-02-03)
        * Adds quick check in ECDSAVerifier to reject ESxxx signatures which length
          doesn't match the expected for the ESxxx algorithm (iss #399).
        * Fixes time unit conversion in DefaultJWKSetCache.getLifespan and
          getRefreshTime (iss #384).
        * Prevent instantiation of unneeded new SecureRandom in
          DefaultJWSVerifierFactory to save resources (iss #385).
        * Makes DefaultJWKSetCache thread-safe (iss #392).
        * Makes DefaultJWKSetCache.put NPE safe in concurrent scenarios (iss #392).
        * Adds new JWKSetWithTimestamp class, for use by DefaultJWKSetCache.
    

  6. Log in to comment