Include Page | ||||
---|---|---|---|---|
|
Overview
To implement access policies, it has often been necessary to set up intermediate groups, include/exclude, requirement groups, and allow/deny manual groups. Grouper has features to help in this area including: rules, hooks, templates, move/copy, import/export, and GSH scripts.
The ABAC with scripted groups feature is designed to offer increased efficiency in implementing access policies. It's important for the common groups and policy language to be well documented and people to be properly trained.
JEXL loaded groups
In Grouper v2In Grouper 2.6.6+ there is a first pass at JEXL loaded groups using memberships of groups only. In v5+ scripted groups can also be based on entity data fields. It is basic and can be built on. Note: this is subject to change as we see a working solution and discuss the optimal path forward.
Info | ||
---|---|---|
| ||
For more info, see the February 2022 blog on Attribute Based Access Control with Grouper. |
Expression language (JEXL) scripts facilitate implementing the part of ABAC that defines who is included in a policy based on attributes of those users. Other parts of ABAC such as resource attributes or environment attributes can be taken into consideration with Grouper permissions or by the service which has protected resources.
We want to be able to craft policies by an expression instead of creating loaders or tons of reference groups based on cartesian products of basis/ref groups.
...
- Reduces pre-loaded rollups that might not be used
- You don't need a loader job for each one of these groups
- Any Grouper user could edit the policies if they can READ underlying groups. The expressions are secure (future state)
- The memberships of the ABAC groups are near real time based on an intelligent change log consumer (future state)
- You can have a UI to help build it and give good error messages
- Could visualize the policies. Perhaps could be integrated into existing visualization (future state)
- This solves the issue of composites with any number of factors
UI to configure
Daemon screen
Note in Grouper v2.6.6 you need to wait an hour after changing a script, or run the JEXL script loader full job. In the future we will have an incremental and run the full nightlyv5+ an incremental job will adjust the members quicker. Note: there is one full daemon and one incremental daemon that handles all of the JEXL script ABAC groups. You do not add this, it is built-in
Scripts
The script can only be written by people who can READ groups in the script and UPDATE the owner group. Since this is actually a JEXL script (not a JEXL expression), so you could have multiple lines, variables, conditionals, etc
...
You can use entity.memberOf('full:group:id:path') exactly like that to see if user is in a group or not.
Expression | Description | ||||
---|---|---|---|---|---|
| Three part intersection. Full time staff in MFA | ||||
| Example policy That means users who are not in globalLockout and not in vpnManualLockout |
How it works
There are some trade-offs with performance and resources. This is the current implementation.
- Sees which groups are in the script
- Get the memberships of the owner groups and all script groups
- Consider if configured to include internal subject sources (adjust the membership lists)
- For each member of either the owner group or the script groups for that owner
- Setup the variables for a JEXL script
- Evaluate the script
- If the result does not match the current state of the membership, add or remove
- If a script evaluation fails, proceed with the job
TO DO
- Load groups as members
- Add incremental job
- Unit tests
- Better validation
- More methods to call (other than hasMember)
- Add subject attributes e.g. from global attribute resolver
- Failsafes
- Add delegated admin based on READ of groups
- Visualization
...
Feed the expression through this simple program
Code Block |
---|
public static void main(String[] args) {
JexlEngine jexlEngine = new JexlEngine();
ExpressionImpl expression = (ExpressionImpl)jexlEngine.createExpression("group.campus !~ ['palmer', 'southern'] and group.termStart - 7 > sysdate");
ASTJexlScript astJexlScript = (ASTJexlScript)GrouperUtil.fieldValue(expression, "script");
printNode(astJexlScript, "");
System.out.println(expression);
}
public static void printNode(JexlNode jexlNode, String prefix) {
System.out.println(prefix + jexlNode.getClass().getSimpleName() + (StringUtils.isBlank(jexlNode.image) ? "" : (": " + jexlNode.image)));
String newPrefix = StringUtils.isBlank(prefix) ? "- " : (" " + prefix);
for (int i=0;i<jexlNode.jjtGetNumChildren();i++) {
printNode(jexlNode.jjtGetChild(i), newPrefix);
}
}
|
Output
Code Block |
---|
ASTJexlScript
- ASTAndNode
- ASTNRNode
- ASTReference
- ASTIdentifier: group
- ASTIdentifier: campus
- ASTReference
- ASTArrayLiteral
- ASTReference
- ASTStringLiteral: palmer
- ASTReference
- ASTStringLiteral: southern
- ASTGTNode
- ASTAdditiveNode
- ASTReference
- ASTIdentifier: group
- ASTIdentifier: termStart
- ASTAdditiveOperator: -
- ASTNumberLiteral: 7
- ASTReference
- ASTIdentifier: sysdate |
Grouper can take that object model and see which group and subject attributes are related, print out a nice analysis of the policy, and know which policies are affected by real time changes
Expression 2: campus is palmer or southern, or the term is current with some overlap
Code Block |
---|
group.campus =~ ['palmer', 'southern'] or (group.termStart - 7 > sysdate and group.termStart - 7 < sysdate) |
...
Code Block |
---|
ASTJexlScript
- ASTOrNode
- ASTERNode
- ASTReference
- ASTIdentifier: group
- ASTIdentifier: campus
- ASTReference
- ASTArrayLiteral
- ASTReference
- ASTStringLiteral: palmer
- ASTReference
- ASTStringLiteral: southern
- ASTReference
- ASTReferenceExpression
- ASTAndNode
- ASTGTNode
- ASTAdditiveNode
- ASTReference
- ASTIdentifier: group
- ASTIdentifier: termStart
- ASTAdditiveOperator: -
- ASTNumberLiteral: 7
- ASTReference
- ASTIdentifier: sysdate
- ASTLTNode
- ASTAdditiveNode
- ASTReference
- ASTIdentifier: group
- ASTIdentifier: termStart
- ASTAdditiveOperator: -
- ASTNumberLiteral: 7
- ASTReference
- ASTIdentifier: sysdate |
| Exclusive OR This is VPN users not in MFA and MFA users not in VPN: |
How it works in v5+
The script is parsed and converted to SQL. The results represent the members of the group. The diffs will be added or removed from the group.
Expression 3: campus is palmer or southern, or the term is current with some overlap
Code Block |
---|
person.primaryAffiliation =~ ['faculty', 'staff'] and person.dept =~ ['physics', 'math'] |
...
Code Block |
---|
ASTJexlScript
- ASTAndNode
- ASTERNode
- ASTReference
- ASTIdentifier: person
- ASTIdentifier: primaryAffiliation
- ASTReference
- ASTArrayLiteral
- ASTReference
- ASTStringLiteral: faculty
- ASTReference
- ASTStringLiteral: staff
- ASTERNode
- ASTReference
- ASTIdentifier: person
- ASTIdentifier: dept
- ASTReference
- ASTArrayLiteral
- ASTReference
- ASTStringLiteral: physics
- ASTReference
- ASTStringLiteral: math |
Analyze policy
To confirm a policy is correct, a long form translation of the policy can be displayed along with group names and group counts
Full sync
A nightly full sync will occur. The incremental sync should stop. Make sure all the loaded groups are up to date.
Incremental sync
An incremental change log consumer can
...
Policy patterns
Your institution can make a GSH template that will help users setup policies
TODO document this
See Also
Access Management Features Overview
...