SAS Global Forum 2016 is just over 2 weeks away, and I’m really excited about showing a Permissions Tracer feature we’ll be releasing in the next version of our Metacoda Security Plug-ins. Metacoda is a SASGF sponsor again this year and we’ll be showing a preview of this new version at our Metacoda stand in The Quad, so please stop and say hello if you’re going to be there too.
We’ve had some very positive feedback about how helpful our Identity and Object Permissions Explorers have been, so I’m looking forward to getting some feedback on this new feature too. One of the other reasons I’m excited is that this is something we’ve been building up to for several years as we’ve expanded our code base to help visualize the richness of the SAS metadata security model, including its interacting object inheritance paths, user identity hierarchies, and role-implied special conditions.
So what business problems does the Permissions Tracer solve? It expands on the Permissions Explorers. The existing Permissions Explorers answer the questions “Which users have access to this object and what permissions do they have on it?” and “What objects does this person have access to and what permissions do they have on them?”. The Permissions Tracer is more about “Why does that person have those permissions on that object?” or, as is more often the case when a real need to trace permissions arises, “Why doesn’t that person have permissions on that object?”.
It is well known that a solid understanding of SAS metadata security, and the relative precedence of permissions through access control types, object inheritance trees, and group membership trees, usually takes a long time to acquire (being measured in months/years). As with many learning experiences it also comes from revisiting and understanding mistakes, sub-optimal solutions, and the impact of deviating from best practices. I’m hoping that this plug-in will help people to shortcut some of that learning. Remembering my own experiences, and from talking to other administrators too, unexpected permissions can come from a number sources:
- I didn’t realize that person was a member of that group (often due to complex group nesting).
- I didn’t realize that access control (ACT/ACE) had been applied to that parent object and was having an impact here.
- I didn’t realize that there was a conflict where a permission was both granted and denied to that person (often due to complex group nesting).
- I didn’t realize that that person was/wasn’t a member of that role and that the role had an impact there.
- I didn’t remember that the access control here has a higher/lower precedence than this other access control over here.
- I didn’t realize/remember/know that …
Suffice to say that misunderstandings often come down to not having enough information about the source of permissions, an understanding of the relative precedence of everything involved, as well as potential conflict resolution rules.
In planning this plug-in, we knew the simplest thing to show would be the end-result: the ultimate source of an effective permission grant/deny for a user on an object (we have been calling these Definitive permissions). Whilst I say “simplest to show”, if you’ve ever tried to gather all the required information from metadata and derive this, then you’d know how tricky it is (which goes some way to explaining why it took us a few years to release it even though it was one of the most frequently requested features from our customers!). At the same time, whilst showing the definitive permissions is useful, we also wanted this to be a learning tool where you could see all of the other permissions decision contenders that didn’t make the cut (being less important than other sources). I find that seeing all of the other access controls that were either not important enough, or not applicable, helps in reinforcing an understanding of the outcome (and ultimately why best practices work too).
Now, given that background info, I’ll discuss a few scenarios to show how we have implemented the Permissions Tracer. We wanted permissions tracing to be easily available from lots of different locations so it’s always nearby when you need it.
Tracing from the Permissions Tracer
Firstly, there is a dedicated Permissions Tracer plug-in that you can go to when that’s your primary goal. You search for and select an object, search for and select an identity (normally a user but occasionally a group), and then view the results. In the screenshot below we can see traced permissions for the user “Alice Adams” on a “Salaries” table in the “/Vegas Enterprises/HR/Data” metadata folder.
The top row (shown with precedence level zero) shows Alice’s effective permissions on the table – the end result. All of the other rows represent traced permissions that either contribute to, have the potential to contribute to, or help to explain that effective permissions outcome. This is where you look to see the things you expect to see whilst keeping an eye out for surprises that might explain any discrepancies you are experiencing. The traced permission rows include things such as:
- Direct ACEs (explicit permissions) applied to the Salaries table, for Alice herself or any of the groups in her identity hierarchy (including direct membership, indirect membership through nesting, and implicit membership of SASUSERS and PUBLIC).
- Permissions, for Alice or any group in her identity hierarchy, contained in any Direct ACTs applied to the salaries table itself.
- Permissions, for Alice or any group in her identity hierarchy, from Indirect ACEs (explicit permissions) applied to any parent object of the Salaries table (in the object inheritance path).
- Permissions, for Alice or any group in her identity hierarchy, contained in any Indirect ACTs applied to any parent object of the Salaries table (in the object inheritance path).
- Permissions, for Alice or any group in her identity hierarchy, contained in the Repository ACT (when there is a repository ACT).
- Any Default permission denials used when there is a Repository ACT but the Repository ACT does not specify whether a permission should be granted or denied.
- Any Default permission grants used when there is no Repository ACT and no other applied access control specifies whether a permission should be granted or denied.
- Role-Implied permissions seen when membership or non-membership of a role triggers some automatic or implied grants or denials. These can be seen when the target object is a user, group or role. The role-implied permissions will depend on whether the user is, or is not, a member of one of the special roles “Metadata Server: Unrestricted” and “Metadata Server: User Administration”
- Definitive permissions are the deciding permissions – the ones that explain the effective permissions. These cells have an orange background colour. If there are any permission columns that contain multiple definitive/orange cells it means there are multiple permissions with the same precedence/importance and there is the potential for a conflict situation if some grant and some deny.
- Intermediate Effective rows (hidden by default) show the effective permissions for each parent object in the Salaries table object inheritance path. Sometimes it is useful to show these to see at what level an effective permission switches from a grant to a denial or vice-versa.
- Inapplicable permissions (also hidden by default) are permissions for other users and for groups that Alice is not a direct or indirect member of (i.e. not present in her identity hierarchy). Sometimes unexpected permissions arise because a user is not a member of a group you thought they were, and the permission granted or denied to that group turns out to be inapplicable as a result. If you don’t see the explanation you were expecting in the traced permissions table, turning on the display of Inapplicable permissions might provide the additional clues you need.
Background colours are used to highlight the different types of permission sources, and if necessary you can hide or show different types of rows using the checkboxes above the table.
You might also noticed that all of the rows in the table are assigned a precedence level and reordered in terms of importance. Lower numbered precedence levels are for permissions that are more important than those with higher numbered precedence levels. Sometimes, in conflict situations, you will see rows that have the same precedence level but some rows grant and some rows deny the same permission. Later in this post I’ll show an example of a conflict with multiple definitive sources that control the outcome for a permission (which is shown as multiple orange background cells in a permission column).
As you can see there are lots of possible places permissions can come from, with some obscure and not widely known. The SAS metadata security model is complex because of it’s richness and flexibility. This is why I see so much value in displaying everything in the Permissions Tracer and not just the definitive and effective permissions. Seeing the bigger picture helps to highlight any gaps in someone’s understanding of their own security implementation as well as the SAS metadata security precedence and conflict resolution rules. Finding and understanding those gaps is a useful learning tool.
Tracing Permissions from a Reviewer
The Permissions Tracer plug-in can be useful when your initial goal is to choose an object and identity and trace their permissions on that object. At other times you might not have originally started with a need to do permissions tracing, but it may have occurred to you when you were elsewhere looking at an object or a user in one of the other plug-ins. To avoid you having to backtrack to the Permissions Tracer plug-in and reselect the object and identity, we also provide access to the Permissions Tracer feature from within several of the other plug-ins too.
Perhaps you are in the User Reviewer and asking yourself what effective permissions would this user have on object Y and why are they different to what I had expected (perhaps the user has just phoned you to ask why they have no access). Alternatively, looking at it from an object perspective, you could be in the Protected Object Reviewer and be wondering what would be the effective permissions on this object for user X. In either case you can right click over the user or object and select the Permissions Tracer item from the popup menu.
In the screenshot below we want to do permissions tracing whilst looking at the “/Vegas Enterprises/HR” folder from within the Protected Object Reviewer:
Selecting the Permissions Tracer menu item will display a Permissions Tracer dialog with the object pre-selected as shown below.
We haven’t picked an identity yet, so we start out with a view of all of the potentially relevant access controls all the way up through the HR folders object inheritance path.
The effective permissions for a user on an object is derived from consideration of the user’s identity hierarchy (group membership tree and some key role memberships) and how it relates to the access controls at various levels in the object’s inheritance path. To see effective permissions, and the relative importance of those access controls (via precedence levels), the next step then is to search for and choose a user, in this case “Alice Adams”:
After selecting Alice the contents of the table will then change to show Alice’s effective permissions on the HR folder together with all of the traced permissions.
Tracing from an Effective Permissions Explorer
In another example you might already be looking at effective permissions for a combination of a user and an object, in either the Object Permissions Explorer or the Identity Permissions Explorer, and be thinking why are these permissions different to what I was expecting. In these plug-ins you can right click over the effective permissions row, or an access level badge, and select the Permissions Tracer item from the popup menu and immediately see all applicable permissions and precedences for that combination of user and object.
Tracing Conflicting Permissions
In this next example I thought I would show permissions tracing for a conflict scenario. We often get asked about helping to find and identify permissions conflicts. This is an example of the type of conflict that can occur when you don’t follow the best practice of only ever denying permissions to the implicit groups (PUBLIC or SASUSERS). You’ll find this best practice as one of the 6 Danish Golden Rules for SAS metadata security. You can find a similar example of what can go wrong when you don’t follow this best practice in my SAS ANZ Forum 2010 paper: Best Practices with SAS® 9 Metadata Security
The Permissions Tracer dialog below shows that Euan has an effective denial of the RM (ReadMetadata) permission on the folder (so it is effectively hidden from him). We can also see a conflict in the RM column with 2 Definitive permissions: one is an explicit denial for the “Vegas Enterprises: Power Users” group and the other is an explicit grant for the “Vegas Enterprises: Data Scientists” group. Given both have the same precedence level we can deduce that those groups appear at the same level in Euan’s identity hierarchy (the SAS metadata security rules will therefore deny the RM permission as we have a conflict with the same type of direct access control (ACE) for groups at the same level in the identity hierarchy).
Because it is useful to be able to review the user’s identity hierarchy and the object’s inheritance path when tracing permission we include these as additional tabs in the Permissions Tracer. Here is the contents of the Identity Hierarchy tab for Euan that confirms he is a direct member of both of those groups (and incidentally the Data Scientists group is also a member of the Power Users group).
Here is the contents of the Object Inheritance tab for the folder that shows all of the parent objects that it can inherit permissions from.
This screenshot shows what we see when we tick all of the checkboxes and include the normally hidden Intermediate Effective and Inapplicable rows. Euan is not a member of the “SAS Administrators” and “SAS System Services” groups, which is why those rows are inapplicable.
Earlier I mentioned there are also some special circumstances where membership or non-membership of certain SAS metadata roles will also have an impact on effective permissions. We call these Role-Implied Permissions in the Permissions Tracer and I thought I would finish off with a couple of examples where you might see those.
In this first one we are tracing permissions on the “Metadata Server: Unrestricted” role for an unrestricted administrator. Being an unrestricted user means you are automatically and implicitly granted all permissions on all objects (regardless of the access controls that are in place). You can see these role-implied unrestricted grants shown below with a pale-red cell background colour (we have turned off the Definitive permissions display here for clarity otherwise both of those cells would also be orange).
This next example traces permissions for the same “Metadata Server: Unrestricted” role but this time for a restricted user administrator (a direct member of the “SAS Administrators” group and an indirect member of the “Metadata Server: User Administration” role). Restricted user administrators cannot manage the unrestricted role and cannot manage unrestricted users otherwise they would be able to promote themselves to unrestricted. As shown below there is a role-implied WM (WriteMetadata) denial (arising from non-membership of the unrestricted role) that overrides the otherwise expected grant for “SAS Administrators”.
This has been a very long post (on a complex topic) so thank you for sticking with me if you’ve got this far! :)
I hope you’ve found the post useful and are as excited to try it out as I am to demo it. If you’re going to SAS Global Forum 2016 please stop by the Metacoda booth in The Quad so you can see it in action and share your own experiences.
If you can’t make it to SASGF I’d still like to hear from you, so please leave a comment below and let me know if you have any questions or feedback.
Before long we’ll also be contacting beta testers to see if they’d like to try out the upcoming Metacoda Plug-ins 6.0 release, so if you want to participate please let me know.