10.11. User Impersonation

Presto has to be authenticated when accessing external service through the connector. Typically it requires passing authentication credentials which contain information on behalf what user Presto is going to connect. Such credentials are stored in connector properties file. Any Presto user that access service through the Presto assesses it as the user configured in connector properties. This approach has following downsides: * no authorization policies built-in into this external service are able to recognize the actual user, causing that any user that authenticates to Presto has the same permissions. * it is difficult to do an audit of access of the external service as every Presto user is seen as the same local user in the external service.

One way of solving this is to impersonate the Presto user as the local user in the external service. With this approach Presto authenticates in the external service using credentials stored in connector properties file, but once it connects it informs the external service that any further action in given session should be performed on behalf of current Presto user. That way Presto user alice becomes a local user alice in the external service. This requires the user that connects to the external service (the one which is configured in connector properties file) to be trusted in this system i.e. has to be allowed to impersonate other users.

When impersonating Presto users in the external service, Presto itself also should require authentication and proper access control configuration to ensure that users with valid credentials can be authenticated in the external service.

Notice that external service is required to support impersonation mechanism and actual details are different depending on the service.

Currently connectors that supports user impersonation and Presto user to local user translation are: * Oracle Connector * PostgreSQL Connector * SQL Server Connector * Teradata Connector

Notice that Hive Connector also supports user impersonation when connecting to Hive Metastore or HDFS. However, Hive Connector does not support Presto user to local user translation.

Presto User to Local User Translation

The same actual user could be represented differently among services. For example Presto user alice_in_presto could be represented in the external service as alice_in_external_service. In such situation, before we could impersonate Presto user alice_in_presto in the external service we would need to first translate that user into alice_in_external_service. This can be done by adding to configuration user name translations file with auth-to-local.config-file in the connector properties file, like below:

auth-to-local.config-file=etc/auth-to-local-rules.json

The config file is specified in JSON format. It contains the rules defining how Presto user will be represented in the external service.

Refresh

By default, when a change is made to the auth-to-localh.config-file, Presto must be restarted to load the changes. There is an optional property to refresh the properties without requiring a Presto restart. The refresh period is specified in the connector properties file:

auth-to-local.refresh-period=10m

User Translation Rules

These rules control the Presto user name translation to the external service local user name. The result local user is calculated by the first matching rule read from top to bottom. If no rule matches, an error is raised. Each rule is composed of the following fields:

  • match (optional): determines if local user should be calculated from Presto user name (USER) or principal (PRINCIPAL). Defaults to USER.
  • pattern (required): regex to match against the value pointed with match.
  • substitution (optional): local user replacement for Presto user.
  • case (optional): determines if result local user should be lower cased (LOWER), upper cassed (UPPER) or case should remain (KEEP). Defaults to KEEP.

For example, if you want to impersonate Presto user alice to access the external system as user alice_in_the_external_system and bob as charlie, you can use the following rules:

{
  "rules": [
    {
      "match": "USER",
      "pattern": "alice",
      "substitution": "alice_in_the_external_system"
    },
    {
      "match": "USER",
      "pattern": "bob",
      "substitution": "charlie"
    }
  ]
}

If you want to impersonate Presto users with principals alice/hr@company.com and charlie/eng@company.com to access the external system as users HR_ALICE and ENG_CHARLIE accordingly, but Presto principals bob/marketing@company.com and danny/marketing@company.com to use marketing_acount, you can use the following rules:

{
  "rules": [
    {
      "match": "PRINCIPAL",
      "pattern": "[^/]+/marketing@company.com",
      "substitution": "marketing_acount"
    },
    {
      "match": "PRINCIPAL",
      "pattern": "([^/]+)/(.+)@company.com",
      "case": "UPPER",
      "substitution": "$2_1"
    }
  ]
}