Developing and Deploying Custom Trino Plugins (Access Control Example)
This article explains how to develop, package, and deploy custom Trino plugins—illustrated with an access‑control plugin—by using Java SPI, Maven dependencies, implementing the Plugin and SystemAccessControl interfaces, and configuring the plugin in Trino’s configuration files.
Introduction
Trino is a fast, distributed big‑data query engine that supports single‑source and federated queries across many data sources such as Hive , MySQL , Kafka , Clickhouse , and Elasticsearch . It provides a rich Java SPI‑based plugin system that can be extended for custom needs like audit logging or access control.
Plugin Overview
Trino plugins are implemented using the standard Java SPI mechanism. Plugin classes are listed in the META-INF/services directory and loaded via ServiceLoader . The core Plugin interface defines default methods such as getConnectorFactories() , getSystemAccessControlFactories() , and getEventListenerFactories() , each returning an empty collection by default.
public interface Plugin {
default Iterable
getConnectorFactories() {
return emptyList();
}
default Iterable
getSystemAccessControlFactories() {
return emptyList();
}
default Iterable
getEventListenerFactories() {
return emptyList();
}
// ... more factory methods
}Common plugin types include SystemAccessControl (permission control), EventListener (event handling), Functions (custom functions), and PasswordAuthenticator (authentication).
Plugin Development
Below is a step‑by‑step guide to creating a custom access‑control plugin using Maven.
Dependency Configuration
Add the Trino SPI dependency to your pom.xml with provided scope because Trino supplies the classes at runtime.
<dependency>
<groupId>io.trino</groupId>
<artifactId>trino-spi</artifactId>
<scope>provided</scope>
</dependency>Trino also provides Jackson and Slice libraries; use the versions bundled with Trino. Any additional libraries must be packaged with the plugin, as Trino isolates plugin classes with a separate class loader.
Code Development
1. Create a Java class that implements Plugin and overrides getSystemAccessControlFactories() to return your custom factory.
public class CustomAccessControlPlugin implements Plugin {
@Override
public Iterable
getSystemAccessControlFactories() {
return ImmutableList.of(new CustomAccessControlFactory());
}
}2. Implement a SystemAccessControlFactory that supplies the plugin name and creates the actual access‑control implementation.
public class CustomAccessControlFactory implements SystemAccessControlFactory {
@Override
public String getName() {
return "my-custom-access-control";
}
@Override
public SystemAccessControl create(Map
config) {
return new CustomTableAccessControl(config);
}
}3. Implement the SystemAccessControl interface (or extend an existing abstract class) to provide permission checks such as checkCanSelectFromColumns , row‑level filters via getRowFilters , and column masks via getColumnMasks .
public interface SystemAccessControl {
default void checkCanSelectFromColumns(SystemSecurityContext context, CatalogSchemaTableName table, Set
columns) {
denySelectColumns(table.toString(), columns);
}
default List
getRowFilters(SystemSecurityContext context, CatalogSchemaTableName tableName) {
return List.of();
}
default List
getColumnMasks(SystemSecurityContext context, CatalogSchemaTableName tableName, String columnName, Type type) {
return List.of();
}
// ... more methods
}The methods receive context objects containing query ID, user, principal, and groups, allowing you to enforce custom security logic.
Deployment Configuration
Deployment
Package the plugin with Maven to produce a JAR file, then place the JAR (and any additional dependencies) in Trino’s plugin directory under a sub‑directory named exactly like the plugin, e.g., my‑custom‑access‑control . The plugin can be deployed to all nodes (coordinator and workers) or only to the coordinator, depending on the plugin’s requirements.
Configuration
Create an access-control.properties file in Trino’s etc directory with the following content:
access-control.name = my-custom-access-control
custom-property1 = custom-value1
custom-property2 = custom-value2The access-control.name must match the value returned by SystemAccessControlFactory.getName() . All other custom properties are passed as a Map<String, String> to the factory’s create() method.
Multiple access‑control plugins can be configured by adding access-control.config-files to etc/config.properties and listing the property files, e.g.:
access-control.config-files = etc/access-control-1.properties, etc/access-control-2.propertiesConclusion
After building, deploying, and configuring the plugin, start Trino and check the logs to verify that the custom plugin has been loaded successfully.
Reference
Trino official documentation: https://trino.io/docs/current/
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.