By Chris Hyzer, University of Pennsylvania and Chair of the Grouper Project
Grouper is an enterprise group and access management platform that provides critical features to ensure the right people have access to what they need. Grouper is part of the InCommon Trusted Access Platform, an identity and access management suite of software designed to integrate with existing systems.
Many of the exciting new features in Grouper come from needs that we learn about when a community member gets in touch and shares their use case. Our friends at Georgia Tech suggested an advanced access control approach, using scripted groups, and we realized incorporating the new capabilities into Grouper could have broad benefits. A starting point for this feature is being rolled out in Grouper version 2.6.6+. “Scripted groups” are groups that are defined by a script based on group memberships or user attributes. The script can be thought of as the access policy.
The new access control feature partially implements Attribute Based Access Control (ABAC). This is the part of ABAC that defines who is included in a policy based on attributes of those users. For example, you might want to define a population for a policy based on those users’ attributes. For example, the policy is applicable for users who are primarily employees, enrolled in multi-factor authentication (MFA), and have been trained in FERPA.
Other parts of ABAC are resource attributes (e.g. files which are marked as “top secret” or amounts less than $10,000) and environment attributes (e.g. time of day or user source IP address). Resource and environment attributes are not covered in scripted groups and can be taken into consideration with Grouper permissions or by the service which has protected resources.
Grouper already fully implements Role Based Access Control (RBAC). RBAC has various features but centers around roles (collections of users who are allowed to do something), hierarchy of roles (SuperAdmin can do what Admin can do and more), etc. Obviously there is a gray area here, but for the purposes of this blog, since a group is scripted based on user attributes and kept up to date, then the needle is moving from RBAC over to ABAC.
It has been posited that Grouper memberships can be thought of as attributes (memberOf), so Grouper policies stitched together with composites are similar to ABAC. A “composite” is a group which is composed of two factor groups using group math (intersection, minus, or union). An example of a composite is “employees in MFA” which is an intersection of the employee group and the MFA group. However, policies should be able to more easily be configured than how composites are currently structured. Enter scripted groups based on other memberships or user attributes.
Over the years other people have asked these questions about Grouper, and now we finally have better answers.
Can access policies be configured with natural language?
Ideally we would want a business analyst to speak to Grouper and the access will happen. We aren’t there quite yet but we can make strides in that direction. Starting with natural language, perhaps we can have a scripted dialect but be able to translate from something less “programmy.” So this might be the eventual script “Jira admins who are employees”:
Note that Grouper leverages the Java Expression Language (JEXL) engine and language for scripting. We can allow some shortcuts so policy scripts can be more natural (e.g. ‘member of’ instead of ‘memberOf’, or ‘and’ instead of ‘&&’). Reference groups could benefit from labels to make a term for the institutionally meaningful group (e.g. ‘employee’ instead of ‘ref:employee’). This makes the “script” accessible to less technical users. Imagine typing this into the Grouper UI and achieving the same result:
Member of employee, and member of app:jira:jiraAdminsManual
Can we have composites which have more than two factors?
Of course you could have an arbitrary number of groups specified with more options for the group math. Here is a script for a group with three groups intersected “Jira admins who are employees and enrolled in MFA”:
Member of employee, member of app:jira:jiraAdminsManual, and member of mfa
I cannot use ‘department’ for reference groups, I need ‘department’ coupled with ‘affiliation’, but do I have to pre-load the cartesian product of those groups when only a fraction will be used?
Here is an example based on user attributes “English department staff who aren’t in the global lockout group”:
Has affiliation attribute with name of staff and dept of english,
but not a member of lockout
The corresponding (generated) JEXL script would look like this:
entity.hasAttribute(‘affiliation’, ‘name==staff && dept==english’)
Can grouper have “dynamic groups?”
Grouper pre-computes all members so it is ready to quickly answer questions about access. If you want to know more details about this design, buy me a beer at an upcoming conference. Sometimes policies expressed in natural language can be thought of as “dynamic”.
It’s not the timing of when the decisions are computed, it’s the configuration of a script and the expectation that the access decisions are consistent with the data. Grouper knows when group memberships change and can also be alerted when user attributes change, allowing up-to-date access enforcement. i.e. you do not need to schedule each scripted group like a Grouper Loader job. Grouper will take care of it for you in near real-time.
How can we get rid of “intermediate” groups?
Intermediate groups are groups that exist to build another group (usually a policy group used in an application). Intermediate groups do not serve another purpose and clutter the Grouper folders and perhaps confuse users (here is something that you should not use). Well, if you can script a policy on one group, and the previous strategy was to use composites with max two factors, then you can see how you will have a less confusing Grouper registry since the intermediate groups will not be there anymore. i.e. previously a three factor intersection would require one intermediate group (intersect two groups into an intermediate group, and intersect that with the third group). During an analysis of the scripted group (to troubleshoot or verify), or a visualization, you could imagine Grouper describing the policy in logical parts with aggregate counts, but those discrete pesky bloated intermediate groups will not actually exist.
Can end users manage loader jobs securely?
Previously, there were security risks with non-admins configuring loader jobs, or entering JEXL scripts. This is due to SQL and JEXL being open ended and it is possible and easy to break out of the intended bounds of the delegation. With this new JEXL scripted approach, the script will be parsed to ensure that no Java classes are being used which shouldn’t be. Utility methods will be carefully scrutinized and allowed in the script. The groups being referenced in the script are detected and checked to see if the user has the READ privilege on those groups. Now end users can configure scripted groups securely!
Is there a better way to do real-time loader jobs?
The Grouper Loader has a way to do real-time updates based on changes in the source data, but it is a little tedious to set this up and test for many jobs. With scripted groups, there are two cases of real time updates. First if the script is based on group memberships, of course Grouper knows about changes of “factor groups” and will quickly update the scripted policy group in an incremental way. Second is attribute data. A recent addition to Grouper is the entity global attribute resolver which pulls in attribute data for users from SQL or LDAP in a generic way that can be used for various Grouper features such as provisioning. That entity resolver can specify how changes are communicated to Grouper, and then each scripted policy group can leverage the same speed for how updates are applied. There would be no need for the policy writer to configure anything to leverage real time updates.
Can we reduce the number of loader jobs we have?
Yes! Loaders are currently used for ABAC when it is too difficult to build a group with composites. Those will not be needed anymore. Also some loaders use attribute data to set up basis and reference groups that might not be necessary depending on the choices you make when setting up your community data and entity resolvers.
How can we express access policies more quickly?
There is a lot of work required to set up intermediate groups, include/exclude, requirement groups, and allow/deny manual groups into a policy. Over the years Grouper has refined some features to help in this area including: rules, hooks, templates, move/copy, import/export, and GSH scripts. But now if the common groups and policy language are well documented and people are properly trained, entering in a policy statement or script will be a lot more efficient than the previous strategies.
Can we visualize the query in a loader job?
No, that is a problem with the Grouper Loader but not with scripted groups. As a first pass we will be able to visualize all the groups that make up the scripted group. After that we can take a subset of the available script language, and if the policy conforms to what is visualizable, then a diagram representation of the policy can be displayed. Of course these are accessible so a text version of the representation is available as well.
Consider this policy for the group jiraAdmins:
Member of employee, member of MFA, and member of app:jira:jiraAdminsManual, but not a member of lockout or app:jira:jiraLockoutManual
This could be visualized as:
There are a lot of possibilities with scripted policy groups and the first pass in Grouper 2.6.6+ only scratches the surface. See more details on Grouper Attribute Based Access Control (ABAC) with JEXL script loaded groups at this wiki page including the current progress and plan. If you are interested in using scripted groups or have requirements you would like to see included, please Slack us with your use cases in the InCommon-Grouper channel. If you’d like to be added to this Slack channel, please use this form. You are invited to review the overall Grouper Roadmap at this wiki page.
The Grouper team thanks our amazing Grouper community for your continued support and contributions. A lot of community conversation about Grouper happens these days on our InCommon-Grouper Slack channel.