Back to Index

Arch-core-banner.png

Salesforce Wave Security Best Practices

Authors: Tomasz Bacewicz, Umair Rauf - Analytics Cloud ASG #AsktheACExperts


Overview

Salesforce understands that the confidentiality, integrity, and availability of our customers' information are vital to their business operations and our own success. Our Customer Success platform has security at the foundation of the service. This foundation includes both protection for your data and applications, while providing flexibility to implement your own security scheme to reflect the structure and needs of your organization.

Wave Analytics leverages some of these foundational security components from Salesforce and enables Wave specific access control options to protect access to your data and applications.

  1. Authentication and Access: The Salesforce Administrator uses Wave Analytics feature licenses and permission sets to enable users to access Wave. There are two standard license types i.e. Wave Explorer and Wave Builders. You can create logical naming for any users using the Builder license based on their responsibility e.g. a user who is assigned a Builder license and all Wave permission sets may be called a Wave admin; a user with Builder license and permissions to create dashboards only could be your Wave advanced analyst, etc.
  2. Application Security: Administrators and/or application owners can restrict access to their respective applications. This ensures that only authorized users can access the datasets, lenses and dashboards contained within an application. Data owners can also use Applications to restrict access to related set of datasets, lenses and dashboards geared for specific audiences (these are essentially the ACLs of Wave Analytics objects). The application access can be assigned to an individual user, all users in a specific role or all users in a public group.
  3. Data Security: Data security can be implemented at multiple levels:
    1. Salesforce object-level security and Salesforce field-level security can help you control what gets ingested into Wave from Salesforce core objects.
    2. Wave dataset row-level security can be enforced using security predicate filters, which limit the results within a dataset explicitly to data which the user is authorized to access based on the predicate rule. The Wave predicate filters can help enforce ownership based, role-based, team-based and/or other custom security policies.
    3. Salesforce Partners are building Wave end-points, which will allow encrypted data transfer to Wave.

The document provides implementation details for these security tiers, relating them to customer specific use-cases. This document assumes prior knowledge of Salesforce foundational security components including physical, network and application-level security controls around Salesforce Customer Success platform.


References

The Wave product documentation including detailed security implementation reference is available at the following link.


Planning the Security Implementation

Some of the key questions you should ask while planning your access control strategy for Wave Analytics include:

  1. Which group of users will interact with Wave?
  2. Which applications and analytics content will they access?
  3. What activities will they perform in their primary roles?
  4. Any specific classes of user (e.g. sales ops etc.) outside the standard security model who require broad access?
  5. What is the span of access to data for each class of user?
  6. Does the data have the required dimensional attributes, needed to implement access controls on data?
  7. Is all security enforcement data internal to the Salesforce platform or is there a requirement to include externally available hierarchy data to enforce security policy?

The Wave platform enables rapid data ingestion, transformation and analysis to help reduce the time to actionable insights. To ensure that cross-functional data are secure and accessible to authorized users; it is important to deploy a well crafted security model.


You have to plan security implementation at differents phases of your analytics implementation:

While Enabling Wave Analytics

While Building Applications


While Uploading and Registering new Datasets

Plan user access for Wave Analytics by assigning licenses and permission sets to appropriate user classes

  • Implement permission sets for various user classes
  • Assign explorer and builder permission set licenses

Provide access to Applications containing datasets, lenses and dashboards for authorized users.

  • Provide Application level access to users based on their primary engagement i.e. Viewer, Editor or Manager.

Apply data security controls at two levels


  • For Salesforce data, you have to make sure that Wave Analytics ‘Integration User Profile’ has access to objects and fields specifically or including custom objects and fields
  • User Profiles can be used to manage objects, that a user can access. Overall access to extract objects and fields into Wave can be controlled by the access of the Integration User Profile.
  • field-level security provides visibility to fields within an object
  • For any data, you can apply security predicate permissions to allow user access to records he/she has authorization for based on myriad predicate conditions.

Permissions: You will need Salesforce platform administrative privileges with “Manage Profiles and Permission Sets” and “Assign Permission Sets” to perform these tasks


Permissions: You will need ‘Manager’ access on the specific Wave Application along with ‘Create Wave Analytics Apps’. You can also perform this function if you are already the owner of a wave application or you have ‘Manage Wave Analytics’ permission-sets.


Permissions: Administrative access with ‘Manage Profiles and Permission Sets’ and optionally ‘Edit Read Only Fields’ to manipulate object and field-level security settings; ‘Edit Wave Analytics Dataflow’ and ’Upload External Data to Wave Analytics’ permissions to manipulate security predicate for dataset.



Managing your User Access to Wave Analytics

The Wave platform can have multiple types of users. This includes administrators, developers and/or consumers of analytics. The consumers can also be further divided into power users vs. general consumers of published content.


It is important to think through the various user classes, and assign appropriate permissions to these users. You should also factor in specific application needs, whereby some users may have broader access on one application while restrictive access on another.


You can organize users in the following configuration


Flexible Security Model

Basic Tiered Security Model

Multi-Tiered Security Model

  • Wave Developers
  • Wave End-User
  • Wave Administrators
  • Wave Developers
  • Wave End-User
  • Wave Platform Administrator
  • Wave Developers
  • Wave Advanced Analysts
  • Wave End-User

Most flexible in a sandbox environment where two classes of permissions can help address broad implementation needs. This ensures most flexibility for developers and power users who would typically get the Builder permissions to manage the application


Consider assigning standard Wave permissions to these levels per product documentation

Best suited for a QA Sandbox where multiple projects or use-cases are being implemented in parallel, where a separate administrator role can help ensure clean application space among stakeholders

Targeted for Multiple-Wave project/ use-case scenarios where each team may need builder freedom within their Application while centralization may be warranted for Application Creation, and Data Flow among teams.


Also consider for more Enterprise production deployments where it is required to have tiered permissions to provide flexibility among business teams while ensuring a clean production state for end-users.


While the permission assignments are flexible to implement, here is a recommended set of system permissions for organizing a multi-tiered security permission set,

Users Class (Role)

Purpose

Wave License Type

Advocated Permission sets

Wave Platform Administrator


Manages overall administration around Wave Analytics for an Org. This role may also serve as custodian of the common Wave dataflow in production. Also ensures high-level access and application organization within Wave. It is recommended to have the security predicate setup and dataflow be managed by the admin.


Analytics Cloud - Builder License


Optional: Sales Analytics Apps

  • Create and Edit Wave Analytics Dashboards
  • Create Wave Analytics Apps
  • Edit Wave Analytics Dataflows
  • Manage Wave Analytics
  • Upload External Data to Wave Analytics
  • Use Wave Analytics

For customers with Sales Analytics App license:

  • Manage Wave Analytics Templated Apps
  • Access Sales Cloud Analytics Templates and Apps
  • Use Wave Analytics Templated Apps

Wave Advanced Designer (or Developer)

This person works on specific use-cases to build datasets, lenses and dashboards. In a basic model, this could be your Salesforce Business Analyst, BI Developer, Business Power Analysts.

Analytics Cloud - Builder License


Optional: Sales Analytics Apps

  • Create and Edit Wave Analytics Dashboards
  • Edit Wave Analytics Dataflows
  • Upload External Data to Wave Analytics
  • Use Wave Analytics

For customers with Sales Analytics App license:

  • Access Sales Cloud Analytics Templates and Apps
  • Use Wave Analytics Templated Apps

Wave Advanced Analyst


Develop lenses and dashboards with access to specific Applications. May load external data for analysis but cannot modify the dataflow


Analytics Cloud - Builder License


Optional: Sales Analytics Apps


  • Create and Edit Wave Analytics Dashboards
  • Upload External Data to Wave Analytics
  • Use Wave Analytics

For customers with Sales Analytics App license:

  • Access Sales Cloud Analytics Templates and Apps
  • Use Wave Analytics Templated Apps

Wave End-user


Primarily consumes pre-built dashboards, perform ad-hoc exploration and where needed, saves lenses to private applications


Analytics Cloud - Builder License


Optional: Sales Analytics Apps


  • Upload External Data to Wave Analytics
  • Use Wave Analytics

For customers with Sales Analytics App license:

  • Access Sales Cloud Analytics Templates and Apps
  • Use Wave Analytics Templated Apps

Mass Assigning Permissions to Users

You can mass assign a particular permission set to a broad range of users through the following methods.


Using Salesforce Setup Screens

A Salesforce administrator with ‘Manage User’ permission can use the Permission-set assignment functionality to assign a permission set to a single or multiple users. To perform mass assignment:


  1. From Setup, click Manage Users | Permission Sets.
  2. Select a permission set.
  3. In the permission set toolbar, click Manage Assignments.
  4. Click Add Assignments. If any users are selected, this button isn’t available.
  5. Select the users to assign to this permission set. You can assign up to 1000 users at a time. You can view the selected list view, select another list view, or to narrow the list of users using a different filter criteria, create a new list view.
  6. Click Assign.
  7. Review the messages on the Assignment Summary page. If any users weren’t assigned, the message column will list the reasons on why the operation could not be performed.
  8. To return to a list of all users assigned to the permission set, click Done.

Using sObject API

The sObject API allows you to perform activities which are not exposed through the permission set UIs. The easiest way to leverage the API without writing any code is through Salesforce workbench at Workbench. This is performed by inserting PermissionSetAssignment records.


You should have a list of Users and their permission set in a comma-separated CSV and follow these instructions:


  1. Select “Insert” from the “Data” menu at the top of your browser window.
  2. Select PermissionSetAssignment from the ObjectType menu
  3. Select the “From File” radio button and choose your CSV-formatted spreadsheet.
  4. Click “Next”
  5. Map the columns from your spreadsheet as appropriate.
  6. Click “Map Fields”
  7. Choose whether you wish to process the request asynchronously
  8. Click “Confirm Insert”

To remove permissions, you need to delete records from the PermissionSetAssignment object.


Tip: To access all users assigned to a specific role:


SELECT Id, Name
FROM User
WHERE RoleId IN (SELECT Id
FROM Role
WHERE RoleName Like ‘%sales%’)

Planning Application Ownership

Plan the level of permissions for each Salesforce user, Salesforce public group and/or Salesforce user role, that can access an application. For roles, you can also decide if the entire child hierarchy needs access to the application.


Users Class (Role)

Application Permissions

Definitions

Platform Administrator


‘Manager’ access on all applications


Manager:


  • Viewer and Editor Permissions, plus
  • Change the app’s sharing settings
  • Rename the app or delete the app

Editor:


  • Viewer Permission, plus
  • access to Save changes to existing dashboards, lenses, and datasets in the app

Viewer:


  • View dashboards, lenses, and datasets in the app
  • See who has access to the app
  • Save contents of the app to another app that the user has Editor or Manager

Data Flow Editor


‘Editor’ Access


‘Manager’ Access to common dataset Application


Power User and/or BI Developer


‘Editor’ Access


‘Manager’ Access to specific applications


End User


‘Viewer’ Access



To assign access for users, roles or groups, you can click Share for an application and select the appropriate users in the drop-down.


Image02.png


Securing your Data in Wave Analytics

Choosing the data that each user or group of users can see is one of the key decisions that affects data security. You need to find a balance between limiting access to data, thereby limiting risk of unauthorized data use, versus the convenience of data access for your users for analytics.


You can secure your data at multiple levels.

  1. You can restrict the data within Salesforce prior to ingestion in Wave Analytics by leveraging object and field-level security permission.
  2. Once loaded in Wave Analytics, you can apply row-level security rules to limit access for certain class of users.

You can restrict data pulls from Salesforce using the following mechanisms,

  • To allow the objects for which the data can be pulled into Wave Analytics, you can assign visibility permission set to the Wave Analytics Integration user.
  • To specify the fields within an object which can be pulled into Wave Analytics, you can modify field-level security for an object for the Wave Analytics Integration user (Read access is needed for the field, which is required to move into Wave).

Salesforce also provides ability to restrict access to individual records (rows) that users can view and/or edit in Salesforce. In the Salesforce platform, this is accomplished through organization-wide sharing settings, defining a role hierarchy, and creating sharing rules. Once the data is loaded into Wave, the dataset owner or the encapsulating application manager/editor has to take steps to apply row-level security, which is implemented through security predicates. The security could be based on record ownership, management hierarchy or team visibility; among others.


Object Level Security in Salesforce

Object-level security—or object permissions—provide the most explicit way to control data. Using object permissions you can prevent the Integration user from seeing (or for regular Salesforce user) any instance of a particular type of object, such as a lead or opportunity. Object permissions let you hide whole tabs and objects from particular users, so that they don’t even know that type of data exists.


You specify object permissions in permission sets and profiles. Permission sets and profiles are collections of settings and permissions that determine what a user can do in the application.


Profiles are typically defined by a user’s job function (for example, System Administrator or Sales Representative). For providing visibility for the Salesforce Wave Analytics native dataflow to access objects, you have to ensure that Wave Analytics Integration User profile has visibility to the object which is desired to be pulled into Wave Analytics. In addition, the Wave Analytics Security User controls access to any custom fields which can be used when applying a security predicate to a dataset.


You can use profiles to grant access to objects. This can be achieved by editing the profile and provide ‘Read’ access under the ‘Standard Object Permissions’ and ‘Customer Object Permissions’ .


  1. From Setup, click Manage Users | Profiles.
  2. Find the Profile for “Integration User”.
  3. To add people to profile which already has required object permissions
    1. In the profile toolbar, click Manage Assignments.
    2. Click Add Assignments. If any users are selected, this button isn’t available.
    3. Select the users to assign to this profile. You can assign up to 1000 users at a time. You can view the selected list view, select another list view, or to narrow the list of users using a different filter criteria, create a new list view.
  4. Click Assign.
  5. Review the messages on the Assignment Summary page. If any users weren’t assigned, the Message column lists the reasons.
  6. To return to a list of all users assigned to the permission set, click Done.

Note: The Wave Analytics native dataflow currently does not support all Salesforce object types for native ingestion using the Dataset builder. You can reference the detailed list of unsupported objects from the following document. While these objects are provided restricted access for Integration user, you can still use Salesforce Bulk API to export these data objects into a CSV and then load them into Wave using one of the available data ingestion strategies:

  1. Wave Analytics External Data API
  2. Excel Connector
  3. A Partner ETL tool
  4. CSV upload in Wave UI

Field Level Security in Salesforce

When Wave Analytics is enabled in a Salesforce org, by default the Wave Analytics Integration User is provided read access to only standard fields within the Salesforce standard objects. While ingesting data into Wave Analytics, it’s commonly desired to pull data from custom objects and/or custom fields from Standard objects. While allowing this access, you may still restrict sensitive fields e.g. date of birth or margin etc.


Field-level security—or field permissions—control whether a user can see, edit, and delete the value for a particular field on an object. They let you protect sensitive fields without having to hide the whole object from users. Field permissions are also controlled in permission sets and profiles. The Wave Integration user requires read access to these fields.


The field-level security settings can be modified through the Integration user’s profile page.


  1. From Setup, click Manage Users | Profiles.
  2. Find the Profile for Wave Analytics Integration User
  3. On the profile setting screen, search for field-level security.
  4. You can click through the objects to change visibility level of specific fields for the profile. The “Read-Only” option has to be selected for a field to be extracted through the workflow.

Row Level Security in Wave Analytics

When users load data to their Wave Application, all this data will be visible to any user who has access to the application. Salesforce Wave provides security predicates to implement row-level security on a dataset. The predicate acts as a filter based on the defined predicate rule. A builder or admin should plan on applying a predicate to each dataset which is loaded into Wave.


The predicate can flexibly help users implement various business security policies including record ownership, owners management visibility, team visibility, geographic restrictions, and/or a combination.


The fundamental principle around security predicate is to use any standard or custom field within the Salesforce User object and filter records from a dataset by matching the field with a particular dimension in your dataset. A combination predicate will use multiple set of keys with and (&), or ( || ) logic.


In this section we’ll discuss both use-case based security predicate modeling and low-level implementation options on configuring the predicate on a dataset.


Low-Level Implementation Options

There are a few options in applying a security filter to a dataset. These options are listed below:


  1. The simplest way to add a security predicate to a dataset is to edit the dataset in the UI once the dataset is uploaded (Hover over the dataset on the homepage of Wave and click “Edit”, the last text box on the page determines the security predicate). The predicate will persist even as it is overwritten with a new upload or data pull from Salesforce.

Note: When using this option for implementation, make sure to logout and log back into the org to see the security predicate take effect.


Image05.png


2 If uploading an external dataset, the security predicate can be applied upon loading the data using the “rowLevelSecurityFilter” node in the schema file. Double quotes within your security predicate have to be escaped (eg. “'OwnerId' == \"$User.Name\"”).


{
  "fileFormat" : {
    "charsetName" : "UTF-8",
    "fieldsDelimitedBy" : ",",
    "fieldsEnclosedBy" : "\"",
    "linesTerminatedBy" : "\n",
    "numberOfLinesToIgnore" : 1
  },
  "objects" : [ {
    "name" : "Dataset_Name",
    "fullyQualifiedName" : "Dataset_Name",
    "connector" : "SalesforceAnalyticsCloudDatasetLoader",
    "label" : "Dataset_Name",
    "description" : "Dataset_Name",
    "rowLevelSecurityFilter" : "'OwnerId' == \"$User.Id\"",
    "fields" : ....


3 The last option in setting a predicate filter is by specifying it in the register step of a workflow using the "rowLevelSecurityFilter" node in the “parameters” node when the dataset is being registered.

"Register_Dataset": {
        "action": "sfdcRegister",
        "parameters": {
            "alias": "Dataset_Name",
            "name": "Dataset_Name",
            "source": "105_Augment_OpportunityTeamMember_Opportunity",
            "rowLevelSecurityFilter": "'OwnerId' == \"$User.Id\""
        }
    }


The predicate filter can only use fields in the User object. Moreover, the fields which can be used in the predicate are limited to ones which the Security User (with the profile Wave Analytics Security User) can access. Access can be expanded by granting read access to necessary fields for the profile.


High-Level Options

Use Case 1: Record Ownership

The simplest implementation of using the security predicate is based on record ownership e.g. opportunity owner, case owner and/or account owner. Many standard objects such as Opportunity or Account have an Owner ID field already associated with them. This allows for a very simple implementation of a predicate based on ownership by defining it as:

‘OwnerId’ == “$User.Id”

No extra transformations or extracts need to occur besides extracting the object itself for this implementation.


Note: For external data loads, a Salesforce OwnerId may not come through. This may drive workflow augment transformation with Accounts to find an appropriate owner which may become the basis for applying ownership based security. (e.g. ‘Account.OwnerId’ = “$User.Id”) The $User.Id variable will use the 18 digit ID. Therefore, the OwnerId being uploaded should also be in the 18 digit format (not 15).


Use Case 2: Team Based Visibility

Record ownership security could be extended to team based security. The implementation in this case would vary depending on the way that the object in question is structured. The object could either:


  1. Contain fields that already define the users which are on the team (such as a field for AE, SE, CSM, etc for an Opportunity)
  2. Require joins between linked intermediary objects to determine the team involved (such as having to augment between Opportunity and the Account object before pulling in the AE involved on the Opportunity).

To tackle team based security in the first scenario, no data manipulation needs to occur. The object can be pulled as is and then a security predicate can be written to check if the ID of a user matches one of the team fields already included in the object. For example, if the Opportunity object was being pulled with the team IDs of the Sales Engineer (SE__c) and Account Executive (AE__c) already defined within the Opportunity, the security predicate could look something like this:

‘OwnerId’ == “$User.Id” || ‘SE__c’ == “$User.Id” || ‘AE__c’ == “$User.Id”

Now, a user would be able to see the opportunity only if they are the owner, SE, or AE of it.


For the second scenario, Salesforce contains standard objects such as AccountTeamMember and OpportunityTeamMember. These objects can be used to create a multivalued field listing out all the user IDs which have access to a record. Depending on how the org is structured, there is an option to either allow everyone on an account team to see each opportunity associated with that account, or OpportunityTeamMember can be used to have a specific team for each opportunity. Either way, the user IDs of the team members can be made into a multi-valued field by augmenting the TeamMember object onto its corresponding root object (OpportunityTeamMember to Opportunity, AccountTeamMember to Account). An example of the predicate in this case would be (given that the multi-valued team field is named ‘TeamIDs’):

‘TeamIDs’ == “$User.Id”

Therefore, if the user’s ID matches with an ID in the field, the user will be able to see the record.


Use Case 3: Management Visibility

Wave Analytics has functions specifically designed to allow a management visibility security model. This allows the owner to see their respective record as in the first implementation alternative but it also permits all managers above the owner to see the owner’s records as well.


For example, let us consider this management structure below:


Image04.png


If Tony (NJ_Sales) is an owner of a record, a management based security model should allow Bill (East_Sales) as well as Keith (VP_Sales) to see this record within Wave Analytics. On the other hand, if Mary (WA_Sales) owns a record, neither Tony (NJ_Sales) nor Bill (East_Sales) should see the record. Instead, Lucy (West_Sales) and of course Keith (VP_Sales) should be the only other people who can see Mary’s record.


The prerequisites to implement include:


  1. The Salesforce org needs to have a management hierarchy in place; typically this is based on the sales hierarchy but could also be a territory hierarchy or any other hierarchy based management structure
  1. When deciding on using a hierarchy structure for the Wave security model, the object from which the hierarchy is built has to have parent IDs which map the hierarchy out from the lowest to the highest point
  1. An owner User ID on each record so that the hierarchy can be applied from the bottom up on each record
  2. Access to pull all the Users which are owners of each record in the dataset from the Salesforce org into Wave Analytics
  3. Access to pull the object which maps out the hierarchy structure (eg. Role object for sales hierarchy).

For an example in implementation, the Salesforce opportunity object will be pulled (via standard dataflow) to create a Wave Analytics dataset and then the sales hierarchy will be applied as the management hierarchy security model on the opportunity dataset. The implementation steps are as follows:


1. Besides only pulling the Opportunity dataset into Wave Analytics, the Roles and Users (API Name: UserRoles) objects have to be pulled as well. 2. The UserRole object then has to be flattened using the dataflow with this dataflow JSON syntax:

"104_Flatten_UserRole": {
	"action": "flatten",
	"parameters": {
  	"multi_field": "Roles",
  	"parent_field": "ParentRoleId",
  	"path_field": "RolePath",
  	"self_field": "Id",
  	"source": "103_Extract_UserRole"
	}
  },
a. The “flatten” action requires several parameters as seen above
i. self_field
the ID field of the main hierarchy object
ii. parent_field
the parent of each node in the hierarchy. For example from the hierarchy chart above, the role “NJ_Sales” would have the parent_field ID of “East_Sales”.
iii. multi_field
this is the name of the newly added field after the flatten is completed which contains the IDs from the record owner’s parent role, all the way to the highest role in the hierarchy. From the earlier example, this would include the IDs for “East Sales” and “VP_Sales” in a multivalued format.
iv. path_field
A string representation of the multi_field field which has role IDs separated by a backslash (\).

3. Once the UserRole object has been flattened, it has to be augmented onto the User object. The augment key used is the RoleID from the User dataset and the ID of the UserRole dataset (the User dataset is on the left, UserRole on the right of this augment). The result of this operation is then augmented onto the Opportunity dataset with the augment key as the Opportunity Owner ID and the User ID (Opportunity on the left of the augment, UserWithRoles on the right). The full dataflow is represented in the image below. 4. Lastly, the security predicate needs to be applied to the resulting dataset. The easiest way to make sure that the security predicate is applied at the time of dataset creation is by including it in the workflow.

This type of pattern can be applied to other hierarchical objects within an org such a territory based hierarchy. The resulting multivalued field would contain the hierarchical territory IDs which would need to match with a user field allowing the predicate can be applied.


Use Case 4: Security Based on Externally Sourced Data

The use cases above assume data loaded from Salesforce objects. The same general method carry to hierarchy data which has been ingested from external sources i.e. from a data warehouse, an existing BI tool and/or a CSV.


The important aspect for any externally loaded security data is to have some level of unique mapping with the Salesforce User Object. An example scenario is a geographic based visibility hierarchy which provides user access on Accounts, Opportunities, Cases or Campaigns based on a user’s Region, Area, Territory that they manage. It’s important that this data exists at a level where there is a Unique external UserID, User Alias, User’s email which also corresponds to a Salesforce User Object field. This help mesh up the external hierarchy data with Salesforce objects to apply security. The example case-study discusses this model in elaborate detail.


View All Functionality

While implementing any of these use cases, an admin or other users involved in the implementation process may need full access to the data. There are various ways to achieve this functionality.


View All Option 1


The most common practice has been to modify the User object with a “View All” field.


  1. You can add a custom drop-down field on the User object with visibility details. Example values could be “View All”, “View Opportunities”, “View Account Bookings”, “View Product Bookings”.
  2. You have to ensure the ‘Wave Analytics Security User’ has visibility to the custom field on this user. You can control this by going into the Wave Analytics Security User’s profile, searching for field-level security (FLS) and editing FLS settings for the User object by providing access to the designated custom field e.g. “View_All__c”
  3. Next in your dataset, while uploading you should plan to have a multi-value field (typically loaded as a comma (,) separated values). For the opportunity dataset you can consider the field to house “View All, View Opportunities” value for each record.
  4. The security predicate appended to the dataset will be

|| ‘View_All_Settings’ == “$User.View_All__c”


View All Option 2


Another way of implementing the View All functionality is by using the Custom Permissions field to create a multivalued list of profile IDs for each row of a dataset.


  1. Create new custom permission
  1. Setup | Develop | Custom Permissions, create new with Label: “View All Analytics Data” and Name: “View_All_Analytics_Data”
  1. Add custom permission to desired “View all” profile
  1. Setup | Manage Users | Profiles, select desired profile for all data and add “View All Analytics Data” as a Custom Permission
  1. Create a field in your dataset with the value “View_All_Analytics_Data”
  1. To create a dataset which has a record for each profile with the newly created “View All” custom permission, set up a workflow like so:
Image07.png


  1. To the workflow above, you can add an augment to the dataset desired to have “View All” functionality. The core dataset (such as Opportunity) should be on the left of the augment. The newly created field in your dataset with the “View_All_Analytics_Data” value should be the left key and the right key will be the DeveloperName from the “CustomPermission” object. This will create a multivalued field for each profile which has access to all the rows in the dataset. The final predicate to enable the view all functionality will be (dataset field names may vary based on relationship names set in the augments):

|| ‘SetupEntityAccess.ViewAllAnalyticsData.PermissionSet.ProfileId’ == “$User.ProfileId”


Adding “View All” Field to a Dataset


There are different options in adding the “View All” field to the dataset depending on whether the data comes from an external or internal source. For external data, the the field could simply be added manually or using an ETL tool. If the external data is already loaded into Wave without this field or if the source of the data is internal from Salesforce core, the “computeExpression” can be used on the data to create the extra field following the 200 release (Spring ‘16). An example of such a transformation is shown below:


 "CreateDerivedFields": {
   "action": "computeExpression",
   "parameters": {
      "source": "100",
      "mergeWithSource": true,
      "computedFields": [
         {
            "name": "View_All_Field",
            "type": "Text",
            "label": "View All Field",
            "isMultiValue": true,
            "multiValueSeparator": ",",
            "saqlExpression": "\"View All, View Opportunities\""}
      
         ]
      }
   }


This transformation will create the multivalue field with the label “View All Field” with the static values of “View All” and “View Opportunities”. An Accounts dataset could have a similar transformation performed but with static values of “View All” and “View Accounts”. In this way, an Admin can flexibly control the datasets which each user is able to access. For example, one user could be assigned the “View All” value for their “View_All__c” which will allow them to see both the Opportunity and the Accounts dataset. Meanwhile, another User may only be assigned the “View Accounts” value for the “View_All__c” field restricting them to only see the Accounts dataset while otherwise being limited to what they see in the Opportunity dataset in accordance with how the rest of the security predicate for that data is set up.


Example Case Study : Leading Cloud Technology Firm

Customer Background

A leading Cloud vendor leverages Wave for a Churn Analysis Dashboard. The dashboard is targeted for executives, sales leaders and regional sales managers. The data are sourced from the Customer’s data warehouse. Key data dimensions include Account Bookings, Product Bookings, Opportunities and certain set of derived metrics which are combined for key insights into Churn.


Security Requirements

The solution required Wave’s role-based security to enable authorized access to data for certain class of users. These user classes include:


Access Requirement

Description

1

Account Ownership

Owner of an account should have visibility to their records

2

Geographic Visibility

Sales management is provided access to specific geographies based on their visibility span on the territory hierarchy. While any opportunity is restricted to a specific territory, a user visibility may span across multiple regions, multiple areas and/or multiple territories. This visibility may not always follow Accounts natural owner hierarchy.


The customer maintains changes to this hierarchy using their data warehouse and the hierarchy controls access across their analytic platforms.

3

View All

The business owner team for the application and other cross-region resources who may not sit in geographic visibility hierarchy or account ownership hierarchy require access to ‘All Data’. This is especially important as regions may plan and add more territories or re-align territories, which may require updates to territory visibility assignments.

The use-case was implemented on externally sourced data and security hierarchy. The user visibility geographic visibility data is maintained by the Customer sales operation team in the following format:


User Alias


Region


Area


Territory


Comment


URAUF


Americas


All bookings & opportunities in AMER


URAUF


EMEA


Europe-West


All bookings & opportunities in Western Europe


URAUF


EMEA


Europe-East


TM-EMEA-5


All bookings & opportunities in Russia


TOMASZ


EMEA


All bookings & opportunities in EMEA


TOMASZ


APJ


All bookings & opportunities in APJ


BOBD


EMEA


Europe-North


TM-EMEA-10


Only Denmark Opportunities


BOBD


EMEA


Europe-North


TD-EMEA-11


Only Sweden Opportunities


To effectively use externally sourced hierarchy data, there should be appropriate matching dimensions within the Wave dataset. In addition, there should be a way to map the external user access data with an authenticated user in Salesforce who will access the dataset.


Implementation Details

When loading data into Wave without applying a security filter at load time, it is always recommended that you register it to a specific folder/application which has access restricted to certain users. These users can include the administrator, selective builders (or dataflow user) and the Integration user. Next, you can use the native dataflow to perform additional transformations on these loaded datasets and apply security predicate while registering it to the destination application where end-users will be able to access. This will ensure security of your data while loading it into Wave using application-level security.


The account ownership is a simple rule to implement whereby account booking, product booking and opportunity datasets had each row getting mapped to an account. These datasets were augmented with OwnerID from Salesforce Account object using the ‘Customer_Account_Key__c’. This provided an ‘owner’ for each record which can be used for the security predicate:


‘Owner_Id’ = “$User.Id’


The geographic hierarchy data was reorganized to have a key value pair for all territories a user is assigned to,


UserAlias

Territory_ID

UserAlias

Territory_ID

URAUF

TM-AMER-1

TOMASZ

TM-EMEA-1

URAUF

TM-AMER-2

TOMASZ

TM-EMEA-2

URAUF

TM-AMER-3

TOMASZ

TM-EMEA-3

URAUF

.....

TOMASZ

.....

URAUF

.....

TOMASZ

.....

URAUF

TM-EMEA-10

TOMASZ

TM-EMEA-10

URAUF

TM-EMEA-11

TOMASZ

TM-EMEA-11

TOMASZ

TM-EMEA-1

TOMASZ

TM-SEA-1

TOMASZ

TM-EMEA-2

TOMASZ

TM-JAP-1

TOMASZ

TM-EMEA-3

BOBD

...


This restructured allows you to augment the user aliases for a particular territory on the Account Bookings, Product Bookings and Opportunity object. You can achieve this with the following transformation in your data workflow.



{
{
"Extract_Opportunity": {
        "action": "edgemart",
        "parameters": {
            "alias": "OpportunityRaw",
            "SFDCtoken": "SFDCtoken",
            "skipLocalCache": false
        }
    },
"Extract_UserTerritory": {
        "action": "edgemart",
        "parameters": {
            "alias": "UserTerritory",
            "SFDCtoken": "SFDCtoken",
            "skipLocalCache": false
        }
    },
"Extract_Account": {
        "id": "Extract_Account",
        "action": "sfdcDigest",
        "parameters": {
            "SFDCtoken": "SFDCtoken",
            "object": "Account",
            "fields": [
                {"name": "Customer_Account_Key__c" },
                {"name": "OwnerId"}
                {"name": "Id"}
            ]
        }
    },
"OpportunityAccount_Augment": {
        "action": "augment",
        "parameters": {
            "relationship": "Account",
            "left_key": [
                "ACCOUNT_ID"
            ],
            "right_key": [
                "Customer_Account_Key__c”
            ],
            "left": "Extract_Opportunity",
            "right": "Extract_Account",
            "right_select": [
                "OwnerId"     
          }
    },
"OpportunityAlias_Augment": {
        "action": "augment",
        "parameters": {
            "relationship": "Territory",
            "operation": "LookupMultiValue",
            "left_key": [
                "Territory_ID"
            ],
            "right_key": [
                "Territory_ID"
            ],
            "left": "OpportunityAccount_Augment",
            "right": "Extract_UserTerritory",
            "right_select": [
                "UserAlias"
            ]
        }
    },
    "Register_Opportunity": {
        "action": "sfdcRegister",
        "parameters": {
            "source": "OpportunityTerritory_Merge",
            "alias": "OpportunitySecure",
            "rowLevelSecurityFilter": "'Territory.UserAlias' == \"$User.Alias\"
                                        || 'Account.OwnerId' == \"$User.Id\"",
            "name": "Opportunity"
        }
    }
}

The above workflow creates an augmented column ‘Territory.UserAlias’ in the Opportunity dataset which can be mapped to the $User.Alias field to apply the row level security.


The workflow rapidly leverages the external hierarchy and applies the security predicates using the Opportunity Territory information with User’s Territory assignment.


Example Case Study : Accounts Overview

Customer Background

An extensive implementation of the security predicate included an overview of booked opportunities, customer health by case, and customer product adoption. This implementation requires that each account owner and the hierarchy above the owner is able to see these different metrics.


Security Requirements

No.

Access Requirement

Description

1

Account Ownership

Owner of an account should have visibility to their records


2

Sales Hierarchy Visibility

The sales hierarchy should be able to see every record they manage, starting from the owner going up.


3

View All

Some users need to have access to the whole dataset. This mostly includes users who are working on the implementation and maintenance allowing them to debug any data or product issues that may arise.

Implementation Details

The Opportunity, Case, and Adoption datasets were all externally loaded from an EDW. The User, UserRole, and Account datasets on the other hand are pulled from the org directly. To combine the sales hierarchy to each of the main three objects (Opportunity, Case, Adoption), the UserRole object is flattened, augmented with User, and this result is augmented with Account. This full result is then augmented with each of the three objects on the Account Owner ID. This means that the owner of the account and above in the sales hierarchy will have access to each record which corresponds with the account they own or manage.


To assure that all of these datasets aren’t visible without a security predicate applied, a staging App was created. The scheduled uploads of the Opportunity, Case, Adoption, User, and Account datasets are all directed into this App. This App has access restricted to everyone but the users who are in charge of loading and verifying the data. Once all the uploads have been completed, a daily workflow is scheduled to run. This workflow creates the final Opportunity, Case, and Adoption datasets which each have user hierarchies the static “View All” field computed using the “computeExpression” action. All of these are then registered into the final destination App where users can view them depending on their position in the sales hierarchy.


Below is a sample of the entire workflow in this use case. Here, only Opportunity is shown but the same augments are done to the Adoption and Case datasets.


{ 
    "Extract_Account": {
    "action": "edgemart",
    "parameters": {
      "alias": "raw_account"
    }
  },
    "Extract_Opportunity": {
    "action": "edgemart",
    "parameters": {
      "alias": "DW_OPPORTUNITY"
    }
  },
    "Extract_User": {
        "action": "sfdcDigest",
        "parameters": {
            "object": "User",
            "fields": [
                {
                    "name": "Id"
                },
                {
                    "name": "Name"
                },
                {
                    "name": "Department"
                },
                {
                    "name": "UserRoleId"
                }
            ]
        }
    },
    "Extract_UserRole": {
        "action": "sfdcDigest",
        "parameters": {
            "object": "UserRole",
            "fields": [
                {
                    "name": "Id"
                },
                {
                    "name": "Name"
                },
                {
                    "name": "ParentRoleId"
                }
            ]
        }
    },
    "Flatten_UserRole": {
        "action": "flatten",
        "parameters": {
            "source": "Extract_UserRole",
            "self_field": "Id",
            "parent_field": "ParentRoleId",
            "multi_field": "Roles",
            "path_field": "RolePath"
        }
    },
    "Augment_User_FlattenUserRole": {
        "action": "augment",
        "parameters": {
            "left": "Extract_User",
            "left_key": [
                "UserRoleId"
            ],
            "relationship": "Role",
            "right": "Flatten_UserRole",
            "right_key": [
                "Id"
            ],
            "right_select": [
                "Id",
                "Name",
                "Roles",
                "RolePath"
            ]
        }
    },
  "Account_UserRole_Augment":{
  	"action": "augment",
  	"parameters": {
  		"relationship": "Owner",
  		"left_key": ["OwnerId"],
  		"right_key": ["Id"],
  		"left":"Extract_Account",
  		"right": "Augment_User_FlattenUserRole",
  		"right_select":[
             “Id”,
  		"Name",
        "Macro_Segment_c",
        "Coverage_Country_c",
        "Role_Name",
        "User_Path",
        "User_Role_Path",
        "User_Role_Id_Path"
  		]
  	}
   },
   “Join_Opportunity_Account”: {
    "action": "augment",
    "parameters": {
      "relationship": "Account",
      "left_key": [
        "AccountId"
      ],
      "right_key": [
        "Id"
      ],
      "left": "Extract_Opportunity",
      "right": "Account_UserRole_Augment",
      "right_select": [
        "Owner.Id",
        "Owner.Name",
        "Owner.Macro_Segment_c",
        "Owner.Coverage_Country_c",
        "Owner.Role_Name",
        "Owner.User_Path",
        "Owner.User_Role_Path",
        "Owner.User_Role_Id_Path"
      ]
    }
  },
  "Opportunity_Account_ViewAll": {
   "action": "computeExpression",
   "parameters": {
      "source": "Join_Opportunity_Account",
      "mergeWithSource": true,
      "computedFields": [
         {
            "name": "Dataset_Access",
            "type": "Text",
            "label": "Dataset_Access",
            "saqlExpression": "\”View All\”"}
      
         ]
      }
   },
    "Register_Opportunity": {
    "action": "sfdcRegister",
    "parameters": {
      "source": "Opportunity_Account_ViewAll",
      "alias": "opportunity",
      "folderid": "00l30000003VYDpAAO",
      "name": "Opportunity",
      "rowLevelSecurityFilter": "'Owner.User_Role_Id_Path' == \"$User.UserRoleId\" || 'Owner.Id' == \"$User.Id\" || 'Dataset_Access' == \"$User.Dataset_Access__c\""
    }
  }
}

Conclusion

Trust being the highest priority for Salesforce, Wave provides our Customers robust alternatives to control application and data access on the Wave platform. They can use Salesforce org security to make sure that only pre-determined data elements are imported into Wave. Once the data is within Wave, Application level security and the security predicate can be leveraged to implement different schemes such as team based security or management hierarchy based security.

About these Best Practices

The Advanced Solutions Group ( ASG ) is specialized analytics team in the Analytics Cloud product organization that provides world-class technical leadership and guidance focused on empowering the Wave ecosystem. ASG helps drive rapid value by leveraging deep technical knowledge of the Wave platform and apps. These best practices cover design and implementation alternatives for real-world analytics use-cases.

Reach the ASG experts at #AsktheACExperts

ASG Logo Final.png