Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce an authentication plugin interface to the Trino JDBC driver #22516

Open
sugibuchi opened this issue Jun 26, 2024 · 1 comment
Open

Comments

@sugibuchi
Copy link

sugibuchi commented Jun 26, 2024

Proposal

Introduce an authentication plugin interface similar to the ones existing in the PostgreSQL JDBC driver and MySQL JDBC driver to the Trino JDBC driver.

Context

Many public clouds and PaaS platforms, including Kubernetes, have a kind of "service account" mechanism that allows hosted workloads to access protected resources without predefined security credentials.

  • AWS: IAM role for EC instances, EKS service accounts, etc.
  • Azure: Entra Managed Identity
  • GCP: Service account
  • Kubernetes: Workload identity federation

Using such service accounts significantly simplifies application deployment and improves security by eliminating the need for tedious credential management. A question here is how we can utilize service accounts provided by each platform in the Trino JDBC driver.

The main difficulty of this problem is that each platform has a different mechanism for authentication with service accounts and provides its own SDK for this. Therefore, it is not realistic to implement service account support for various platforms directly in the JDBC driver.

Interestingly, Microsoft Azure integrates its authentication framework, including service account (managed identity) support, into JDBC drivers by using "authentication plugin" interfaces.

The PostgreSQL JDBC driver and MySQL JDBC driver have authentication plugin interfaces (PostgreSQL, MySQL), which allow JDBC clients to plug in third-party components for client authentication.

The authentication plugins (PostgreSQL, MySQL) provided by the Azure identity authentication extensions authenticate JDBC clients in various ways supported by the Azure Identity framework and send JWT access tokens issued by Entra ID for authenticated clients to Azure PostgreSQL and MySQL as security credentials.

The support of a similar plugin interface in the Trino JDBC driver will enable more seamless integration of the authentication mechanism provided by each platform into Trino user authentication.

Technical details (idea)

Plugin API

Conceptually, the minimum definition of the authentication plugin interface for Trino looks like:

public interface AuthenticationPlugin 
{
    Set<String> propertyNames();

    void validateProperties(Properties properties) throws SQLException;

    boolean requireSecureConnection();
}

public interface HttpInterceptorPlugin extends AuthenticationPlugin
{
    Interceptor getInterceptor(String host, Properties properties);
}

AuthenticationPlugin interface defines an API for validating connection properties for the plugin. We need to define interfaces for each of the authentication methods supported by Trino as an extension of this interface. HttpRequestInterceptorPlugin in the above code is an interface that can be used for basic authentication, JWT authentication, and headers authentication.

For example, we can implement a plugin for using Entra ID-based authentication like below:

public class EntraIdAuthenticationPlugin implements HttpInterceptorPlugin
{
    public static String API_ID_URI = "azure.apiIdUri";
    ...
    public Interceptor getInterceptor(String host, Properties properties)
    {
        TokenCredential credential = new DefaultAzureCredentialBuilder().build();
        TokenRequestContext request = new TokenRequestContext().addScopes(properties.getProperty(API_ID_URI));

        return chain -> chain.proceed(chain.request().newBuilder()
                .addHeader(AUTHORIZATION, "Bearer " + credential.getTokenSync(request).getToken())
                .build());
    }
}

Modification of the JDBC driver

We need to implement the following modifications in TrinoUri.

  • Support authenticationPluginName as a new connection property
  • Extract and validate extra connection properties for the plugins
  • Instantiate and use specified plugins to configure HTTP clients

Usage

JDBC clients can use an authentication plugin by setting the plugin class name as authenticationPluginName with additional connection properties for the plugin.

Properties connectionProperties = new Properties();

connectionProperties.setProperty("SSL", "true");
connectionProperties.setProperty("authenticationPluginName", "io.trino.jdbc.plugin.azure.EntraIdAuthenticationPlugin");
connectionProperties.setProperty("azure.appIdUri", "api://xxxxx-.....");

Connection connection = DriverManager.getConnection("jdbc:trino://host:port", connectionProperties);

The above example code will automatically detect an available authentication method, including a service account (Managed Identity), thanks to DefaultAzuretokenCredential and send JWT access tokens issued by Entra ID to Trino.

On the Trino server side, we can use JWT authentication to authenticate clients.

Status

We are testing a custom version of the Trino JDBC driver with this plugin interface to use Entra ID-based authentication. It works well in Azure for now, but more details of the plugin API need to be discussed.

@mosabua
Copy link
Member

mosabua commented Jun 26, 2024

fyi @electrum

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants