What happens when you assign a Role to a User

With the release of IDM 3.6 and the RBPM (Roles Based Provisioning Module) in the 3.7 version of User Application, the approach of using Roles to grant permissions began to take form.

This was modified with the addition of Resources in UA 3.7 which was a fairly big change.

Originally, a Role granted another Role, eventually one of those Roles granting an Entitlement. With the addition of Resources an extra abstraction layer of Resources was added.

The basic benefit of a Resource is that it has a name, a description, and carries a value to place in the Entitlement.

Whereas a single Group entitlement object can support every group in the target system, potentially thousands of them, you would need to create a Resource for every Group you wanted to statically grant. You could of course leave the specific value definable at grant time but that makes automation kind of hard.

This extra abstraction can be a bit annoying, specifically since you could now need thousands of Resource objects to represent all the possible groups. However, previously you would have had to assign the group info into the Entitlement grant on the Role, so it is not per se that big a difference, it just seems like a big step.

Now the model would be something like the following:

Level 30 Role (Business Role) representing the users Department is granted (somehow).
There is a Level 10 (Permission Role) that is a child Role to the Level 30.
There is a Resource with an entitlement value statically defined assigned to the Level 10 Role.
The user is granted the Level 30 Role.

The user now gets the Role granted by some fashion. This can be done many ways, here is a list of some of the possibilities:
The Role being assigned to a Container that the user resides in.
The Role being assigned to a Group the user is a member of. (Of which the user is a member? Dangle you participle! Dangle!)
The Role being assign to a Dynamic group the user is a dynamic member of.
The Role being directly assigned to the user.

In the direct assignment to the user, this can happen a number of different ways.

Someone could use the User Application (the newer IDM Home, just redirects you back to the User Appl to do it) interface as a Role Manager or Administrator and assign it by hand. The user could make a request via IDM Home of the User application and if an approval is needed and granted will get the Role assigned.

An automated system could use SOAP to call the Web services API User Application supports and make the requestRolesAssignment() call. An IDM driver can use the token Add Role (which under the covers makes the same SOAP call). A workflow can be used that after filling out the form, getting needed approvals, grants the role, which ultimately uses the same SOAP API to make the call under the covers.

As you can see there are many possible ways to get to the same endpoint.

Once any of these things happen, the User Application makes an nrfRequest object. The User App objects are stored in a container under the User Application IDM Driver object. There is a Requests container, under the RoleConfig container in Appconfig, for a DN that looks sort of like this:

cn=Requests,cn=RoleConfig, cn=AppConfig, cn=UserApplication, cn=dset, ou=idm, ou=system, o=acme

The objectClass is nrfRequests. Each object is named with a datestamp and a GUID, that is unique. I thought it would be the correlationID of the event that generated it but looking at the object, I think the correlationID is different.

This leaves with an object named something like:
cn=20170106110948-cc9d8af089ec4444a8e89a9aa3435a75-0,cn=Requests,cn=RoleConfig, cn=AppConfig, cn=UserApplication, cn=dset, ou=idm, ou=system, o=acme

An LDIF of a sample object looks something like this.

dn: cn=20170106110948-cc9d8af089ec4444a8e89a9aa3435a75-0,cn=Requests,cn=RoleC
onfig, cn=AppConfig, cn=UserApplication, cn=dset, ou=idm, ou=system, o=acme
nrfStartDate: 20170106160948Z
nrfCategory: 25
nrfRequester: cn=geoffc,ou=admins,ou=system,o=acme
nrfTargetDN: cn=RL10-AD-PLC-TicketingUsers,cn=Level10,cn=RoleDefs,cn=RoleConf
nrfSourceDN: cn=D-111100,cn=Department,cn=Level30,cn=RoleDefs,cn=RoleConfig,c
nrfCorrelationId: UserApp#RoleRequest#2911ddf2-8404-4936-a2a0-8e3933a5a43b
objectClass: nrfRequest
objectClass: Top
nrfImmediate: TRUE
cn: 20170106110948-cc9d8af089ec4444a8e89a9aa3435a75-0
nrfDescription: 10 to 30 mapping
nrfOriginator: uaadmin
nrfStatus: 0
nrfRequestDate: 20170106160948Z

You have an nrfTargetDN, i.e. the Role being granted. An nrfSourceDN for the other object. In this example it is a Level 10 Role being made the child role of a Level 30 Role.

These objects are then worked upon by the Roles and Resource Service Driver (RRSD) that then does the work of granting the Roles as appropriate. I tried to work through a bunch of those examples in a series of articles I wrote:

Following a Role Grant in the RRSD Driver – Part 1
Following a Role Grant in the RRSD Driver – Part 2
Following a Role Grant in the RRSD Driver – Part 3
Following a Role Grant in the RRSD Driver – Part 4

Needless to say, there is a lot of stuff going on, in RRSD when one of these nrfRequest objects get created.

I thought in this article I would take a different approach and instead focus on what happens to the User object, and what attributes get populated and what the values look like and mean. I find this is an aspect that is totally undocumented and if you ever need to troubleshoot what is going on, you will have no idea what a success looks like or what a failure might look like. I hope this approach turns out to be valuable to someone. I do it because I was curious and looking and realized it would be nice to see it all written down.

Now having said that, it looks like it should be easy to reproduce this work on your user 'by hand' in a driver or in an LDIF to manually assign Roles, not via the SOAP interface but rather via direct manipulation of the attributes. I agree it looks easy, but I have been told that there is some hidden magic we do not see, that would be broken by a direct attribute approach. Nonetheless, I have heard tale of folk doing it and it seems to work, so I do not know which is correct.

I once tried to find out, what RRSD looks at, specifically, when it re-evaluates a user and updates it to the correct set of Roles. That is, RRSD is not event driven, in the traditional IDM sense. Normally a driver sees an update, if the object is associated, it sends just the modify event and does what is required. RRSD acts as though every request is a synthetic add, and looks at all the attributes and recalculates the final Roles and Resources that should be assigned, and updates the user to match.

The question then becomes, what is RRSD looking at on a User, to decide it should have a Role assigned or not. My initial theory was the nrfRequest object. You can easily search for any nrfRequest whose nrfTargeDN is this user. But then you should repeat for every group the user is a member of for Group Role assignments. Dynamic groups are different as there is no attribute on the User indicating it is a member, instead you have to query the group member list to see if this user is in it. Container Role assignments are potentially the same but easier since there are usually not that many containers in a DN.

However, it seems like nrfRequest objects get cleaned up, so I remain unclear on what RRSD is specifically looking at, after all, it needs to know when to Remove or Revoke a grant. I wonder if maybe that is the answer? RRSD never removes a Role, it only Revokes it. That is, keeps the nrfAssignedRoles (or whatever attribute is being used) but change the nameSpace/State component (usually 1 for granted, 0 for revoked) from 1 to 0. Thus the user stores the info on themselves. Of course if a user is 'cleaned up' there is no good way to recover Role assignments at that point, since the info is not stored on the Role, like would be in the case of the reciprocal attributes involved in Groups and Group membership.

However, I wanted to show the attributes you might see on a user. Starting with a simple case of a direct assignment of a Level 30 Business Role to a user. This Role has a Resource assigned, that grants an Entitlement with a specific Group DN. I made a custom entitlement that grants eDirectory (in the IDV) group memberships using entitlements. If you need this, I have a package handy I can share that does this nicely, just add it to a Loopback driver and you are good to go.

First we get the nrfAssignedRoles set on the user, since this Role was directly assigned to the user. There is nrfContainerRoles for inherited from container examples. There is nrfDynamicGroupMembership and nrfGroupRoles for the two kinds of Group Role inheritances.

If you are added to a Level 30 role that has a Level 10 Role as a child, then the nrfAssignedRoles would show the Level 30, and the nrfInheritedRoles would show the Level 10. This differs from inheriting a Role from a Group.

All examples of attributes are shown in LDAP format, so the three components are separated by a pound sign (#).


Here is the raw attribute.


Here it is expanded to make it easier to read and the XML reformatted.


As you can see, I set a start and expiration date in my assignment, and those values get passed through into the attribute payload. Also the request time, requestor, and request description are stored as well. You can search for this kind of info and parse this in policy if need be, it just takes a few steps. But that is a topic for another article.

As a shortcut, I think the RRSD adds this attribute:


This allows a more simple query, to periodically check and see if there are any expired Roles that need to be revoked. You can see this sort of approach in the WorkOrder Driver, and how I intercepted it to make it faster with a simple add on policy in a package I made that uses an LDAP query for DirXML-nwoDueDate instead of reading every DirXML-WorkOrder and comparing the DirXML-nwoDueDate to the current time. The RRSD driver does not use an IDM query, it goes straight to eDirectory for this poll via JClient so I cannot intercept it and make it faster.

Now since this Role has a Resource assigned, the user gets that as well and it is stored in this attribute:

Here is the raw attribute, one very long line.

cn=TT2,cn=ResourceDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme#2#<assignment><start_tm>20170118215750Z</start_tm><req_tm>20170118215750Z</req_tm><inst-guid>95b08e1126664fd0af381b3983014b45</inst-guid><req>cn=uaadmin,ou=admins,ou=system,o=acme</req><req_desc>Created by the Role Driver</req_desc><ent-ref>&lt;?xml version="1.0" encoding="UTF-8"?>&lt;ref> &lt;src>UA&lt;/src> &lt;id/> &lt;param>{"ID":"\\CORP-IDMDEV\\acme\\groups\\TestingGroup"}&lt;/param> &lt;/ref> </ent-ref><ent-dn>O=acme\OU=system\OU=idm\CN=dset\CN=Test Assignment\CN=Testing</ent-dn><cause><type>role driver</type></cause></assignment>

Here it is expanded to make it easier to read and the XML reformatted.

<req_desc>Created by the Role Driver</req_desc>
<ent-ref>&lt;?xml version="1.0" encoding="UTF-8"?>&lt;ref> &lt;src>UA&lt;/src> &lt;id/> &lt;param>{"ID":"\\CORP-IDMDEV\\acme\\groups\\TestingGroup"}&lt;/param> &lt;/ref> </ent-ref>
<ent-dn>O=acme\OU=system\OU=idm\CN=dset\CN=Test Assignment\CN=Testing</ent-dn>
<type>role driver</type>

Again you can see the times (note no Expiration time, Resource grants do not support that, the Role is what sets expirations) and some of the info. I think cause is interesting as it tells us the grant was by the role driver as opposed to a direct assignment in User App or a Workflow.

Inside the <ent-ref> node is:
&lt;?xml version="1.0" encoding="UTF-8"?>&lt;ref> &lt;src>UA&lt;/src> &lt;id/> &lt;param>{"ID":"\\CORP-IDMDEV\\acme\\groups\\TestingGroup"}&lt;/param> &lt;/ref>

Which works out to:
<?xml version="1.0" encoding="UTF-8"?>

This makes sense, as when we look at the attribute that is the Entitlement grant, we see that in it.


The raw attribute.

cn=Testing,cn=Test Assignment,cn=dset,ou=idm,ou=system,o=acme#1#<?xml version="1.0" encoding="UTF-8"?><ref> <src>UA</src> <id/> <param>{"ID":"\\CORP-IDMDEV\\acme\\groups\\TestingGroup"}</param> </ref>

Here it is expanded to make it easier to read and the XML reformatted.

cn=Testing,cn=Test Assignment,cn=dset,ou=idm,ou=system,o=acme
<?xml version="1.0" encoding="UTF-8"?><ref>

That looks the same as the ent-ref in the nrfAssignedResources. In fact if you looked at the nrfResource object, you would see an attribute nrfEntitlementRef that has this same value on it.

I.e. The assignment of the Entitlement to a Resource, sets the nrfEntitlementRef value on the Resource object. The grant of a Resource, copies that value into the ent-ref node of the nrfAssignedResources attribute. This is then copied into the DirXML-EntitlementRef attribute.

Alas, modifying this value on the nrfResource value causes all sorts of issues. For one thing the RRSD does not event on this change and will not go and update all the users with the Resource assigned. Thus the functionality was removed from the IDM Home interface, even if the ability to change the entitlement (and its value) is still there in the older User Application interface. Same applies if you raw edit the attribute. We actually had a customer here a change like this was made, and it broke those Resources in a way we could never fix, and ended up having to delete them. Again this hints at more than just the raw attributes being consumed.

For each Resource action, you get a history in this attribute.


cn=TT2,cn=ResourceDefs,cn=RoleConfig,cn=AppConfig,cn=UserApplication,cn=dset,ou=idm,ou=system,o=acme#1#<history><action_tm>20170118215750Z</action_tm><req_tm>19700118042616Z</req_tm><req>cn=uaadmin,ou=admins,ou=system,o=acme</req><req_desc>Created by the Role Driver</req_desc><action>granted</action></history>

Here it is expanded to make it easier to read and the XML reformatted.

<req_desc>Created by the Role Driver</req_desc>

This just gives us a record of what happened and when.

It seems that every Role is listed in the nrfMemberOf attribute, and SecurityEquals is set so that they can be used like Groups for permission granting if desired.



I did not have an nrfInheritedRoles example in there, but you get the basic idea of the set of attributes that a Role grant can add to a user. Most of these attributes are part of the nrfIdentity object class.

If this helps you, please leave a comment, as I am always curious to know if it helps.


How To-Best Practice
Comment List
Parents Comment Children
No Data