How to use row level security in Superset UI - apache-superset

I am using the newest version of superset and it has the row-level security option in the UI. Can anyone help me and let me know or give a little walk through that how can I implement it in the UI and use it. There is hardly much documentation there.

Row level security essentially works like a WHERE clause. Let's assume that we build a dashboard using table called tbl_org that look likes:
manager_name department agent
Jim Sales Agent 1
Jim Sales Agent 2
Jack HR Agent 3
Jack HR Agent 4
Say, we need to show Jim only the rows/records where he is a manager on the dashboard when he logs in. The same for Jack. This is when RLS is useful.
The Superset UI provides three fields that need to be filled.
Table: The table on which we want to apply RLS. In this case would be tbl_org
Roles: The role or roles to which you want this rule to apply to. Let's say we use the Gamma role.
Clause: The SQL condition. The condition provided here gets applied to the where clause when the query is executed to fetch data for the dashboard. So for example, if you use the condition manager_name = Jim this will result in the query: SELECT * from tbl_org where manager_name = Jim
If you want dynamically filter the table based on the user who logs in you can use a jinja template:
manager_name = '{{current_username()}}'
For this, the usernames created in Superset need to match the manager_name column in tbl_org

if you want [manager_name = '{{current_username()}}'] make sense,
you have to add ["ENABLE_TEMPLATE_PROCESSING": True] in the config.py.

Row Level Security (RLS) allows an admin to force a WHERE predicate into the query SQL statement that is sent to the DB on the user's behalf.
This can be used to limit the query results to rows that explicitly meet or do not meet specific criteria, and as such, cause the list or rows returned to the user to be filtered. The criteria can be applied based on the target table(s) and user role(s).

Related

How to apply Row Level Security in below scenario in power bi?

I am importing insurance data (view - having global data ) from Amazon redshift through ODBC connection. I want to apply RLS based on country and contract signed date ( for each country, contract signed date is different.)
Report is published in workspace (new workspace type with premium licence applied)
Requirement is to create role for each country and create one role as a global where we will see the data for all country after particular date(date column is available in view)
I want to assign 2 roles to single user.
For ex. XYZ person want to see global data as well as Australia's data.
Can you tell me what will be the output for this?
Is it possible to apply Row Level Security in above scenario ?
I think, there is no need to create two role for single user.
If you give user to global role then user can view global data and even he can filter for Australia's data. If you are putting country filter in the reports.

Dynamic Row Level Security for Power BI

I would like to allow users privileges by region with PBI DAX expression implementation to first get USERPRINCIPALNAME then proceed to get their region.
User Table:
Scenario:
When Shaun login to powerBI service. He only can view the dashboard and dataset in region R10.
If you have multiple tables you want to control with dynamic security, you might prefer an approach based on the propagation of the security filters through the relationships instead of using a DAX expression for every table you want to filter.
What we have to do is to create a new role and use this code to apply security filter for the user table :
[EMAIL]= USERPRINCIPALNAME()
The second thing to do is to apply bi-directionnal filtering for the relationship betwen user_region and region.

How to provide permission to the user to access only one column in the created Microsoft Lists?

Am new to Microsoft Lists and trying to implement the library management system. Have prepared a list to show the book details using the 'From Excel' list. Need to restrict the permission based on the user role(admin, client).
For example, If a user needs to request a book, there might be a column to access for the user to send a request for the desired book. So that, an admin will get notified for the request and take action.
Similarly, from the list i created, i need to provide permission to the user to access only one column. The rest of the column can only be for view purposes.
Note: As i searched i found we can set permission like view, view, and edit, and stop sharing the list based on the roles of Members, Owners, and Visitors.
Could anyone please guide me on this?
Regards,
Vadivel
#Karthi,
It's not possible to configure column permission, the least permission is item-level. There is no column-level or view level permission.
Here are 2 possible solutions:
Make the target column read-only. Then develop another interface for the administrator to manage the data. For example, through SharePoint rest API, we can turn the column back to editable and post updates then immediately turn it to read-only.
Check Set List Column Read Only in SharePoint using PowerShell
How to update read only field
Hide the target column and make a calculated column then set its value equal to the target column. The user will only see those calculated columns, any updates on the target column will be reflected in calculated columns.
Check Make SharePoint Columns read-only without coding

Using RLS with Analysis Service Live Connection in a PBIE "App Owns Data" scenario

I'm kind of new to PBI and I'm looking if it's the right tool for my case.
I would like to use Power BI Embedded in a web application for our customer (where they're logged in) which do not have any Power BI account/licence.
The database on which the reports are based are on-premise so we're would use Analysis Service Live Connection to access them.
Each customer should have his own report.
Is it possible to use RLS in that case?
Does that mean we've to create a role for each of them?
What username should be given in the EffectiveIdentity? Is it 'free text' that is used by PBI to get the username in the DAX?
If each customer will have his own report, then why do you need RLS at all? Just make the report to show what the user is supposed to see. Or you want to have a single report (or set of reports), which is shared between the users and they should see only their data? I will assume it is the later one.
I will start with the last question - the effective identity is not a "free text". It must be a valid user name, having rights to access the data, as specified in the documentation:
The effective identity that is provided for the username property must be a Windows user with permissions on the Analysis Services server.
The you can define RLS in your Analysis Service model, by adding a "users security" table, where you specify which rows should be visible to each user. Define relationships between this users security table and other tables in the model, and then let RLS to filter the data in the security table. The relationships with the rest of the model will apply cascade filtering on the data, so only relevant rows will be visible to the user. See Implement row-level security in an Analysis Services tabular model for example.
So the answer of your second question is no, you don't need a separate role for each user, because the filtering is based on the username and for every user it filters the same thing the same way.

How to apply dynamic Row level Security based on Username and location?

This is related to Row-level security in Power BI. Here is a dummy table on which I want to implement this RLS.
The RLS formula I am using right now is -
[location] = LOOKUPVALUE([location],[login],USERPRINCIPALNAME())
My end requirement is to make this RLS work on the case where if a user logs in he should see the data if the location he is in and also should see other users who are in the same location.
But lookup is throwing an error:
A table of multiple values was supplied where a single value was expected
Also, a single user can have access to multiple location and a single location could have multiple users.
How I can achieve this level of Row-level security using either Lookup or using any other possible way?
Your requirement can also be done through this way, you need to work on both the Power BI desktop and app server to get this right.
In Desktop
Power BI Desktop allows you to create Roles.Click on Manage Roles
and then click on Create New Role.
You would need to create Roles based on the Location here.
For Example Create a rule Called as Location A and click on the
table and give the formula to filters on that table. For example,
[Location] = "A".
So, you can create 'n' number of roles like this and then publish the dashboard.
App.PowerBI.Com
Now, Open app.powerbi.com and then go to the corresponding dataset and
right click on it, select security - you will find the groups there.
On the Groups, enter the emailid's that should have access to it.
You can add a person in multiple groups, that will allow them to see
more than one group.
Testing
Desktop allows you to test it as well - you can click on view as
roles, to see what the user in that group sees.
Also to remember, only people who have access to the dashboard will be able to see the data inside it. So, you will need to share it with them and as well as need to add them inside the groups. If you fail to do one of it, then they won't see anything on the dashboard.
Most efficient Method
This is a better method and I think this is the one you are asking for,
[login] = username()
The function username() automatically gets the email address of the user that is logged in.
Create the above mentioned filter on the new role in the required table.
This way, you would still be adding those 50000 users manually inside the roles under the security section of the corresponding dataset.
But If they all belong to a particular group in an organization, and your Office-365 team has configured your back-end in the right way, then you will only need to enter the group.
But most companies don't have this configuration on their back-end as it is very difficult to control the data security.
Change the Data Model
To do your requirement, you also need to change your data model.
You will need to have two tables initially.
The Value Table - You can have many columns like name and all in there, but it doesn't matter.
The Email Address Table For Location as your second table.
Now Merge the Locations from Value Table to Email Address Table and that will be your final Table. Use this for visualizations but please be very clear on DAX - as you may have duplicate rows and different values.
Now Create RLS on this Table. It should work.
As the name goes, Row Level Security is applied on each rows. So, the formula will be evaluated for each row individually. So, your only option is to have a flat table with all the values.
I answered a question very similar to this one on another page. I will copy it here because I added a bit for the lookup function.
Embedded Power BI: Add Multiple Users in Row Level Security and assign different roles
If you have more than one data to filter against in a role, pass the list as a string path to RLS, parse it into a table, then return the row when it matches with a value in the column.
We do this if we are not actually passing username, but for cases like multiple sales offices, or making a view that compares data from multiple user accounts, or when a user belongs to different hierarchies in an organization, or basically any time you want to use multiple filters..
example input using sales ids
//Username() = "020104010|020104061|020104303|020104304"
//DAX
var userIds = Username()
VAR tbl=
GENERATE (
GENERATESERIES(1,PATHLENGTH(UserIds),1),
ROW ( "Key", PATHITEM ( userIds, [value]))
)
VAR valueList =
SELECTCOLUMNS ( tbl, "Key", [Key] )
return [sales_id_column] in valueList
If you need to add lookup functions, you can apply it when the ROW() statement is called.. it will look like this:
VAR tbl=
GENERATE (
GENERATESERIES(1,PATHLENGTH(UserIds),1),
VAR CurrentKey = [Value]
RETURN
ROW ( "Key", LOOKUPVALUE(Table[c1],Table[c2], PATHITEM ( userIds, CurrentKey )))
)
There is also a case when the table has a many to many relationship and cannot use multiple roles as identity. Or for this case specifically when you only want to use one role to filter many tables. In that case the username looks like this:
Username() = "Username:Bob|Location:A|Location:C"
The code will have an extra step to parse the inner path after you change the ":" to a "|". Then use a if conditional to check if the current table filters for this role. This approach supports a claims-based authorization where only one role needs to be created in RLS and everything can be done client-application side.
runtime is O(k(n log m)) where m is the number of claims you have applying RLS in the current table, n is the number of rows in the table, and k is the number of tables you are applying RLS on