User Impersonation
Audience: System Administrators
Content Summary: Some use cases require a trusted service user that has the ability to impersonate Immuta users, such as applications that run queries on behalf of users, but cannot maintain a pool of connections per-user.
This page details how to create an impersonation user.
Impersonation User Creation
Creation of an impersonation user can be done by connecting to the immuta
database of the Query Engine as a superuser and running a simple script.
-
Create a file named
create-impersonation-user.sql
with the contents below. This script will prompt you for a username and password and then create the user and give it the ability to impersonate Immuta users.\prompt 'Impersonation username: ' username CREATE USER :username; \password :username ALTER ROLE :username SET search_path=immuta,public; GRANT bodata_impersonate_user TO :username;
-
Steps for connecting to the
immuta
database of the Query Engine depend on the type of Immuta installation you are working with. Choose the tab below corresponding to your Immuta deployment to get connected and run thecreate-impersonation-user.sql
script.namespace="immuta" podname=$(kubectl -n "${namespace}" get pod \ -l app=immuta,component=postgres,immuta-database-role=immuta,immuta-ha-postgres-role=master \ -o jsonpath='{.items[0].metadata.name}' ) kubectl -n "${namespace}" cp create-impersonation-user.sql ${podname}:/tmp/ \ -c query-engine -- psql -d immuta kubectl -n "${namespace}" exec -ti ${podname} -c query-engine -- \ psql -d immuta -f /tmp/create-impersonation-user.sql
container=$(docker-compose ps -q db) docker cp create-impersonation-user.sql ${container}:/tmp/ docker-compose exec db psql -d immuta -f /tmp/create-impersonation-user.sql
# This assumes you are logged in as root. Adjust accordingly if you have other # privilege escalation mechanisims in place. cp create-impersonation-user.sql /var/lib/pgsql/ su - postgres psql -d immuta -f create-impersonation-user.sql
The impersonation user does not have access to data without a user's Immuta token; however, it should be stored securely as any other password.
Impersonating Users
The basic flow when impersonating users includes these steps:
- Impersonation user connects to the Immuta Query Engine.
- User authenticates with application managing impersonation user. (See Handling User Authentication for details.)
- In a SQL connection, the impersonation user begins a transaction and sets
a session variable,
bodata.impersonation_token
to the logged in user's Immuta token. - User's queries are executed in the context of this transaction.
- Transaction ends.
Example:
BEGIN;
set local bodata.impersonation_token = '<token>';
-- Execute query as proxied user
END;
user = ""
password = ""
hostport = ""
token = ""
conn = psycopg2.connect("postgresql://{}:{}@{}/immuta?sslmode=require".format(
user, password, hostport))
with conn:
with conn.cursor() as curs:
curs.execute("set local bodata.impersonation_token = '{}'".format(token))
# Execute query as proxied user
# curs.execute('.....')
# print curs.fetchone()
User-based Impersonation (Optional)
- Impersonation user connects to the Immuta Query Engine.
-
In a SQL connection, the impersonation user begins a transaction and sets 2 session variables:
-
bodata.impersonation_userid
to theimmuta userId
of the user to impersonate -
bodata.impersonation_iamid
to the IAM associated with the user being impersonated -
User's queries are executed in the context of this transaction.
- Transaction ends.
Example:
BEGIN;
SET LOCAL bodata.impersonation_userid = 'jdoe@immuta.com';
SET LOCAL bodata.impersonation_iamid = 'LDAP';
-- Execute query as proxied user
END;
user = ""
password = ""
hostport = ""
immuta_user = ""
conn = psycopg2.connect("postgresql://{}:{}@{}/immuta?sslmode=require".format(
user, password, hostport))
with conn:
with conn.cursor() as curs:
curs.execute("SET LOCAL bodata.impersonation_userid = '{}'".format(immuta_user))
curs.execute("SET LOCAL bodata.impersonation_iamid = 'LDAP'")
# Execute query as proxied user
# curs.execute('.....')
# print curs.fetchone()
Handling User Authentication
It is the responsibility of the application using the impersonation user to authenticate users properly and obtain the users' Immuta API tokens.
There are two options for authenticating users:
- The application can use the Immuta API to authenticate users with username and password.
- The application can ask user for Immuta API keys and use these to authenticate users with Immuta.
In both scenarios the token will expire after 1 hour of inactivity. In this
case, activity means any query using impersonation. You can check if the token
has expired by calling the
current user
endpoint with the user's token. If this endpoint returns status code 401
,
then it is expired, and the user must be re-authenticated. This process differs
depending on the chosen option.
Authenticate with Username and Password
-
Users enter their Immuta username and password in the login screen in your application. The authentication endpoint on the back end can pass the username and password to the Immuta authenticate endpoint.
-
The response from the authenticate endpoint contains a short-lived token, which is generally valid for 1 hour from the last activity in the Immuta API.
Note: This endpoint contains a parameter,
iamid
, which corresponds to the IAM system the user selects when logging into Immuta. If possible, you should use a single IAM system, such as a corporate LDAP server. -
The token returned in the authenticate response is used to make calls on behalf of the user through the impersonation user's SQL connection.
Since the Immuta tokens expire after 1 hour of inactivity, you may want to cache them in the user's session. If the token expires, you will need to prompt the user for their username and password and authenticate them against the Immuta API.
Authenticate with Immuta API Key
In this workflow your application must have the ability to associate Immuta API keys with a user account, most likely through a page in your application.
-
The user first needs to generate an API key in the Immuta UI on their profile page. See Generate API Keys for details.
-
When the application needs to obtain an Immuta token, it can use the API key with the authentication endpoint. The response from the authenticate endpoint contains a short-lived token, which is generally valid for 1 hour from the last activity in the Immuta API.
-
The token returned in the authenticate response is used to make calls on behalf of the user through the impersonation user's SQL connection.
Since the Immuta tokens expire after 1 hour of inactivity, you may want to cache them in the user's session. If the token expires, you can authenticate on behalf of the user with their API key.