trinodb / trino-gateway

https://trinodb.github.io/trino-gateway/
Apache License 2.0
122 stars 47 forks source link

Support certificate authentication on Trino #269

Open oneonestar opened 4 months ago

oneonestar commented 4 months ago

(Feature request) Trino Gateway currently doesn't work if the backend Trino is using certificate authentication.

There are a few ways that I could think of to solve this issue. Discussion is needed before moving to implementation.

  1. TLS Termination at Trino Proxy. Perform authentication on Trino Proxy. Forward the request to coordinator base on the routing policies. Perform authentication between Trino Proxy and Coordinator. Allow Trino Proxy to "impersonate" the user.
  2. Return HTTP 307 Redirect First decrypt the request, select coordinator base on routing policies. Return HTTP 307 Redirect to the selected coordinator. Client directly connect to the Trino coordinator.
  3. TLS Passthrough (I don't think this will work since hostname wont't match)

Discussion about automatic retry of queries in the future, will need storage of submitted queries and state, and more, will work on that at a later stage

Looking at the dev sync's meeting notes, method 1 seems a reasonable choice.

Support Certificate Authentication in Trino Gateway (draft)

electrum commented 3 months ago

In trino-proxy, we handled this by creating a JWT bearer token using the certificate principal . trino-proxy is configured with a key to generate the JWT that is trusted by the Trino coordinator. In other words, we convert the TLS certificate into a bearer token.

Another potential option is to support the Client-Certificate header from RFC 9440. This would require support in Trino. It's similar to the standard Forwarded in that it requires opt-in configuration to be trusted, as we do with the http-server.process-forwarded config.

wendigo commented 2 months ago

@electrum for the RFC 9440 do we need to touch jetty at all? We have an access to the headers in the public Identity authenticate(ContainerRequestContext request) so we can get the cert chain there

oneonestar commented 2 months ago

for the RFC 9440 do we need to touch jetty at all?

No. ContainerRequestContext is enough.

I think the flow would be:

  1. During TLS handshake, Gateway ask for client certificate
  2. Client present and proof they have the client certificate.
  3. Gateway verify the certificate is valid
  4. Gateway extract the cert chain from ContainerRequestContext.
  5. Gateway send request with Client-Certificate header to Trino, along with a JWT to proof itself is from gateway
  6. Trino verify the JWT token, extract cert chain from Client-Certificate header and pass it to CertificateAuthenticator