back to all blogsSee all blog posts

Workload identity and JWK rotation for JWT Builder, configurable quiesce timeout, and Netty transport in 26.0.0.11-beta

image of author
Ismath Badsha on Oct 20, 2026
Post available in languages:

Open Liberty 26.0.0.11-beta adds workload identity injection and JWK rotation settings to the JWT Builder, makes the server quiesce timeout configurable on the server element, and previews a Netty-based HTTP transport.

The Open Liberty 26.0.0.11-beta includes the following beta features (along with all GA features):

Workload identity and JWK rotation support for JWT Builder

A JSON Web Token (JWT) is a compact, signed token that carries claims about a subject, and a JSON Web Key (JWK) is a key that consumers use to verify the token’s signature. The JWT Builder now supports automatic workload identity injection into the JWTs that it generates, so JWT consumers can identify the workload or application that generated a JWT. The JWT Builder also now lets you configure how often it rotates its JWKs and the maximum number of JWKs it publishes on the JWK endpoint (the default rotation interval is 12 hours and the default maximum of JWKs is 2). When the maximum number of JWKs is reached, the oldest JWK is discarded after the next rotation. Publishing more JWKs ensures that previously issued JWTs remain verifiable after rotation. Alternatively, the maximum number of JWKs can be set to 1 to invalidate all previously issued JWTs after each JWK rotation.

These capabilities are configured through the workloadIdentityClaim, jwkRotationTime, and jwkMaxKeys attributes in the jwtBuilder element of the JSON Web Token 1.0 (jwt-1.0) feature. This feature is intended for server administrators and application developers.

Previously, developers had to generate a workload identity themselves and inject it into the JWTs by using the JwtBuilder API. Now, the JwtBuilder API can automatically inject a workload identity into the JWTs it builds. Once the workloadIdentityClaim property is set on the jwtBuilder element, the claim designated by that property cannot be modified by JwtBuilder APIs which reference that jwtBuilder element, providing a verifiable attestation of the originating workload.

JWT Builders before this release rotated JWKs every 12 hours, and the JWK endpoint published a maximum of 2 JWKs. Now server administrators can specify the rotation interval based on their security requirements and the maximum number of JWKs that the JWK endpoint publishes, reducing disruption when JWKs are rotated.

Enable workload identity

To enable workload identity in the JWT Builder, set the workloadIdentityClaim attribute in the jwtBuilder element to your desired claim name. For example:

<jwtBuilder id="myJwtBuilder" workloadIdentityClaim="workload-identity" />

When the JwtBuilder API is used to create a JWT, it automatically injects the workload identity into the workload-identity claim. For example:

JwtBuilder.create("myJwtBuilder")
    .subject("jdoe")
    .audience(List.of("server"))
    .claim("email", "[email protected]")
    .buildJwt();

This code creates a JWT with the following payload:

{
  "token_type": "Bearer",
  "aud": "server",
  "sub": "jdoe",
  "email": "[email protected]",
  "workload-identity": "myHost,/wlp/usr/,myServer,myApp",
  "iss": "https://localhost:9443/jwt/myJwtBuilder",
  "exp": 1790280039,
  "iat": 1790272839
}

The format of the workload identity claim’s value is <host-name>,<path-to-usr-dir>,<server-name>,<app-name>. In a containerized environment, you can use the CONTAINER_HOST and CONTAINER_NAME environment variables to customize the <host-name> and <server-name> values.

Configure JWK rotation

To configure the JWK rotation interval and the maximum number of JWKs published on the JWK endpoint, set the jwkRotationTime and jwkMaxKeys attributes in the jwtBuilder element. For example:

<jwtBuilder jwkRotationTime="30m" jwkMaxKeys="4" />

In this example, the JWKs are rotated every 30 minutes and the JWK endpoint publishes a maximum of 4 JWKs.

For more information, see the following resources:

Configurable quiesce timeout on the server element

When the server shuts down, Liberty enters a quiesce stage, which prevents services from accepting new requests and allows existing requests to complete. Previously, the quiesce stage was fixed at 30 seconds. You can now configure the server quiesce timeout (quiesceTimeout) directly on the server element in the server.xml file.

This update is intended for developers and operators who experience problems during server shutdown when 30 seconds is not long enough for services to complete existing requests.

In 26.0.0.10-beta, you could configure the quiesce timeout on the executor element. This setting is now promoted to the server element, which is the appropriate location for a server-wide shutdown setting. If quiesceTimeout is configured on the server element, and chainQuiesceTimeout is configured on the channelfw element, the value on the server element takes precedence.

To configure the quiesce timeout, add the quiesceTimeout attribute to the server element in the server.xml file:

<server quiesceTimeout="1m30s">
    ...
</server>

The timeout value is a positive duration, which is a number followed by a unit of time: hours (h), minutes (m), or seconds (s). You can combine units in a single value; for example, 1m30s is equivalent to 90 seconds. The minimum value is 30 seconds. If you specify a shorter duration, the minimum of 30s is used instead.

For more information, see the Liberty configuration reference for the server element and the related GitHub issue Make Quiesce time configurable (#25523).

Netty on Open Liberty

Open Liberty now provides a Netty-based HTTP transport as a beta preview. This is an internal implementation swap of the underlying transport that is used for HTTP/1.1, HTTP/2, WebSocket, JMS, and SIP communications. It is designed for zero migration: your applications and server.xml file should continue to behave the same. We are looking forward to your feedback before GA.

This update is targeted at application developers, performance engineers, and operations and site engineers who validate behavior, throughput, and observability. Netty’s event-driven I/O gives Open Liberty a modern foundation for long-term scalability, easier maintenance, and future performance work, all without asking you to change APIs or configuration.

Try the Netty-based transport

No changes are required to benefit from the Netty-based transport. Use the All Beta Features runtime for this release. To help us validate parity and performance for your real-world scenarios, you can try the following areas:

  • HTTP/1.1 and HTTP/2: large uploads and downloads, chunked transfers, compression-enabled content, and keep-alive behavior.

  • WebSocket: long-lived communications and backpressure scenarios.

  • Timeouts: read, write, and keep-alive timeouts under load.

  • Access logging: verify the formatting and log results compared to previous builds.

  • JMS communications: message send and receive throughput, and durable subscriptions.

Limitations of the beta

HTTP

  • HTTP requests with a content length greater than the maximum integer value fail because of internal limitations on request size with Netty.

  • If the http option maxKeepAliveRequests has no limit, there is a maximum limit of 50 pipelined requests on HTTP/1.1.

  • Because of internal limitations of the Netty library, the http option MessageSizeLimit is capped at the maximum integer value for HTTP/2.0 connections.

  • Because of internal differences with Netty, the http option ThrowIOEForInboundConnections might behave differently from the Channel Framework implementation.

ALPN

  • The Netty implementation supports only the native JDK ALPN implementation. For information about the ALPN implementations that the Channel Framework supports but the Netty beta does not, see ALPN support.

Try it now

To try out these features, update your build tools to pull the Open Liberty All Beta Features package instead of the main release. The beta works with Java SE versions 27, 25, 21, 17, 11, and 8.

If you’re using Maven, you can install the All Beta Features package using:

<plugin>
    <groupId>io.openliberty.tools</groupId>
    <artifactId>liberty-maven-plugin</artifactId>
    <version>3.12.4</version>
    <configuration>
        <runtimeArtifact>
          <groupId>io.openliberty.beta</groupId>
          <artifactId>openliberty-runtime</artifactId>
          <version>26.0.0.11-beta</version>
          <type>zip</type>
        </runtimeArtifact>
    </configuration>
</plugin>

You must also add dependencies to your pom.xml file for the beta version of the APIs that are associated with the beta features that you want to try. For example, the following block adds dependencies for two example beta APIs:

<dependency>
    <groupId>org.example.spec</groupId>
    <artifactId>exampleApi</artifactId>
    <version>7.0</version>
    <type>pom</type>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>example.platform</groupId>
    <artifactId>example.example-api</artifactId>
    <version>11.0.0</version>
    <scope>provided</scope>
</dependency>

Or for Gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'io.openliberty.tools:liberty-gradle-plugin:4.0.3'
    }
}
apply plugin: 'liberty'
dependencies {
    libertyRuntime group: 'io.openliberty.beta', name: 'openliberty-runtime', version: '[26.0.0.11-beta,)'
}

Or if you’re using container images:

FROM icr.io/appcafe/open-liberty:beta

Or take a look at our Downloads page.

If you’re using IntelliJ IDEA, Visual Studio Code or Eclipse IDE, you can also take advantage of our open source Liberty developer tools to enable effective development, testing, debugging and application management all from within your IDE.

For more information on using a beta release, refer to the Installing Open Liberty beta releases documentation.

We welcome your feedback

Let us know what you think on our mailing list. If you hit a problem, post a question on StackOverflow. If you hit a bug, please raise an issue.