trinodb / grafana-trino

The Trino datasource allows to query and visualize Trino data from within Grafana.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] Add capability to impersonate user (pass Grafana connected to Trino and execute request in his name)

rico-elb opened this issue · comments

Hello Everyone,

Some context
As a user of Starburst, we need to be able to impersonate Grafana's connected users to execute request on Starburst.
Because we apply access policies with Ranger on Starburst and want to be able to apply the right access of the user who is connected to Grafana.
We don't want to use a generic service account, as we can't figure who exactly perform the request, and we need that information for two reasons:

  • auditing
  • applying the right access to the requested ressource at a user (Grafana's connected user) level

For now, the user configured on the Grafana's Data Source configuration is the one which perform the request on Starburst.

So, what we are looking for:

  • Configure the Data Source to activate impersonation of Grafana's connected user
  • Impersonate all requests done by Grafana over Trino with the Grafana's connected user.

Some search on what could be done (maybe) to achieve that
Unfortunately, I don't have suffisiant knowlegde to make the dev myself for this. That's why I come here...

But here the things I think are needed to be done/implemented (even if I don't know exactly where):

  • Add a checkbox like "impersonationNeeded" on the config page of the Grafana Trino DataSource (in which file, I don't know ?)
  • Then we have to get the connected user, maybe something like that in the Datasource.ts:
impersonationNeeded: Boolean;
connectedUser: String;

constructor(....) {
	this.impersonationNeeded = instanceSettings.jsonData.impersonationNeeded || false;
	this.connectedUser = instanceSettings.username;
}

Then maybe a possibility to pass connected user to each Trino request::

  • And use those informations when submitting a request to Trino via HTTP connexion:
doRequest(options: any) {
    options.headers = options.headers || {};

    // Add the impersonation header if set
    if (this.impersonationNeeded) {
      options.headers['X-Trino-User'] = this.connectedUser;
    }

    return this.backendSrv.datasourceRequest[...];
  }

But does this header option be transferred to the Trino client when calling request, I don't know ?

Another possibility, is maybe adding this option in the Trino client in Go directly when executing a request:
https://github.com/trinodb/trino-go-client/blob/60351ff4fb2c3a2c1e67ea660ee37d286b2aeb15/README.md#system-access-control-and-per-query-user-information

db.Query("SELECT * FROM foobar WHERE id=?", 1, sql.Named("X-Trino-User", string(<connectedUser>)))

But I don't see how to pass to the Trino GO Client instance....

I think this feature can useful for many Trino user.

Can someone know how to do that ?

Thanks,

Eric

This is a very reasonable request. Usually, this is solved by setting the session user connection property.

I started looking into this. There's some support for it in Grafana: https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/add-authentication-for-data-source-plugins#forward-oauth-identity-for-the-logged-in-user

What we need to figure out is if we can access these headers when opening up a connection, to set the session user, instead of later, when executing queries.