Implement row-level entry management in a multi-tenant surroundings with Amazon Redshift


This can be a visitor publish co-written with Siva Bangaru and Leon Liu from ADP.

ADP helps organizations of every kind and sizes by offering human capital administration (HCM) options that unite HR, payroll, expertise, time, tax, and advantages administration. ADP is a pacesetter in enterprise outsourcing companies, analytics, and compliance experience. ADP’s unmatched expertise, deep insights, and cutting-edge expertise have reworked human sources from a back-office administrative operate to a strategic enterprise benefit.

Folks Analytics powered by ADP DataCloud is an software that gives analytics and enhanced insights to ADP’s purchasers. It delivers a guided analytics expertise that make it straightforward so that you can create, use, and distribute tailor-made analytics on your group. ADP Folks Analytics’s streamlined, configurable dashboards might help you determine potential points in key areas, like additional time, turnover, compensation, and way more.

ADP offers this analytics expertise to 1000’s of purchasers as we speak. Securing clients’ knowledge is a prime precedence for ADP. The corporate requires the best safety requirements when implementing a multi-tenant analytics platform on Amazon Redshift.

ADP DataCloud integrates with Amazon Redshift row-level safety (RLS) to implement granular knowledge entitlements and implement the entry restrictions on their tables in Amazon Redshift.

On this publish, we talk about how the ADP DataCloud staff applied Amazon Redshift RLS on the inspiration of role-based entry management (RBAC) to simplify managing privileges required in a multi-tenant surroundings, and likewise enabled and enforced entry to granular knowledge entitlements in enterprise phrases.

The ADP DataCloud staff had the next key necessities and challenges:

  • Help a multi-tenant software to implement a logical separation of every tenant’s knowledge rows
  • Help dynamic provisioning of latest tenants
  • Minimal affect on efficiency

Row-level safety in Amazon Redshift

Amazon Redshift is a completely managed, petabyte-scale knowledge warehouse service within the cloud. One of many challenges with safety is that enterprises need to present fine-grained entry management on the row degree for delicate knowledge. This may be performed by creating views or utilizing completely different databases and schemas for various customers. Nonetheless, this method isn’t scalable and turns into complicated to take care of over time, particularly when supporting multi-tenant environments.

In early 2022, Amazon Redshift launched row-level safety, which is constructed on the inspiration of role-based entry management. RLS lets you management which customers or roles can entry particular data of information inside tables, based mostly on safety insurance policies which can be outlined on the database object degree. This new RLS functionality in Amazon Redshift allows you to dynamically filter present rows of information in a desk together with session context variable setting capabilities to dynamically assign the suitable tenant configuration. That is along with column-level entry management, the place you may grant customers permissions to a subset of columns. Now you may mix column-level entry management with RLS insurance policies to additional prohibit entry to explicit rows of seen columns. Confer with Obtain fine-grained knowledge safety with row-level entry management in Amazon Redshift for added particulars.

Resolution overview

As a part of ADP’s key necessities to help a multi-tenant knowledge retailer whereby a single desk holds knowledge of a number of tenants, enforcement of safety insurance policies to make sure no cross-tenant knowledge entry is of paramount significance. One apparent manner to make sure that is by creating database customers for every tenant and implementing RLS insurance policies to filter a single tenant’s knowledge as per the logged-in person. However this may be tedious and turn out to be cumbersome to take care of because the variety of tenants develop by the 1000’s.

This publish presents one other option to deal with this use case by combining session context variables and RLS insurance policies on tables to filter a single tenant’s knowledge, thereby easing the burden of making and sustaining 1000’s of database customers. In truth, a single database person is all that’s wanted to attach and question completely different tenant’s knowledge in numerous classes from a multi-tenant desk by setting completely different values to a session context variable in every session, as proven within the following diagram.

Let’s begin by overlaying the high-level implementation steps. Think about there’s a database person in Amazon Redshift app_user (which is neither an excellent person, nor has the sys:secadmin function granted, nor has the IGNORE RLS system privilege granted by way of one other function). The person app_user owns a schema with the identical title and all objects in it. The next is a typical multi-tenant desk worker within the app_user schema with some pattern data proven within the desk:

CREATE TABLE app_user.worker (
    tenant_id varchar(50) not null,
    id varchar(50) not null,
    title varchar(200),
    electronic mail varchar(200),
    ssn char(9),
    constraint employee_pkey major key (tenant_id,id)	


To implement that, the next steps are required:

  1. Create a RLS coverage on a column utilizing a predicate that’s set utilizing a session context variable.
  2. Allow RLS on the desk degree and connect the RLS coverage on the desk.
  3. Create a saved process that units the session context variable used within the RLS coverage predicate.
  4. Join and name the saved process to set the session context variable and question the desk.

Now RLS will be enabled on this desk in such a manner that at any time when app_user queries the worker desk, the person will both see no rows or retrieve solely rows particular to single tenant regardless of being the proprietor of the desk.

An administrator, similar to app_admin, both an excellent person or a person that has the sys:secadmin function, can implement this as follows:

  1. Create a RLS coverage that attaches a tenant_id predicate utilizing a session context variable:
    create rls coverage tenant_policy
    with (tenant_id varchar(50))
    utilizing (tenant_id = current_setting('app_context.tenant_id'));

  2. Allow RLS and connect the coverage on the worker desk:
    alter desk app_user.worker row degree safety on;
    connect rls coverage tenant_policy on app_user.worker to public;

  3. Create a saved process to set the tenant_id in a session variable and grant entry to app_user:
    create or substitute process app_admin.set_app_context
    (p_tenant_id in varchar)
    	language plpgsql
    as $$ 	
    		v_tenant_id  varchar(50);
        reset all;   
    	v_tenant_id := set_config('app_context.tenant_id',p_tenant_id,false);	
    grant execute on app_admin. set_app_context(varchar) to app_user;

  4. Hook up with app_user and name the saved process to set the session context variable:
    name app_admin.set_app_context('T0001');

When this setup is full, at any time when tenants are connecting to ADP Analytics dashboards, it connects as app_user and runs saved procedures by passing tenant_id, which units the session context variable utilizing the tenant ID. On this case, when requests come to attach and question the worker desk, the person will expertise the next situations:

  • No knowledge is retrieved if current_setting('app_context.tenant_id') isn’t set or is null
  • Knowledge is retrieved if current_setting('app_context.tenant_id') is ready by calling the app_admin.set_app_context(varchar) process to a worth that exists within the worker desk (for instance, app_admin.set_app_context(‘T0001’))

No knowledge is retrieved if current_setting('app_context.tenant_id') is ready to a worth that doesn’t exist within the worker desk (for instance, app_admin.set_app_context(‘T9999’))

Validate RLS by analyzing question plans

Now let’s evaluation the previous situations by working an clarify plan and observing how RLS works for the check setup. If a question incorporates a desk that’s topic to RLS insurance policies, EXPLAIN shows a particular RLS SecureScan node. Amazon Redshift additionally logs the identical node kind to the STL_EXPLAIN system desk. EXPLAIN doesn’t reveal the RLS predicate that applies to the worker desk. To view an clarify plan with RLS predicate particulars, the EXPLAIN RLS system privilege is granted to app_user by way of a task.

On this first state of affairs, tenant_id wasn’t set by the saved process and was handed as a null worth, due to this fact beneath choose assertion returns no rows .

=> choose depend(1),tenant_id from worker group by 2;

depend | tenant_id


(0 rows)

Clarify plan output exhibits the filter as NULL:

=> clarify choose depend(1),tenant_id from worker group by 2;



XN HashAggregate (price=0.10..0.11 rows=4 width=20)

-> XN RLS SecureScan worker (price=0.00..0.08 rows=4 width=20)

-> XN End result (price=0.00..0.04 rows=4 width=20)

One-Time Filter: NULL::boolean

-> XN Seq Scan on worker (price=0.00..0.04 rows=4 width=20)

(5 rows)

Within the second state of affairs, tenant_id was set by the saved process and handed as a worth of T0001, due to this fact returning solely corresponding rows as proven within the clarify plan output:

Name saved process to set the session context variable as ‘T0001’ after which run the choose :

=> name app_admin.set_app_context('T0001');

=> choose depend(1),tenant_id from worker group by 2;
 depend |   tenant_id
     3 | T0001
(1 row)

Clarify plan output exhibits the filter on tenant_id as ‘T0001’

=> clarify choose depend(1),tenant_id from worker group by 2;
                                QUERY PLAN
 XN HashAggregate  (price=0.07..0.07 rows=1 width=20)
   ->  XN RLS SecureScan worker  (price=0.00..0.06 rows=1 width=20)
         ->  XN Seq Scan on worker  (price=0.00..0.05 rows=1 width=20)
               Filter: ((tenant_id)::textual content="T0001"::textual content)
(4 rows)

Within the third state of affairs, a non-existing tenant_id was set by the saved process, due to this fact returning no rows:

=> name app_admin.set_app_context('T9999');

=> choose depend(1),tenant_id from worker group by 2;
 depend | tenant_id
(0 rows)

=> clarify choose depend(1),tenant_id from worker group by 2;
                                QUERY PLAN
 XN HashAggregate  (price=0.07..0.07 rows=1 width=20)
   ->  XN RLS SecureScan worker  (price=0.00..0.06 rows=1 width=20)
         ->  XN Seq Scan on worker  (price=0.00..0.05 rows=1 width=20)
               Filter: ((tenant_id)::textual content="T9999"::textual content)
(4 rows)

One other key level is that you may apply the identical coverage to a number of tables so long as they’ve the column (tenant_id varchar(50)) outlined with the identical knowledge kind, as a result of RLS polices are strongly typed in Amazon Redshift. Equally, you may mix a number of RLS insurance policies outlined utilizing completely different session context variables or different related column predicates and connect them to a single desk.

Additionally, this RLS implementation doesn’t want any adjustments when a brand new tenant’s knowledge is added to the desk, as a result of it may be queried by merely setting the brand new tenant’s identifier within the session context variable that’s used to outline the filter predicate contained in the RLS coverage. A tenant to its corresponding identifier mapping is usually performed throughout an software’s tenant onboarding course of and is mostly maintained in a separate metastore, which can also be referred to throughout every tenant’s login to get the tenant’s identifier. With that, 1000’s of tenants may very well be provisioned without having to vary any coverage in Amazon Redshift. In our testing, we discovered no efficiency affect by tenants after RLS was applied.


On this publish, we demonstrated how the ADP DataCloud staff applied row-level safety in a multi-tenant surroundings for 1000’s of consumers utilizing Amazon Redshift RLS and session context variables. For extra details about RLS finest practices, check with Amazon Redshift safety overview.

Check out RLS on your future Amazon Redshift implementations, and be happy to go away a remark about your use circumstances and expertise.

In regards to the authors

Siva Bangaru is a Database Architect at ADP. He has greater than 13 years of expertise with technical experience on design, growth, administration, and efficiency tuning of database options for quite a lot of OLAP and OLTP use circumstances on a number of database engines like Oracle, Amazon Aurora PostgreSQL, and Amazon Redshift.

Leon Liu is a Chief Architect at ADP. He has over 20 years of expertise with enterprise software framework, structure, knowledge warehouses, and large knowledge real-time processing.

Neha Daudani is a Options Architect at AWS. She has 15 years of expertise within the knowledge and analytics house. She has enabled purchasers on numerous tasks on enterprise knowledge warehouses, knowledge governance, knowledge visualization, grasp knowledge administration, knowledge modeling, and knowledge migration for purchasers to make use of enterprise intelligence and analytics in enterprise development and operational effectivity.

Rohit Bansal is an Analytics Specialist Options Architect at AWS. He makes a speciality of Amazon Redshift and works with clients to construct next-generation analytics options utilizing different AWS Analytics companies.


Please enter your comment!
Please enter your name here