Skip to content

platformadmin.com

Paul Homes blogging on SAS® platform administration topics

  • Home
  • Reading List
  • About / Contact
  • RSS Feed
  • LinkedIn
  • GitHub
  • LinkedIn (Metacoda)
  • YouTube (Metacoda)
platformadmin.com

Tag: Member Level Security

Metacoda Plug-ins Tip: Advanced Expression-Based Filters (Protected Object Reviewer)

This post continues a series of examples on Advanced Expression-Based Filters for Metacoda Plug-ins, in this case for the Protected Object Reviewer.

Here are some expressions that you may find useful to copy and paste into the filter bar of the Metacoda Protected Object Reviewer as a starting point for finding interesting sets of SAS metadata objects that have had access controls, Access Control Templates (or ACTs) and/or Access Control Entries (ACEs or explicit permissions), applied to them:

Protected Tree Branch Objects: show folders and objects, underneath the /Vegas Enterprises metadata tree branch, that have had any ACTs or ACEs applied to them.

#@ path.startsWith("/Vegas Enterprises")

ACT Protected Tree Branch Objects: show folders and objects, underneath the /Vegas Enterprises metadata tree branch, that have had ACTs applied (and optionally ACEs). Continue reading “Metacoda Plug-ins Tip: Advanced Expression-Based Filters (Protected Object Reviewer)”

Author Paul HomesPosted on 16 May 201829 December 2024Categories Metacoda Security Plug-insTags ACE, ACT, Advanced Expression-Based Filters, BeanShell, Filter Bar, Member Level Security, Metacoda Plug-ins, Metacoda Plug-ins Tip, Metacoda Security Plug-ins, Protected Object Reviewer, Row Level Security, SAS Metadata Security

Metacoda Plug-ins Tip: Advanced Expression-Based Filters (ACE Reviewer)

This post continues a series of examples on Advanced Expression-Based Filters for Metacoda Plug-ins, in this case for the ACE Reviewer.

Here are some expressions that you may find useful to copy and paste into the filter bar of the Metacoda ACE Reviewer as a starting point for finding interesting sets of SAS Access Control Entries (ACEs or explicit permissions):

Tree Branch ACEs: show explicit permissions on folders and objects underneath the /Vegas Enterprises/HR metadata tree branch.

#@ protectedObjectPath.startsWith("/Vegas Enterprises/HR")

Object Type ACEs: show explicit permissions on folders (excluding the root folder) Continue reading “Metacoda Plug-ins Tip: Advanced Expression-Based Filters (ACE Reviewer)”

Author Paul HomesPosted on 16 May 201829 December 2024Categories Metacoda Security Plug-insTags ACE, ACE Reviewer, Advanced Expression-Based Filters, BeanShell, Filter Bar, Member Level Security, Metacoda Plug-ins, Metacoda Plug-ins Tip, Metacoda Security Plug-ins, Row Level Security, SAS Metadata Security

SAS 9.2 OLAP Cube Identity Driven Member Level Security

Identity-driven member level security for SAS 9.2 OLAP cubes, as the name suggests, uses the identity of the requesting user to restrict access to specific members of a dimension, and in so doing control the subset of cube data that the user has access to. Imagine that you have an OLAP cube containing sales data for all sales people, but an individual sales person is restricted to only seeing a subset of that data. Among all of the other dimensions, perhaps one of the dimensions in the cube has the sales person’s user id contained within it. We can construct an identity-driven MDX expression that can be used to filter the cube data on that dimension to only include members that match an identity attribute such as user id. Of course there are also other ways of using other identity attributes to limit access to cube data but I’ll keep it simple in this example.

To quote from SAS® 9.2 OLAP Server: User’s Guide > What’s New in the SAS 9.2 OLAP Server > Security For Cubes documentation:

Identity-driven security enables you to substitute identity values in a permission condition. It enables you to insert a placeholder into the permission condition that, at query time, gets resolved to a string that represents the user identity.

You can see the various identity value placeholder properties available to you in: SAS® 9.2 OLAP Server: User’s Guide > Modifying and Maintaining Cubes > Cube Security > Identity-Driven Security. Some of the ones that we might use with an individual user include:

  • SAS.Userid – the normalized user id for the person querying the cube (e.g. BILLY@MYDOMAIN)
  • SAS.IdentityName (or SAS.PersonName) – the name of the person querying the cube, as seen in the SAS Management Console User Manager plug-in (e.g. Billy Baxter)
  • SAS.ExternalIdentity – a site specific identifier for people that have been bulk-loaded into metadata from directories such as Active Directory, OpenLDAP etc. This could be an employee number for example (e.g. e12345678)

In this post I’m going to highlight a simple example for a couple of reasons. Firstly, whilst the documentation includes lots of general examples, I couldn’t find many that demonstrate the use of an identity-driven member level security filter. Now I can refer to this post when I need to remember how it’s done. Additionally, during my investigation, I kept getting stumped by an MDX syntax error dialog during the definition of the permission condition. It took me a while to discover that I could just accept the error because at run-time, when the identity substitution happens, the MDX will become syntactically valid. Publishing my experiences might help others save themselves a bit of time and frustration too.

My example cube was built from a SAS table that included a sales person user id column. The value of that column for each row was the user id for the sales person that had access to that data – i.e. that row would contribute to the cube subset that the sales person would be able to see when they query the cube. The format of the user id in that column was quite specific. It was in a normalised format, as explained in the SAS documentation. The user id was converted to uppercase and included a domain suffix on Windows. In Windows environments it would most likely be in the format USERID@DOMAIN (e.g. BILLY@MYDOMAIN), whereas in some UNIX environments it might be in the format USERID (e.g. BILLY). If you don’t know what the format is for your environment you can probably work it out by looking in the SAS Metadata Server logs or turning on some of the debugging options for the SAS OLAP Server. If you don’t get the format correct you are likely to end up with an MDX filter that filters out everything so there is nothing to display!

Information on how to set up member level security on a dimension can be found in the SAS® 9.2 OLAP Server: User’s Guide > Cube Building and Modifying Examples > Setting Member Authorizations On A Dimension. I won’t duplicate that information here, suffice to say that in my example cube I want to apply an identity-driven member level security filter on normalized userid members in the lowest level of a DimSalesPerson dimension using the SAS.UserId property. I want it to apply to all known SAS identities (i.e. SASUSERS group) so I start out by adding an explicit grant of the Read permission to the SASUSERS group on the DimSalesPerson dimension in the cube. This enables the Edit Authorization… button that I click to open the Add Authorization dialog. I select the radio button for Create an advanced MDX expression using the expression builder then click the Build Formula… button. I can then enter the MDX expression to filter the cube data for the current user identity.

When constructing the MDX filter expression you can insert placeholders for Identity Values (such as SAS.Userid) which will be substituted at run-time with the appropriate value corresponding to the user making the request. These Identity Values need to be in a specific format SUB::IdentityValueName (e.g. SUB::SAS.Userid). Whilst I couldn’t find the format documented anywhere, you will see an example of it if you use the Build Formula dialog’s Data Sources list to add an Identity Value into the expression. There is also an example screenshot showing SUB::SAS.IdentityGroups at the bottom of SAS® 9.2 OLAP Server: User’s Guide > Cube Building and Modifying Examples > Setting Identity Driven Security. It doesn’t show it used within a larger MDX expression however.

In my example I want to use the normalized user id to choose the appropriate member of the DimSalesPerson dimension, so I type the following into the Build Formula dialog’s Expression Text field and click the OK button.

{[DimSalesPerson].[All Sales People].[SUB::SAS.Userid]}

Tip: if you want help in working out the syntax for this filter, open the OLAP cube in SAS Enterprise Guide, use point-and-click to filter in the slicer on an example user id in the appropriate dimension. When the table looks like it displays data for a single user, view the MDX:

    SELECT CrossJoin({[DimTime].[All Time].Children }, {[Measures].[SaleAmountSUM] }) ON COLUMNS,
    {[DimGeo].[All States].Children } ON ROWS
    FROM [TransactionsCube]
    WHERE ([DimSalesPerson].[All Sales People].[BILLY@MYDOMAIN])

You should see what you need in the MDX WHERE clause and you can replace the user id with the identity property – SUB::SAS.UserId in this case.

This is where, initially, I got stuck for a while. I saw the following error dialog because it was not valid MDX since SUB::SAS.Userid was not actually a real member.

It turns out this was ok, because although it was not itself a valid member, at run-time when the user queried the cube it was replaced with the real member value (e.g. BILLY@MYDOMAIN) and became valid MDX (assuming of course that BILLY@MYDOMAIN was a member!).

Tip: How can I tell whether the syntax error is due to the placeholder or the rest of the MDX? One method that I use is to start out by using a constant for a valid member (e.g. {[DimSalesPerson].[All Sales People].[BILLY@MYDOMAIN]}) instead of the placeholder. Verify the MDX syntax is ok for the constant value and that the filter works as expected when you open the cube (i.e. you see the subset of data for that constant user). If all is ok then go back and replace the constant with the placeholder (e.g. {[DimSalesPerson].[All Sales People].[SUB::SAS.Userid]})

So even though I had this error I could click the OK button. I then saw the following warning dialog where I could confirm I did indeed want to save the invalid MDX expression as a permission condition by clicking the Yes button.

With the identity driven member level security filter applied, now whenever the cube was queried the user would only see the subset of data they had been granted access to.

As I mentioned earlier this is a relatively simple example. In reality you would probably want to apply the identity-driven filter to a suitable sales-people group and allow some management-level people to see larger or complete subsets of the cube. You might also want to filter based on group memberships and probably make the filter a bit more robust in case the user id doesn’t exist in the cube. Also, if you are running the third maintenance of SAS 9.2 you could also apply the permission conditions in batch using a permissions table.

The method I use to review all the SAS OLAP cube member level security permission conditions that are present in metadata is to use our Metacoda Security Plug-ins ACE Reviewer. You can click on the image below if you want to see it full size:

Finally, the following SAS usage notes can be very helpful for debugging or troubleshooting with the SAS OLAP Server:

  • SAS Usage Note 38429: Generating journal files for the SAS® OLAP Server by using SAS® Management Console
  • SAS Usage Note 36728: Setting additional debug options for the SAS® OLAP Server 9.2

BTW: The inspiration for this post came from a question asked on the SAS Discussion Forums > SAS Stored Processes > Thread: Role based security as input parameter, data read from oracle db on demand

Update 02Feb2011: If you’re reading this post then you might also be interested in a related post on Angela Hall’s Blog: Implementing OLAP Member Level Security for All Vantage Points

Update 03Feb2011: In some testing I found the following permission condition useful for filtering on a user id level (that has unique member values across the entire dimension) in a cube at an arbitrary level (i.e. not knowing/specifying how deep the level is within the dimension/hierarchy or what it’s parents are) and then including all unknown ancestors above it.

Ancestors(Head(Filter([DIM_SALES].AllMembers,[DIM_SALES].CurrentMember.Level.Name = 'SALESPERSON_ID' and [DIM_SALES].CurrentMember.Name = 'SUB::SAS.UserId')).Item(0))

I’m likely to forget this so am jotting it down here in case I might need to use it as the basis for future OLAP member level security work. I don’t know about you but I always find MDX work is like mental gymnastics, better than sudoku :) , so I like to keep examples of MDX functions in action. I hope it might give you some ideas too.

Update 04Feb2011: Thanks to a post from Bob in the SAS discussion forum thread linked above I discovered the SAS MDX <!–CONDITION–> ‘operator’ today (looks like an XML comment!). It is used for specifying member level security permission conditions when you have more than one hierarchy in the dimension you are securing. I can’t find it in any of the SAS reference docs but there are a couple of usage notes that mention it:

  • SAS Sample 37136: Applying member-level security to a cube dimension that has more than one hierarchy
  • SAS Problem Note 13557: MDX restriction of default member may cause error when viewing cube
Author Paul HomesPosted on 26 January 201120 September 2024Categories SAS Metadata SecurityTags MDX, Member Level Security, Metacoda Security Plug-ins, SAS, SAS 9.2, SAS Metadata Security, SAS OLAP Server9 Comments on SAS 9.2 OLAP Cube Identity Driven Member Level Security
RSS Feed Follow me on Mastodon View my LinkedIn® profile Send me a message   Vertical separator   Visit the Metacoda web site

Metacoda - productivity through metadata visibility

Horizontal separator

Tags

  • Accounts/Logins
  • ACT
  • Active Directory
  • Base SAS
  • Best Practices
  • Blogging
  • Identity Sync
  • IWA
  • Kerberos
  • Linux
  • Logging
  • Metacoda Plug-ins
  • Metacoda Plug-ins Tip
  • Metacoda Security Plug-ins
  • Metadata API
  • Metadata Migration
  • Metadata Promotion
  • Metadata Security Testing
  • Mid-Tier
  • PAM
  • platformadmin.com
  • Roles & Capabilities
  • SAS
  • SAS 9.1
  • SAS 9.2
  • SAS 9.3
  • SAS 9.4
  • SAS Architecture
  • SAS Configuration
  • SAS Enterprise Guide
  • SAS Global Forum
  • SAS Information Delivery Portal
  • SAS Installation
  • SAS Management Console
  • SAS Metadata
  • SAS Metadata Security
  • SAS Papers
  • SAS Training
  • SAS Usage Notes
  • SAS Viya
  • SPN
  • Ubuntu
  • UNIX
  • Windows
  • Windows 2008 R2

Blog Roll [ ... and links to blog rolls]

  • [ … blogs.sas.com]
  • [ … SAS RSS Feeds]
  • NOTE: The blog of RTSL.eu
  • The SAS Dummy

Metacoda Links

  • Metacoda
  • Metacoda Security Plug-ins
  • Metacoda Support

SAS Communities

  • SAS Communities
  • Stack Overflow / SAS tag
  • Super User / SAS tag

SAS Institute Links

  • SAS
  • SAS Australia
  • SAS Customer Support

SAS User Groups

  • [ … other SAS user groups]
  • SAS Global Forum
  • SUGA

Categories

  • General
  • Guest Posts
  • Interesting SAS Usage Notes
  • Linux
  • Metacoda
  • Metacoda Custom Tasks
  • Metacoda Plug-ins
  • Metacoda Security Plug-ins
  • SAS Architecture
  • SAS Books
  • SAS Configuration
  • SAS Documentation
  • SAS Enterprise Guide
  • SAS Environment Manager
  • SAS Installation
  • SAS Management Console
  • SAS Metadata
  • SAS Metadata Security
  • SAS Open Metadata API
  • SAS Software
  • SAS Support Resources
  • SAS Training
  • SAS User Groups
  • SAS Viya
  • Solaris
  • VirtualBox
  • Windows

Archives

  • October 2023
  • September 2023
  • August 2023
  • March 2023
  • February 2023
  • March 2022
  • July 2021
  • May 2021
  • March 2021
  • October 2020
  • March 2020
  • June 2019
  • April 2019
  • March 2019
  • February 2019
  • October 2018
  • September 2018
  • August 2018
  • May 2018
  • February 2018
  • September 2017
  • August 2017
  • June 2017
  • April 2017
  • January 2017
  • July 2016
  • April 2016
  • March 2016
  • November 2015
  • September 2015
  • July 2015
  • June 2015
  • March 2015
  • February 2015
  • January 2015
  • October 2014
  • May 2014
  • March 2014
  • February 2014
  • December 2013
  • October 2013
  • September 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • Home
  • Reading List
  • About / Contact
  • RSS Feed
  • LinkedIn
  • GitHub
  • LinkedIn (Metacoda)
  • YouTube (Metacoda)

Copyright © 2010-2025 Paul Homes. All rights reserved. | Legal Notices | Admin