diff --git a/api/src/main/java/io/grpc/CallCredentials.java b/api/src/main/java/io/grpc/CallCredentials.java index 3e588e24027e..cac5245c5393 100644 --- a/api/src/main/java/io/grpc/CallCredentials.java +++ b/api/src/main/java/io/grpc/CallCredentials.java @@ -62,6 +62,22 @@ public abstract void applyRequestMetadata( @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914") public abstract void thisUsesUnstableApi(); + /** + * Check if the security level on the transport is higher than or equal to the minimum security + * level required by {@link CallCredentials} in order to transfer it. + * + *
It should be called in {@link applyRequestMetadata} before sending any + * individual RPC. The RPC should not be sent if the API returns false. + * More details can be found in https://github.com/grpc/proposal/pull/167. + * + * @param requestInfo request-related information + * @param minSecurity minimum security level required by {@link CallCredentials} + */ + public final boolean checkSecurityLevel(RequestInfo requestInfo, SecurityLevel minSecurity) { + SecurityLevel security = requestInfo.getSecurityLevel(); + return security.compareTo(minSecurity) >= 0 ? true : false; + } + /** * The outlet of the produced headers. Not thread-safe. * diff --git a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java index 852fba73b20a..084ccde035f1 100644 --- a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java +++ b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java @@ -90,7 +90,7 @@ public void thisUsesUnstableApi() {} public void applyRequestMetadata( RequestInfo info, Executor appExecutor, final MetadataApplier applier) { SecurityLevel security = info.getSecurityLevel(); - if (requirePrivacy && security != SecurityLevel.PRIVACY_AND_INTEGRITY) { + if (requirePrivacy && !checkSecurityLevel(info, SecurityLevel.PRIVACY_AND_INTEGRITY)) { applier.fail(Status.UNAUTHENTICATED .withDescription("Credentials require channel with PRIVACY_AND_INTEGRITY security level. " + "Observed security level: " + security)); diff --git a/xds/src/main/java/io/grpc/xds/sds/FileBasedPluginCredential.java b/xds/src/main/java/io/grpc/xds/sds/FileBasedPluginCredential.java index 57dc592d50c6..3817bebabf31 100644 --- a/xds/src/main/java/io/grpc/xds/sds/FileBasedPluginCredential.java +++ b/xds/src/main/java/io/grpc/xds/sds/FileBasedPluginCredential.java @@ -29,6 +29,7 @@ import io.envoyproxy.envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.MetadataCredentialsFromPlugin; import io.grpc.CallCredentials; import io.grpc.Metadata; +import io.grpc.SecurityLevel; import io.grpc.Status; import java.io.File; import java.io.IOException; @@ -90,6 +91,12 @@ private static DataSource buildDataSourceFromConfigStruct(Struct secretValueStru @Override public void applyRequestMetadata( @Nullable RequestInfo requestInfo, Executor appExecutor, final MetadataApplier applier) { + if (!checkSecurityLevel(requestInfo, SecurityLevel.PRIVACY_AND_INTEGRITY)) { + applier.fail(Status.UNAUTHENTICATED + .withDescription("Credentials require channel with PRIVACY_AND_INTEGRITY security level. " + + "Observed security level: " + requestInfo.getSecurityLevel())); + return; + } appExecutor.execute( new Runnable() { @Override