Skip to content

Commit 2d02344

Browse files
authored
feat(mtls): Add support for X.509-based mTLS-transport in Java GAX lib (#3852)
Fixes #3851 - Refactors mTLS code path to use new CertificateBasedAccess class to determine mTLS behavior based on env vars. - Refactors mTLS code path to use DefaultMtlsProviderFactory from Java auth lib for creating a default mTLS provider using either the legacy SecureConnect mtls provider or the newer X.509 mtls provider, depending on availability.
1 parent 9b1a34b commit 2d02344

File tree

15 files changed

+511
-344
lines changed

15 files changed

+511
-344
lines changed

gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@
4242
import com.google.api.gax.rpc.TransportChannel;
4343
import com.google.api.gax.rpc.TransportChannelProvider;
4444
import com.google.api.gax.rpc.internal.EnvironmentProvider;
45-
import com.google.api.gax.rpc.mtls.MtlsProvider;
45+
import com.google.api.gax.rpc.mtls.CertificateBasedAccess;
4646
import com.google.auth.ApiKeyCredentials;
4747
import com.google.auth.Credentials;
48+
import com.google.auth.mtls.CertificateSourceUnavailableException;
49+
import com.google.auth.mtls.DefaultMtlsProviderFactory;
50+
import com.google.auth.mtls.MtlsProvider;
4851
import com.google.auth.oauth2.ComputeEngineCredentials;
4952
import com.google.auth.oauth2.SecureSessionAgent;
5053
import com.google.auth.oauth2.SecureSessionAgentConfig;
@@ -150,6 +153,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP
150153
@Nullable private final Boolean allowNonDefaultServiceAccount;
151154
@VisibleForTesting final ImmutableMap<String, ?> directPathServiceConfig;
152155
@Nullable private final MtlsProvider mtlsProvider;
156+
private final CertificateBasedAccess certificateBasedAccess;
153157
@Nullable private final SecureSessionAgent s2aConfigProvider;
154158
private final List<HardBoundTokenTypes> allowedHardBoundTokenTypes;
155159
@VisibleForTesting final Map<String, String> headersWithDuplicatesRemoved = new HashMap<>();
@@ -183,6 +187,7 @@ private InstantiatingGrpcChannelProvider(Builder builder) {
183187
this.mtlsEndpoint = builder.mtlsEndpoint;
184188
this.allowedHardBoundTokenTypes = builder.allowedHardBoundTokenTypes;
185189
this.mtlsProvider = builder.mtlsProvider;
190+
this.certificateBasedAccess = builder.certificateBasedAccess;
186191
this.s2aConfigProvider = builder.s2aConfigProvider;
187192
this.envProvider = builder.envProvider;
188193
this.interceptorProvider = builder.interceptorProvider;
@@ -484,7 +489,10 @@ boolean canUseDirectPathWithUniverseDomain() {
484489

485490
@VisibleForTesting
486491
ChannelCredentials createMtlsChannelCredentials() throws IOException, GeneralSecurityException {
487-
if (mtlsProvider.useMtlsClientCertificate()) {
492+
if (mtlsProvider == null) {
493+
return null;
494+
}
495+
if (certificateBasedAccess.useMtlsClientCertificate()) {
488496
KeyStore mtlsKeyStore = mtlsProvider.getKeyStore();
489497
if (mtlsKeyStore != null) {
490498
KeyManagerFactory factory =
@@ -853,7 +861,8 @@ public static final class Builder {
853861
private boolean useS2A;
854862
private EnvironmentProvider envProvider;
855863
private SecureSessionAgent s2aConfigProvider = SecureSessionAgent.create();
856-
private MtlsProvider mtlsProvider = new MtlsProvider();
864+
@Nullable private MtlsProvider mtlsProvider;
865+
private CertificateBasedAccess certificateBasedAccess;
857866
@Nullable private GrpcInterceptorProvider interceptorProvider;
858867
@Nullable private Integer maxInboundMessageSize;
859868
@Nullable private Integer maxInboundMetadataSize;
@@ -904,6 +913,7 @@ private Builder(InstantiatingGrpcChannelProvider provider) {
904913
this.allowedHardBoundTokenTypes = provider.allowedHardBoundTokenTypes;
905914
this.directPathServiceConfig = provider.directPathServiceConfig;
906915
this.mtlsProvider = provider.mtlsProvider;
916+
this.certificateBasedAccess = provider.certificateBasedAccess;
907917
this.s2aConfigProvider = provider.s2aConfigProvider;
908918
}
909919

@@ -994,6 +1004,12 @@ Builder setMtlsProvider(MtlsProvider mtlsProvider) {
9941004
return this;
9951005
}
9961006

1007+
@VisibleForTesting
1008+
Builder setCertificateBasedAccess(CertificateBasedAccess certificateBasedAccess) {
1009+
this.certificateBasedAccess = certificateBasedAccess;
1010+
return this;
1011+
}
1012+
9971013
@VisibleForTesting
9981014
Builder setS2AConfigProvider(SecureSessionAgent s2aConfigProvider) {
9991015
this.s2aConfigProvider = s2aConfigProvider;
@@ -1269,6 +1285,25 @@ CallCredentials createHardBoundTokensCallCredentials(
12691285
}
12701286

12711287
public InstantiatingGrpcChannelProvider build() {
1288+
if (certificateBasedAccess == null) {
1289+
certificateBasedAccess = CertificateBasedAccess.createWithSystemEnv();
1290+
}
1291+
if (certificateBasedAccess.useMtlsClientCertificate()) {
1292+
if (mtlsProvider == null) {
1293+
// Attempt to create default MtlsProvider from environment.
1294+
try {
1295+
mtlsProvider = DefaultMtlsProviderFactory.create();
1296+
} catch (CertificateSourceUnavailableException e) {
1297+
// This is okay. Leave mtlsProvider as null so that we will not auto-upgrade
1298+
// to mTLS endpoints. See https://google.aip.dev/auth/4114.
1299+
} catch (IOException e) {
1300+
LOG.log(
1301+
Level.WARNING,
1302+
"DefaultMtlsProviderFactory encountered unexpected IOException: " + e.getMessage());
1303+
}
1304+
}
1305+
}
1306+
12721307
if (isMtlsS2AHardBoundTokensEnabled()) {
12731308
// Set a {@code ComputeEngineCredentials} instance to be per-RPC call credentials,
12741309
// which will be used to fetch MTLS_S2A hard bound tokens from the metdata server.

0 commit comments

Comments
 (0)