Problem
Secrets stored in the GCP secret manager service can be retrieved using the google-cloud-secret-manager client library.
Your code may fail with an SSLHandshakeException error message on Databricks Runtime 9.1 LTS and below.
Sample code:
import com.google.cloud.secretmanager.v1.AccessSecretVersionResponse; import com.google.cloud.secretmanager.v1.ProjectName; import com.google.cloud.secretmanager.v1.Replication; import com.google.cloud.secretmanager.v1.Secret; import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; import com.google.cloud.secretmanager.v1.SecretPayload; import com.google.cloud.secretmanager.v1.SecretVersion; import com.google.protobuf.ByteString; import com.google.cloud.secretmanager.v1.SecretName; import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings import com.google.api.gax.core.FixedCredentialsProvider; import com.google.auth.Credentials def access_secret_version(secret_id, version_id="latest"): # Create the Secret Manager client. client = secretmanager.SecretManagerServiceClient() # Build the resource name of the secret version. name = f"projects/{PROJECT_ID}/secrets/{secret_id}/versions/{version_id}" # Access the secret version. response = client.access_secret_version(name=name) # Return the decoded payload. return response.payload.data.decode('UTF-8') import hashlib def secret_hash(secret_value): # return the sha224 hash of the secret value return hashlib.sha224(bytes(secret_value, "utf-8")).hexdigest()
Error message:
UnavailableException: io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0] Caused by: StatusRuntimeException: UNAVAILABLE: io exception Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0] Caused by: SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) Caused by: io.grpc.StatusRuntimeException: UNAVAILABLE: io exception Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0] Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
Cause
GCM (Galois/Counter Mode) cipher suites are not enabled by default on Databricks Runtime 9.1 LTS and below.
Without the GCM cipher suites, there is no protocol available to establish the expected SSL connection to the GCP secret manager.
You can use the nmap utility to verify which cipher suites are required by the external server.
%sh nmap --script ssl-enum-ciphers -p 443 secretmanager.googleapis.com
Solution
You must enable GCM cipher suites to connect to the GCP secret manager service.
If you upgrade to Databricks Runtime 10.4 LTS and above, GCM cipher suites are enabled by default.
If you stay on Databricks Runtime 9.1 LTS and below, you should follow the instructions in the Enable GCM cipher suites knowledge base article to install GCM cipher suites on your cluster.
Once you have enabled GCM cipher suites, you can connect to the GCP secret manager service.