Skip to main content

v1.36.0

February 5, 2026

🌟 New features

  • Standalone Athenz Token Validation: You can now use AthenzAuthorizer to validate Athenz tokens outside of Armeria's request pipeline. This allows you to easily integrate Athenz authorization into third-party frameworks like Spring MVC or other servlet-based applications. #6607
    ZtsBaseClient ztsBaseClient = ...;
    AthenzAuthorizer authorizer =
    AthenzAuthorizer.builder(ztsBaseClient)
    .policyConfig(new AthenzPolicyConfig("your-domain"))
    .build();

    // Validate tokens anywhere
    AccessCheckStatus status =
    authorizer.authorize(token, resource, action); // 👈👈👈
  • Custom Athenz Token Headers: You can now specify custom HTTP headers for Athenz tokens. This is particularly useful when integrating legacy systems or proprietary authentication schemes that don't utilize standard Athenz headers. #6422 #6604
    // Custom header implementation
    class MyCustomHeader implements AthenzTokenHeader {
    @Override
    public AsciiString headerName() {
    return AsciiString.of("X-Company-Token");
    }
    ...
    }

    // Client-side usage
    AthenzClient
    .builder(ztsBaseClient)
    .tokenHeader(new MyCustomHeader()) // 👈👈👈
    .newDecorator();

    // Server-side usage with annotated services
    @RequiresAthenzRole(
    resource = "my-resource",
    action = "read",
    customHeaders = {"X-Company-Token"}) // 👈👈👈
    public void secureEndpoint() { ... }
  • Faster EventLoopGroup Shutdown: You can now configure custom graceful shutdown parameters for EventLoopGroups to reduce application shutdown time. By default, Netty waits 2 seconds during the quiet period, which can be unnecessarily long for test environments or applications that require rapid restarts. #5813 #6588
    EventLoopGroup eventLoopGroup =
    EventLoopGroups
    .builder()
    .numThreads(4)
    // Reduce quiet period to 100ms and timeout to 500ms
    .gracefulShutdown(Duration.ofMillis(100), Duration.ofMillis(500)) // 👈👈👈
    .build();

    Server.builder()
    .bossGroupFactory(threadName -> {
    return EventLoopGroups
    .builder()
    .numThreads(1)
    .threadFactory(ThreadFactories.newThreadFactory(threadName, false))
    // Reduce quiet period and timeout to 0ms for immediate shutdown
    .gracefulShutdownMillis(0L, 0L)
    .build();
    })
    .workerGroup(eventLoopGroup)
    ...
    .build();
    ClientFactory.builder()
    .workerGroup(eventLoopGroup)
    ...
    .build();
  • File System Change Monitoring: You can now watch directories for file changes using DirectoryWatchService. This is useful for implementing hot-reloading of configuration files, certificates, or other resources without restarting your application. #6598
    try (DirectoryWatchService watchService = new DirectoryWatchService()) {
    Cancellable cancelToken =
    watchService.register(Paths.get("/var/logs"), (dir, file, event) -> {
    // Handle file change events here
    System.out.println("File changed: " + file);
    });
    ...
    // Cancel the watch when no longer needed
    cancelToken.cancel();
    }
  • DocService Docstring Enhancements: DocService documentation now consistently displays descriptions for return values and exceptions across all service types, including annotated services, gRPC, and Thrift. For annotated services, you can use the new @ReturnDescription and @ThrowsDescription to provide detailed context for API consumers. #6605
    @Get("/users/{id}")
    @ReturnDescription("The user with the specified ID")
    @ThrowsDescription(value = IllegalArgumentException.class, description = "If the ID is invalid")
    @ThrowsDescription(value = NotFoundException.class, description = "If the user is not found")
    public User getUser(@Param String id) {
    // ...
    }

📈 Improvements

🛠️ Bug fixes

  • X-Forwarded-For header values with leading or trailing whitespace around comma-separated addresses (e.g., "192.168.1.1 , 10.0.0.1") are now trimmed and parsed correctly. #6615
  • Response content preview is now correctly set to null when an exception occurs during response processing. #6589
  • Spring Boot Actuator now streams heap dump data directly to the client instead of buffering the entire dump in memory. #6612

📃 Documentation

⛓ Dependencies

  • Athenz 1.12.31 → 1.12.33
  • BlockHound 1.0.15 → 1.0.16
  • Dropwizard Metrics 4.2.37 → 4.2.38
  • Jackson 2.20.1 → 2.21.0
  • Jetty 12.0.23 → 12.0.32
  • JUnit 5.14.1 → 5.14.2
  • Kotlin 2.2.21 → 2.3.0
  • Kubernetes client 7.4.0 → 7.5.2
  • Logback 1.5.23 → 1.5.27
  • MCP 0.17.0 → 0.17.2
  • Micrometer 1.16.1 → 1.16.2
  • Micrometer Tracing 1.6.1 → 1.6.2
  • Reactor 3.8.1 → 3.8.2
  • Spring 6.2.14 → 6.2.15, 7.0.2 → 7.0.3
  • Spring Boot 3.5.8 → 3.5.10, 4.0.1 → 4.0.2

🙇 Thank you

This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

@0x1306e6d@jchrys@trustin@ikhoon@novoj@injae-kim@paka-jo@minwoox@jrhee17@JAEKWANG97

Like Armeria?
Star us ⭐️

×