Skip to content

Configure OAuth 2.0 Authentication

To implement OAuth 2.0 authentication with HTTPS support for both Trino's Web UI and JDBC driver connections, two main configuration areas must be addressed:

  • TLS/HTTPS Configuration: Enables secure connections for Trino clients accessing the Web UI and using JDBC drivers (represented by blue lines in the diagram)
  • Internal Communication Security: Establishes secure communication channels between Trino cluster nodes, including coordinator and workers (represented by red lines in the diagram)

Configure TLS/HTTPS

By default, Trino operates without any security measures enabled. This configuration permits connections to the server through HTTP protocol URLs when accessing Trino via the CLI, Web UI, or other client applications.

To enable TLS support for Trino, you have two implementation options:

  • Use a load balancer or reverse proxy to handle TLS termination. This is the recommended and simplest approach for most deployments.
  • Configure TLS directly on the Trino server. This method requires obtaining a valid certificate and configuring it within the Trino coordinator settings.

Since we're deploying Trino within a local Kubernetes environment, we'll implement the second approach by configuring TLS/HTTPS directly on the Trino server using self-signed certificates.

Automated Certificate Generation

Use the provided script to automatically generate all necessary certificates and files:

./generate-tls-certs.sh
generate-tls-certs.sh
#!/bin/bash

set -euo pipefail


CERT_DIR=".cert"
mkdir -p "$CERT_DIR"
rm -f "$CERT_DIR"/*


echo "Creating TLS certificates for Trino..."


echo "Step 1: Creating Private Key..."
openssl genrsa -out $CERT_DIR/private.key 2048 > /dev/null
echo "Step 1: Completed."


echo "Step 2: Creating Certificate..."
openssl req \
  -new \
  -x509 \
  -key $CERT_DIR/private.key \
  -config openssl.cnf \
  -days 365 \
  -extensions v3_req \
  -out $CERT_DIR/certificate.crt > /dev/null
echo "Step 2: Completed."


echo "Step 3: Combining Private Key and Certificate..."
cat $CERT_DIR/private.key $CERT_DIR/certificate.crt > $CERT_DIR/trino-dev.pem
rm -f $CERT_DIR/private.key $CERT_DIR/certificate.crt
echo "Step 3: Completed."


echo "Step 4: Creating Kubernetes secret..."
kubectl create secret generic trino-tls-secret \
    --from-file=trino-dev.pem="$CERT_DIR/trino-dev.pem" \
    --dry-run=client -o yaml > "./trino-tls-secret.yaml"
echo "Step 4: Completed."


echo "Certificate generation completed successfully!"
echo ""
echo "Generated files:"
echo "  - $CERT_DIR/trino-dev.pem (with private key and certificate)"
echo "  - trino-tls-secret.yaml (Kubernetes secret manifest)"
Details

The automated script performs the following steps. Each step can also be executed manually if needed:

Step 1: Create Private Key

echo "Step 1: Creating Private Key..."
openssl genrsa -out $CERT_DIR/private.key 2048 > /dev/null
echo "Step 1: Completed."

What this does:

  • Uses RSA algorithm to generate a 2048-bit private key
  • Saves the private key to .cert/private.key
  • This private key will be used to create the self-signed certificate

Step 2: Create Self-Signed Certificate

echo "Step 2: Creating Certificate..."
openssl req \
  -new \
  -x509 \
  -key $CERT_DIR/private.key \
  -config openssl.cnf \
  -days 365 \
  -extensions v3_req \
  -out $CERT_DIR/certificate.crt > /dev/null
echo "Step 2: Completed."

What this does:

  • Creates a new self-signed X.509 certificate using the private key
  • Uses the OpenSSL configuration file (openssl.cnf) for certificate settings
  • Certificate is valid for 365 days
  • Applies v3_req extensions which include Subject Alternative Names (SAN)
  • The certificate hostname and SAN entries are configured in openssl.cnf
  • Saves the certificate to .cert/certificate.crt
openssl.cnf
[req]
default_bits       = 2048
prompt             = no
default_md         = sha256
req_extensions     = v3_req
distinguished_name = dn

[dn]
C  = TW
ST = Taipei
L  = Taipei
O  = Velano Collective
OU = Data Platform
CN = trino.trino.svc.cluster.local

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1  = 127.0.0.1

Step 3: Combine Private Key and Certificate into PEM Format

echo "Step 3: Combining Private Key and Certificate..."
cat $CERT_DIR/private.key $CERT_DIR/certificate.crt > $CERT_DIR/trino-dev.pem
rm -f $CERT_DIR/private.key $CERT_DIR/certificate.crt
echo "Step 3: Completed."

What this does:

  • Combines the private key and certificate into a single PEM file
  • Creates .cert/trino-dev.pem containing both private key and certificate
  • This combined PEM file is commonly used by applications that need both components
  • Note: This file contains the private key and must be protected properly

Step 4: Create Kubernetes Secret Manifest

echo "Step 4: Creating Kubernetes secret..."
kubectl create secret generic trino-tls-secret \
    --from-file=trino-dev.pem="$CERT_DIR/trino-dev.pem" \
    --dry-run=client -o yaml > "./trino-tls-secret.yaml"
echo "Step 4: Completed."

What this does:

  • Generates a Kubernetes secret YAML manifest file
  • Contains the trino-dev.pem file for deployment
  • Uses --dry-run=client to generate the YAML without applying it to the cluster
  • The secret can be applied directly to the Kubernetes cluster with kubectl apply

After running the script, you will find the generated files in the .cert/ directory, the Kubernetes secret manifest file will be named trino-tls-secret.yaml and it should look like this:

Result
trino-tls-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  creationTimestamp: null
  name: trino-tls-secret
data:
  trino-dev.pem: xxx

Mount the TLS Certificate

To utilize the generated TLS certificate in your Trino deployment, create a Kubernetes secret and mount it to the coordinator's /etc/trino/tls directory.

kubectl apply -f .cert/trino-tls-secret.yaml --namespace trino
trino/values-template.yaml coordinator
coordinator:
  jvm:
    maxHeapSize: "8G"
  livenessProbe:
    initialDelaySeconds: 30
    failureThreshold: 20
  readinessProbe:
    initialDelaySeconds: 30
    failureThreshold: 20
  secretMounts:
    - name: trino-tls
      secretName: trino-tls-secret
      path: /etc/trino/tls
  additionalExposedPorts:
    https:
      servicePort: 8443
      name: https
      port: 8443
      protocol: TCP
  additionalJVMConfig:
    - --add-opens=java.base/java.nio=ALL-UNNAMED # https://trino.io/docs/current/connector/bigquery.html#arrow-serialization-support
    - --sun-misc-unsafe-memory-access=allow
  # access-control.properties: |
  #   access-control.name=file
  #   security.refresh-period=150s
  #   security.config-file=/etc/trino/access-control/rules.json

Next, configure the coordinator to use the TLS certificate by specifying its location in the http-server.https.keystore.path setting:

trino/values-template.yaml server
server:
  workers: 2
  config:
    authenticationType: "oauth2"
  coordinatorExtraConfig: |
    http-server.https.enabled=true
    http-server.https.port=8443
    http-server.https.keystore.path=/etc/trino/tls/trino-dev.pem
    http-server.authentication.oauth2.issuer=https://accounts.google.com
    http-server.authentication.oauth2.client-id=$OAUTH2_CLIENT_ID
    http-server.authentication.oauth2.client-secret=$OAUTH2_CLIENT_SECRET
    http-server.authentication.oauth2.principal-field=email
    http-server.authentication.oauth2.scopes=openid,email
    web-ui.authentication.type=oauth2
  #   distributed-sort=true
  #   query.max-history=50
  exchangeManager:
    name: filesystem
    baseDir: $EXCHANGE_S3_URLS
  # workerExtraConfig: |
  #   discovery.uri=http://trino.trino.svc.cluster.local:8080

Enable and Expose the HTTPS Endpoint

To activate HTTPS in Trino, configure the http-server.https.enabled setting to true and specify the http-server.https.port (typically 8443). Additionally, expose this port through the Kubernetes service configuration.

trino/values-template.yaml server
server:
  workers: 2
  config:
    authenticationType: "oauth2"
  coordinatorExtraConfig: |
    http-server.https.enabled=true
    http-server.https.port=8443
    http-server.https.keystore.path=/etc/trino/tls/trino-dev.pem
    http-server.authentication.oauth2.issuer=https://accounts.google.com
    http-server.authentication.oauth2.client-id=$OAUTH2_CLIENT_ID
    http-server.authentication.oauth2.client-secret=$OAUTH2_CLIENT_SECRET
    http-server.authentication.oauth2.principal-field=email
    http-server.authentication.oauth2.scopes=openid,email
    web-ui.authentication.type=oauth2
  #   distributed-sort=true
  #   query.max-history=50
  exchangeManager:
    name: filesystem
    baseDir: $EXCHANGE_S3_URLS
  # workerExtraConfig: |
  #   discovery.uri=http://trino.trino.svc.cluster.local:8080
trino/values-template.yaml coordinator
coordinator:
  jvm:
    maxHeapSize: "8G"
  livenessProbe:
    initialDelaySeconds: 30
    failureThreshold: 20
  readinessProbe:
    initialDelaySeconds: 30
    failureThreshold: 20
  secretMounts:
    - name: trino-tls
      secretName: trino-tls-secret
      path: /etc/trino/tls
  additionalExposedPorts:
    https:
      servicePort: 8443
      name: https
      port: 8443
      protocol: TCP
  additionalJVMConfig:
    - --add-opens=java.base/java.nio=ALL-UNNAMED # https://trino.io/docs/current/connector/bigquery.html#arrow-serialization-support
    - --sun-misc-unsafe-memory-access=allow
  # access-control.properties: |
  #   access-control.name=file
  #   security.refresh-period=150s
  #   security.config-file=/etc/trino/access-control/rules.json

Secure Internal Communication

To enhance security, the Trino cluster supports secure internal communication (red lines) between nodes through authentication mechanisms, with optional TLS encryption for additional protection.

Configure the shared secret by setting the same value in the config.properties file across all cluster nodes (both coordinator and workers):

internal-communication.shared-secret=<secret>

A large random key is recommended, and can be generated with the following Linux command:

openssl rand 512 | base64
trino/values-template.yaml additionalConfigProperties
1
2
3
additionalConfigProperties:
  - internal-communication.shared-secret=$INTERNAL_SHARED_SECRET
  - retry-policy=TASK

The configurations under additionalConfigProperties will impact all the nodes in the Trino Cluster.

Create Google OAuth 2.0 Client

Since we're using Google as our OAuth2 provider, we'll need to set up a Google OAuth 2.0 client. This is a straightforward process, but there are a few specific configuration details to keep in mind for Trino.

Here are the key configuration settings you'll need:

  • Application Type: Web application
  • Name: Trino (It will be only used in the Google Cloud Console for identification purposes)
  • Audience: Set to internal (Typically, Trino is used within an organization, so this setting is appropriate)
  • Authorized Redirect URIs: Add these two URLs:
    • https://127.0.0.1:8443/oauth2/callback
    • https://127.0.0.1:8443/ui/logout/logout.html

After createing the OAuth 2.0 client, you will be provided with a client ID and a client secret and you will need to copy these values into the Trino configuration.

Configure OAuth 2.0 Authentication

To activate OAuth 2.0 authentication in Trino, configure the following essential properties in the coordinator settings:

  • Client ID: OAuth 2.0 client identifier obtained from Google Cloud Console
  • Client Secret: OAuth 2.0 client secret obtained from Google Cloud Console
  • Authorization Server URL: Google's OAuth 2.0 authorization endpoint
  • Web UI Authentication Type: Must be set to oauth2 to enable OAuth 2.0 for the Web UI

These configurations establish the connection between Trino and the OAuth 2.0 provider, enabling secure authentication for both Web UI and programmatic access.

trino/values-template.yaml server
server:
  workers: 2
  config:
    authenticationType: "oauth2"
  coordinatorExtraConfig: |
    http-server.https.enabled=true
    http-server.https.port=8443
    http-server.https.keystore.path=/etc/trino/tls/trino-dev.pem
    http-server.authentication.oauth2.issuer=https://accounts.google.com
    http-server.authentication.oauth2.client-id=$OAUTH2_CLIENT_ID
    http-server.authentication.oauth2.client-secret=$OAUTH2_CLIENT_SECRET
    http-server.authentication.oauth2.principal-field=email
    http-server.authentication.oauth2.scopes=openid,email
    web-ui.authentication.type=oauth2
  #   distributed-sort=true
  #   query.max-history=50
  exchangeManager:
    name: filesystem
    baseDir: $EXCHANGE_S3_URLS
  # workerExtraConfig: |
  #   discovery.uri=http://trino.trino.svc.cluster.local:8080

Trino can automatically retrieve OAuth 2.0 configuration settings from the OIDC provider's metadata document (such as Google's configuration endpoint). When the coordinator starts up, it fetches this metadata document and automatically configures the necessary OAuth 2.0 authentication properties, removing the need for manual configuration of these settings.

The sequence diagram below illustrates the OAuth 2.0 authentication flow in Trino:

sequenceDiagram
  participant Browser
  participant Coordinator as Trino Coordinator
  participant Server as Google OAuth Server

  Browser->>Coordinator: 1. Request Trino Web UI
  Coordinator-->>Browser: 2. Redirect to Google OAuth (auth URL)
  Browser->>Server: 3. User login + consent authorization
  Server-->>Browser: 4. Redirect back to Trino + authorization code
  Browser->>Coordinator: 5. Send authorization code to Trino /oauth2/callback
  Coordinator->>Server: 6. Exchange authorization code for access token + ID token
  Server-->>Coordinator: 7. Return token(s)
  Coordinator-->>Browser: 8. Display Web UI (logged in)

  note right of Coordinator: Trino uses email from ID token as user identity

References