diff --git a/google-auth-library-java/pom.xml b/google-auth-library-java/pom.xml
index 374ec0ed8737..260fe6bfc286 100644
--- a/google-auth-library-java/pom.xml
+++ b/google-auth-library-java/pom.xml
@@ -80,12 +80,12 @@
2.0.33
3.0.2
false
- 2.48.0
+ 2.50.0
4.33.6
0.9.0-proto3
1.15.0
2.0.17
- 2.13.2
+ 2.14.0
2.67.0-SNAPSHOT
1.18.0
3.5.2
diff --git a/grpc-gcp-java/pom.xml b/grpc-gcp-java/pom.xml
index 17997ee07915..9a6e523f52ec 100644
--- a/grpc-gcp-java/pom.xml
+++ b/grpc-gcp-java/pom.xml
@@ -64,12 +64,12 @@
grpc-gcp
2.67.0-SNAPSHOT
1.11.0
- 2.48.0
+ 2.50.0
2.2.0
- 2.13.2
+ 2.14.0
33.6.0-jre
4.33.6
- 1.82.2
+ 1.83.0
3.0.2
4.13.2
0.31.1
diff --git a/java-bigtable/pom.xml b/java-bigtable/pom.xml
index c6bd75e5f4f7..454eede9bfbd 100644
--- a/java-bigtable/pom.xml
+++ b/java-bigtable/pom.xml
@@ -144,7 +144,7 @@
github
google-cloud-bigtable-parent
https://googleapis.dev/java/google-api-grpc/latest
- 2.48.0
+ 2.50.0
-g
diff --git a/java-datastore/pom.xml b/java-datastore/pom.xml
index 674bdac579f4..30f3d56b7f25 100644
--- a/java-datastore/pom.xml
+++ b/java-datastore/pom.xml
@@ -144,7 +144,7 @@
github
google-cloud-datastore-parent
https://googleapis.dev/java/google-api-grpc/latest
- 2.48.0
+ 2.50.0
-g
diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITPostQuantumCryptography.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITPostQuantumCryptography.java
index e1f2ed82560d..0228795f3f39 100644
--- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITPostQuantumCryptography.java
+++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITPostQuantumCryptography.java
@@ -21,6 +21,7 @@
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.api.gax.httpjson.HttpJsonConscryptUtils;
import com.google.api.gax.httpjson.HttpJsonMetadata;
import com.google.api.gax.httpjson.InstantiatingHttpJsonChannelProvider;
@@ -29,6 +30,16 @@
import com.google.showcase.v1beta1.EchoResponse;
import com.google.showcase.v1beta1.EchoSettings;
import com.google.showcase.v1beta1.it.util.HttpJsonCapturingClientInterceptor;
+import io.grpc.CallOptions;
+import io.grpc.Channel;
+import io.grpc.ClientCall;
+import io.grpc.ClientInterceptor;
+import io.grpc.ForwardingClientCall;
+import io.grpc.ForwardingClientCallListener;
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor;
+import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
@@ -266,4 +277,104 @@ private static KeyStore loadCaCert(String certPath) throws Exception {
}
return trustStore;
}
+
+ /**
+ * Integration test to verify Post-Quantum Cryptography (PQC) TLS negotiation for gRPC clients.
+ *
+ *
In gRPC-Java 1.83.0+, the default Netty transport (`grpc-netty-shaded`) bundles BoringSSL
+ * (`netty-tcnative-boringssl-static`) with built-in PQC hybrid key exchange support (e.g.,
+ * X25519MLKEM768). No custom socket configurator or security provider swapping is needed.
+ *
+ *
Because the local Showcase test server uses a self-signed CA certificate (written to {@link
+ * #DEFAULT_CA_CERT_PATH}), we configure the gRPC transport channel builder directly to trust this
+ * certificate via {@link GrpcSslContexts#forClient()}. This avoids mutating global JVM system
+ * properties in {@code setUp()} and ensures HTTP/JSON tests remain completely isolated.
+ */
+ @Test
+ void testGrpcPqc_withTls() throws Exception {
+ GrpcTlsCapturingClientInterceptor interceptor = new GrpcTlsCapturingClientInterceptor();
+
+ InstantiatingGrpcChannelProvider transportChannelProvider =
+ EchoSettings.defaultGrpcTransportProviderBuilder()
+ .setEndpoint(SECURE_ENDPOINT)
+ .setInterceptorProvider(() -> Collections.singletonList(interceptor))
+ .setChannelConfigurator(
+ managedChannelBuilder -> {
+ if (managedChannelBuilder instanceof NettyChannelBuilder) {
+ try {
+ // Explicitly trust the self-signed CA certificate created by the local
+ // Showcase TLS connection without altering JVM-wide SSL trust stores.
+ ((NettyChannelBuilder) managedChannelBuilder)
+ .sslContext(
+ GrpcSslContexts.forClient()
+ .trustManager(new File(DEFAULT_CA_CERT_PATH))
+ .build());
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to configure gRPC SSL context", e);
+ }
+ }
+ return managedChannelBuilder;
+ })
+ .build();
+
+ EchoSettings settings =
+ EchoSettings.newBuilder()
+ .setCredentialsProvider(NoCredentialsProvider.create())
+ .setTransportChannelProvider(transportChannelProvider)
+ .build();
+
+ try (EchoClient client = EchoClient.create(settings)) {
+ EchoResponse response =
+ client.echo(EchoRequest.newBuilder().setContent("pqc-grpc-tls-test").build());
+ assertThat(response.getContent()).isEqualTo("pqc-grpc-tls-test");
+
+ Metadata capturedHeaders = interceptor.capturedMetadata;
+ assertThat(capturedHeaders).isNotNull();
+
+ // Verify that TLS 1.3 key exchange negotiated the expected PQC hybrid group (X25519MLKEM768).
+ String negotiatedGroup = getGrpcSingleHeaderString(capturedHeaders, TLS_GROUP_HEADER);
+ assertThat(negotiatedGroup).isEqualTo(EXPECTED_PQC_GROUP);
+ }
+ }
+
+ /**
+ * Private gRPC client interceptor to capture the response headers from the Showcase server to
+ * verify the PQC algorithm.
+ */
+ private static class GrpcTlsCapturingClientInterceptor implements ClientInterceptor {
+ final Metadata capturedMetadata = new Metadata();
+
+ @Override
+ public ClientCall interceptCall(
+ MethodDescriptor method, CallOptions callOptions, Channel next) {
+ return new ForwardingClientCall.SimpleForwardingClientCall(
+ next.newCall(method, callOptions)) {
+ @Override
+ public void start(Listener responseListener, Metadata headers) {
+ super.start(
+ new ForwardingClientCallListener.SimpleForwardingClientCallListener(
+ responseListener) {
+ @Override
+ public void onHeaders(Metadata headers) {
+ capturedMetadata.merge(headers);
+ super.onHeaders(headers);
+ }
+ },
+ headers);
+ }
+ };
+ }
+ }
+
+ /**
+ * Private helper method required to extract a single string header from gRPC {@link Metadata}.
+ *
+ * @param metadata the captured gRPC response metadata
+ * @param name the case-insensitive HTTP/2 header name
+ * @return the string header value, or {@code null} if not present
+ */
+ private static String getGrpcSingleHeaderString(Metadata metadata, String name) {
+ Metadata.Key key = Metadata.Key.of(name, Metadata.ASCII_STRING_MARSHALLER);
+ return metadata.get(key);
+ }
}
diff --git a/librarian.yaml b/librarian.yaml
index fe4c6889f47f..0fd0b4b58840 100644
--- a/librarian.yaml
+++ b/librarian.yaml
@@ -30,7 +30,7 @@ tools:
classifier: all-deps
packaging: jar
- name: protoc-gen-java_grpc
- version: 1.82.2
+ version: 1.83.0
group_id: io.grpc
artifact_id: protoc-gen-grpc-java
classifier: linux-x86_64
diff --git a/sdk-platform-java/gapic-generator-java-pom-parent/pom.xml b/sdk-platform-java/gapic-generator-java-pom-parent/pom.xml
index 4b7b477219c5..c810ed161d02 100644
--- a/sdk-platform-java/gapic-generator-java-pom-parent/pom.xml
+++ b/sdk-platform-java/gapic-generator-java-pom-parent/pom.xml
@@ -27,13 +27,13 @@
1.3.2
- 1.82.2
+ 1.83.0
2.2.0
- 2.13.2
+ 2.14.0
33.6.0-jre
4.33.6
1.62.0
- 2.48.0
+ 2.50.0
1.0.0
3.1
1.7.0