Identity-Driven Properties

Overview

It is often necessary to make per-person access distinctions. 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:
  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:
SAS.Userid
returns an authenticated user ID, normalized to the uppercase format USERID or USERID@DOMAIN.
SAS.ExternalIdentity
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. An external identity value functions as a synchronization key in the user bulk load and synchronization macros. For more information, see the SAS Intelligence Platform: Security Administration Guide.
SAS.IdentityGroups
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.
SAS.PersonName
returns a user name, as displayed in the Name field on the user's General tab.
These identity-driven properties are also supported:
SAS.IdentityGroupName
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. Not all applications allow a group to log on. This property is not supported if client-side pooling is used.
SAS.IdentityName
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.

Examples of Identity-Driven Substitutions

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.
The following 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
1Because 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 returns an empty string.

Missing Values in Identity-Driven Properties

If a connecting user doesn't have a value for the identity-driven property that a query uses, the generated query uses an empty string as the substituted value for that identity. If the table against which the query filtering is performed includes empty string values in any rows, those rows are returned to the connecting identity.
Here are some alternatives for addressing missing values:
  • To ensure that data is returned for only those identities who have a value for the property that you are using, make sure that there aren't any empty string values in the target table's security key column.
  • To identify a set of rows that should be returned for identities who don't have a value for the property that you are using, specify an empty string value for those rows in the target table's security key column.
    Note: If the target table is in a DBMS, the extra row must contain an empty (blank) character string (not a NULL value).
  • To identify a situation in which retrieval is empty due to a missing value for the requesting user's identity-driven property, include a mapping for the empty string value (' ') in your security associations table and one extra row in your target table. In that row, use the security key that corresponds to the empty string value and include an appropriate error message. This enables the end user to distinguish between the following situations:
    • an empty result set that is caused by the target table not including any rows that match the user's value for an identity-driven property
    • an empty result set that is caused by the user not having any value for the identity-driven property that a query is using
    Note: If the security associations table is in a DBMS, make sure that the missing value row in that table contains an empty (blank) character string, not a NULL value.
    The following figure depicts an example:
    Example: Error Handling for a Missing External Identity Value
    Example: Error Handling for a Missing External Identity Value