**UPDATE** You can now, as of Summer ’17, use Salesforce Sharing Inheritance to accomplish this. If you’re using External Data Sources or need different security, this works great. https://help.salesforce.com/articleView?id=bi_security_datasets_sharing_getting_started.htm&language=en_US&type=0
I’ve worked on many projects where one of the main goals of the Community implementation is to display Wave Analytics to their Community Users. If you’re familiar with security inside of Wave, you might have seen some of the common examples available in the documentation. Unfortunately, these don’t work well when you’re wanting to implement it for a Community. In addition, the way you implement a Security Predicate has changed since first releasing, and the documentation sometimes varies for how you would go about doing this. This post is going to walk you through how you can setup a Security Predicate and master your Communities Wave deployment!
Business Case
We’re implementing a Customer Community that wants to see Case metrics. You want the Dataset to be dynamic based on the Running User, and allow them to only see their Account’s data. This would allow us to use the same Dataset and Dashboard for all of our customers.
That means being able to control the access of the data at the record (row) level. Just as you currently do with Sharing Rules in your Org as an Admin today. This would look like:
Admin View
Community User View
If you’re new to Wave Analytics, you might be confused why Wave doesn’t do this natively. The reason is because Wave Analytics is connected via an Integration User. That Integration User is typically going to be an Admin Level Read-Only User. When we access Wave, we’re accessing the dataset from the credentials of our Integration User. That means, to enforce Row-Level Security, we have to put our Security Predicate inside every Dataset we need to secure.
Alright, let’s get into the how this is done.
To start off, we need to know what our Root is. In this case, pun intended, we’re going to be using the Case Object as our Root. The Root is what record you want returned. Since we’ve already got the Account ID field native to the Case Object, all we need to do is add a custom Text Formula Field called View All Data, and make the value “View All Data”
On the User Object, we need to have a Formula Field that returns the same value when it is an Internal User. To keep it simple, I’m just granting all Internal Users View All Data privileges. If you wanted to make this more complicated, you can easily expand on this.
Looking into our Dataset’s JSON, you can see we’ve got the AccountId and ViewAllData__c pulled in. If you don’t bring in the fields you want to reference in your Security Predicate, it won’t work.
Based on everything above, what we’re looking to have as our Security Predicate is:
‘AccountId’ == “$User.AccountId” || ‘ViewAllData__c’ == “$User.ViewAllData__c”
‘AccountId’ == “$User.AccountId” is how we are adding in the Community User’s dynamic filter. All Cases where the AccountId matches the Community User’s AccountId will be shown. Keep in mind, you could get creative and use formula fields here if you wanted it to work for an Account Hierarchy instead of just one Account.
|| yes, we can use operators like OR in this, which gives you control to get creative with your sharing.
‘ViewAllData__c’ == “$User.ViewAllData__c” this is how we grant access to all Internal Users. Because, all of the Internal Users will have “View All Data” populated on their User, and all Cases have “View All Data” filled out as well.
Previously, we’d have to download this JSON, and modify the sfdcRegister (103) and include our row-level security predicate there. Now, we just need to navigate to our Dataset in Wave. Note – if you attempt to add your security predicate in it the old way, it won’t work and you’ll be left scratching your head.
Once you’re to your Dataset, select Edit.
Insert the Security Predicate
Select Update Dataset. The next time your Dataflow runs it will update with your Security Predicate. Just like that… you’re all set! You’ve mastered row-level security in Wave.
Why can’t we simply use rowLevelSharingSource
LikeLike
Praneel, I’ve made an update to the top to post that knowledge article. This is a new feature that was not out when I posted this blog post.
LikeLike