Previous Page | Next Page

Authorization Model

Fine-Grained Controls for Data

What Are Fine-Grained Controls?

Considerations for Batch Reporting

Identity-Driven Properties

What Implementations are Available?

How are Fine-Grained Controls Assigned?

What Are Fine-Grained Controls?

Business requirements often specify that different users should see different portions, or slices, of data. In some cases, the requirement is driven by the sensitive nature of data. For example, company policy might state that each sales person should be able to access only his or her own salary information. In other cases, the requirement is intended to prevent information overload. For example, each regional sales team within a national organization might be interested in only the sales trend information for their region. Row-level access distinctions are frequently based on each user's place in an organizational structure such as a management hierarchy or a product matrix. The visibility of data can depend on a simple, site-specific condition such as a user's security clearance level, or on a more complex condition that consists of multiple filters.

You use fine-grained controls to specify who can access particular rows within a table or members within a cube dimension. These controls often subset data by a user characteristic such as employee ID or organizational unit. For example, a table that contains patient medical information might be protected by row-level permissions that enable each doctor to see only those rows that contain data about that doctor's patients.

Unlike other access controls, fine-grained controls are based on filters and rely on target data that is modeled to work with those filters. When fine-grained controls are used, there are three possible authorization decision outcomes for a request to view data:


The requesting user can access all data.


The requesting user can't access any data.


The requesting user can access only the data that meets specified filtering conditions.

Considerations for Batch Reporting

When you use fine-grained controls, it is essential to understand that only dynamically generated reports display data based on the access that is defined for the requesting user. Static reports display data based on the access that is defined for the user ID that was used to generate the report. For example:

Identity-Driven Properties


It is often necessary to make per-person access distinctions for the rows in a table or the members in a dimension. You can make a separate filter for each user (such as where name="joe" ). However, if you have more than a few users, this approach quickly becomes cumbersome. The more efficient alternative is to create a dynamic filter (such as where name="&name;" ) that can discover and insert the correct, user-specific value into the WHERE expression each time access is requested.

To create a dynamic filter, use an identity-driven property as the value against which values in the target data are compared. This list explains how the substitution works:

Note:   This discussion is not applicable to the SPD Server, which has its own implementation of identity-based filtering.  [cautionend]

  1. Each identity-driven property corresponds to a characteristic (such as name, user ID, or external identity).

  2. Each user's values for these characteristics (such as joe, WinXP\joe, or 607189) are stored in the metadata.

  3. The identity-driven property is aware of the user ID with which a client authenticated and can locate information that is stored in the metadata for that user ID.

  4. Each time it receives a request, the identity-driven property substitutes a user-specific value into the filter expression.

These are the most useful identity-driven properties:


returns an authenticated user ID, normalized to the uppercase format USERID or USERID@DOMAIN.


returns a site-specific value (for example, employee ID). This property is often useful because its values are likely to match user information in your data. An identity can have more than one external identity value; however, only the first value is returned. Unlike the values for other identity-driven properties, values for this property are not always populated in the metadata. See External Identities.


returns a list of the groups and roles that this identity belongs to (directly, indirectly, or implicitly). The list contains the group and role names, as displayed in the Name field on the General tab for each group or role.


returns a user name, as displayed in the Name field on the user's General tab.

These identity-driven properties are also supported:


returns a group name, as displayed in the Name field on the group's General tab. If a user logs on with an ID that is stored in a login on a group definition, then the name of the group that owns that login is returned. If a user logs on with a user ID that is not stored in the metadata, then the PUBLIC group is returned.

This property is useful only in the unusual circumstance where a user logs on with the user ID that is defined for a group login. In almost all cases, a user logs on with a user ID that is defined for an individual user definition. This property is not supported if client-side pooling is used.


returns a user name or group name, as displayed in the Name field on the General tab for the user or group. This property is a generalization of SAS.PersonName and SAS.IdentityGroupName.

Note:   In certain circumstances, a connecting identity might not have a value for the identity-driven property that you are using. This can happen with the ExternalIdentity property (sometimes), the IdentityGroupName property (almost always), or the PersonName property (rarely). When a connecting user doesn't have a value for the property that a query uses, an empty string is returned or the query fails. See BI Row-Level Permissions, Identity-Driven Properties, and Missing Values.  [cautionend]


For example, to enable each user to see only his or her own salary information, you could give the PUBLIC group a filter that is based on the SAS.PersonName property. At run time, the SAS.PersonName value that is associated with the connected user ID is substituted into the filter. In this way, the query is modified as appropriate for each requesting client.

This table contains examples of filters that are based on identity properties, showing representations of both the generic form and how each filter would be modified when executed by a user named Harry Highpoint. Harry is a member of the ETL and Executives groups. The example assumes that the customer has an employee information table named EmpInfo which includes Name, Category, WinID, Department, and EmpID columns.

Examples of Filters That Use Identity-Driven Properties
As Defined (Generic Form) As Executed (Resolved Form)
Where EmpInfo.WinID=&SAS.Userid; Where EmpInfo.WinID="HIGH@WIN"
Where EmpInfo.EmpID=&SAS.ExternalIdentity; Where EmpInfo.EmpID="123-456-789"
Where EmpInfo.Department IN &SAS.IdentityGroups; Where EmpInfo.Department IN ('ETL','Executives','PUBLIC','SASUSERS')
Where EmpInfo.Name=&SAS.IdentityName; Where EmpInfo.Name="Harry Highpoint"
Where EmpInfo.Name=&SAS.PersonName; Where EmpInfo.Name="Harry Highpoint"
Where EmpInfo.Category=&SAS.IdentityGroupName; Where EmpInfo.Category=' '1
1 Because the user does not log on with a user ID that is stored as part of a group definition, the user has no value for this property. This either returns an empty string (in BI row-level permissions) or causes the query to fail (in other implementations).

What Implementations are Available?

Each of these components offers an implementation of fine-grained controls:

Information Maps (BI Row-Level Permissions)

provides filtering for SAS data sets and third-party relational data accessed through an information map. You define and assign the filters in SAS Information Map Studio. See BI Row-Level Permissions.

This feature is practical for use with large, dimensionally modeled data marts. BI row-level permissions do not require a specific data model. BI row-level permissions can limit access to data within fact tables without incurring the performance cost of directly filtering those tables. This is accomplished by ensuring that access to a fact table is always subject to an inner join with a filtered dimension (the filtering criteria is usually some type of identity information). This feature enables you to define granular access to third-party data without requiring you to maintain individual user accounts within those database systems.

Not all SAS clients require that users go through information maps in order to access data.

Comprehensive security that incorporates BI row-level permissions requires a specific, high-security configuration of SAS Web Report Studio.  [cautionend]


provides filtering for SAS OLAP data using MDX expressions. You define and assign the filters in SAS Management Console, SAS OLAP Cube Studio, or SAS Data Integration Studio. See OLAP Member-Level Permissions.

SAS Scalable Performance Data Server

enables you to define database views that filter rows based on the user ID of the connecting client. This functionality is provided by the @SPDSUSR system variable. The metadata-based identity driven properties are not available in this implementation. See the SAS Scalable Performance Data Server: Administrator's Guide.

The following table compares the implementations:

Comparison of Fine-Grained Control Implementations
Implementation Secure Graphical Filter Creation Standard Authorization UI Metadata-Aware Identity-Driven
OLAP member-level [check]
SPD Server row-level [check]

BI row-level [caution icon]

How are Fine-Grained Controls Assigned?

Note:   This discussion is not applicable to the SPD Server.  [cautionend]

Fine-grained controls are assigned to users or groups on the Authorization tab of the target dimension or table. These filters are available only to constrain an explicit grant of the Read permission. These filters are incorporated into the access control evaluation process as permission conditions. See Authorization Decisions.

A permission condition is applied only if it is on the setting that is closest to the requesting user. Other conditions that are relevant because of further-removed group memberships don't provide additional, cumulative access. If there is an identity precedence tie between multiple groups at the highest level of identity precedence, those tied conditions are combined in a Boolean OR expression. If the identity precedence tie includes an unconditional grant, access is not limited by any conditions. The following table provides examples:

Precedence for Permission Conditions
Principle Scenario Outcome and Explanation
If there are multiple permission conditions that apply to a user because of the user's group memberships, then the highest precedence identity controls the outcome. A filter on InformationMapA limits Read permission for GroupA.

Another filter on InformationMapA limits Read permission for the SASUSERS group.

The user is a member of both GroupA and SASUSERS.

The user can see only the rows that GroupA is permitted to see. GroupA has higher identity precedence than SASUSERS, so the filters that are assigned to GroupA define the user's access.
If there are multiple permission conditions at the highest level of identity precedence, then any data that is allowed by any of the tied conditions is returned. A filter on DimensionA limits Read permission for GroupA.

Another filter on DimensionA limits Read permission for GroupB.

The user is a first level member of both GroupA and GroupB.

The user can see any member that is permitted for either GroupA or GroupB.

The following example describes the impact of identity precedence when a manager uses an information map that includes both of the following filters for a SALARY table:

When the manager accesses the SALARY table, the filter that is assigned to the Managers group is applied and the filter that is assigned to SASUSERS is ignored. This is because the manager's direct membership in the Managers group has higher identity precedence than the manager's implicit membership in the SASUSERS group. To avoid a situation in which managers can see their employees' salaries but each manager can't see his or her own salary, you can use either of these approaches:

Previous Page | Next Page | Top of Page