Walking through the Office 365 IDM driver – Part 10

over 7 years ago

In part one of this series I walked through some of the configuration, Packages, and GCVs used in the Office 365 IDM driver.

In part two of this series I walked through more of the GCVs and looked at some possible values for the License entitlements.

In part three of this series I looked at the Filter and Schema Map and some more entitlement issues.

In part four of this series I looked at the configuration settings and then on to actual policies, getting through the Subscriber Event Transform policy set.

In part five of this series I worked through the Subscriber Match and Create policy sets.

In part six of this series I started in on the Subscriber Command Transform policy set.

In part seven of this series I continued through the EntitlementsImpl policy in the Command Transform.

In part eight of this series I finished up the Command Transform and started into the Output Transform.

In part nine of this series ( ) I finished walking through the Output Transform.

In part ten of this series I intend to start down the Input Transform policy set.

There are ten policies in the Input Transform, some are common ones (Account Tracking, Entitlement Configuration Resource, Init managed System Info) and some are unique to this driver configurations packages.

  1. NOVLOFFIDCFG-itp-Transform

  • NOVLAUDTENTC-itp-SendEntitlementsEvents

  • NOVLOFFIENTEX-itp-InitEntitlementConfigurationResource

  • NOVLATRKBASE-itp-Publish

  • NOVLOFMSINFO-itp-InitManagedSystemInfo

  • NOVLOFFIENTEX-itp-EntitlementsImpl

  • NOVLDATACOLL-itp-DataCollectionQuerySupport

  • NOVLATRKBASE-itp-Publish2

  • NOVLATRKBASE-itp-WriteAccounts

  • NOVLPWDSYNC-itp-EmailOnFailedPwdSub

1. NOVLOFFIDCFG-itp-Transform

This policy has a single rule, "re-format BlockCredential" that looks for modify events with BlockCredentail available as an operational attribute.

It will then store the value being removed in a variable removevalue, using the XPATH ./modify-attr[@attr-name="BlockCredential"]/remove-value/value/text() to select it. Of course they could have just used the Removed Attribute noun token if they wanted to get it as well. Much easier to read that way.

Then they store the added value in a variable called addvalue, using a similar XPATH just changing the remove-value node for add-value. This would be the definition of the Operation Attribute noun token.

Then they compare if local variable removevalue is the same as $addvalue$. This is nicer than an XPATH compare of if XPATH true $removevalue=$addvalue since this can be case sensitive or insensitive as you want, but the XPATH would be only a case sensitive compare.

If they are the same, then they strip by XPATH, the modify-attr node. Of course, Strip Operation Attribute action token does the exact same thing and is easier to read.

Then if that was the only event, determined by an XPATH of count(./modify-attr)=0 then they veto. That works because if there are no more modify-attr nodes, after you remove the BlockCredentail one, not much of an event left to process.

2. NOVLAUDTENTC-itp-SendEntitlementsEvents

This is a generic rule from the Audit Entitlements package that I will probably review separately one of these days, since it is a big complex package, and not really specific to the Office 365 driver. Basically this one looks for a class of entitlement related events and if detected, sends an audit event to Sentinel or wherever you are sending your audit events.

3. NOVLOFFIENTEX-itp-InitEntitlementConfigurationResource

This is a custom rule for this driver, but is basically the same as in other drivers. You can read more about what happens in here in these two articles:

The first explains what is needed to add this stuff to a pre-IDM 4 driver, and the second is my explanation of what that is doing.

In essence this rule builds the EntitlementConfiguration object that User App looks for, when it does a CODE MAP Refresh. It reads back the defined entitlements in the object and uses that information to present to you, when you try to assign a Resource an Entitlement. What kind of bugs me about this approach is that it is not a generic bit of code the same for every driver being reused, rather it needs to be customized to support the drivers specific entitlements. If you add your own entitlement type (not an instance of say UserAccount or Group, but an entirely new type of Entitlement like Contractor) then you need to edit these policies so it adds support for yours. Thus I do not entirely see the point, seems like it could have been done much more cleverly.

Even worse is if you wanted to add a package with your own additional entitlement type, this causes a real problem. You cannot just add your entitlement object and expect it to get an entry properly added. In their defense, additional entitlement objects get a single line reference with all values set to false, which is not very helpful in the real world.

Thus to add a new entitlement, you need to dirty the package to modify this rule.

The output is interesting and in the resulting DirXML-Resource object, named EntitlementConfiguration you will see the XML as:
<entitlement-configuration modified="20140303033113">
<entitlement data-collection="true" dn="CN=Group,CN=AD,CN=dset,O=idm" parameter-format="idm4" resource-mapping="true" role-mapping="true">
<type category="security grouping" id="group" name="group">
<value langCode="en">Group</value>
<sub-type source="read-attr" source-name="Type">
<display-name source-value="Regular">
<value langCode="en"/>
<display-name source-value="Queue">
<value langCode="en"/>
<parameter mandatory="true" name="ID" source="association"/>
<parameter mandatory="true" name="ID2" source="src-dn"/>
<read-attr attr-name="Members"/>
<operation-data data-collection-query="true"/>
<read-attr attr-name="Type"/>

There will be an entitlement node for each Entitlement object in your driver. The key info is in the main node as XML attributes as:
<entitlement data-collection="true" dn="CN=Group,CN=AD,CN=dset,O=idm" parameter-format="idm4" resource-mapping="true" role-mapping="true">

The data-collection, resource-mapping, and role-mapping in the current rules config come from the GCV settings for Entitlements. The parameter-format is important as the Roles and Resource Service Driver (RRSD) will use this to decide how to parse the parameter value and throw an error if it does not match. The parameters node comes from the definition and tells the RRSD what values are expected for the User App to request when assigning Entitlements to Resources.

Ultimately, the DN XML attribute is probably the most important since the User App requires it in LDAP format when doing a CODE MAP refresh and it is a little hard in packages to build the DN of the new driver, in LDAP format into a delivered policy.

There is so much more to be said here, and the more I play with RBPM the more I learn, I need to find a good format to try and capture it all. But now is not the time or place.

This driver in particular has a number of additional entitlements beyond the simple UserAccount and Group, since it supports License, and Role as well. In Office 365 as discussed in earlier articles in this series there are many possible license values a user can have, to control their access to modules and components. Thus the ability to add a License via an RBPM Role is kind of helpful. I am not sure exactly what a Role in Office 365 is, but as you can see it is manageable via Entitlements (and thus Resources and of course, thus by RBPM Roles as well).

4. NOVLATRKBASE-itp-Publish

As discussed before, I do not want to get into the Account Tracking packages at this time, and hope to do a standalone series on just these components as they are common across many drivers. These exist entirely to manage the DirXML-Accounts attribute.

5. NOVLOFMSINFO-itp-InitManagedSystemInfo

This policy was described for the most part in the series I did on the Managed System Gateway driver, where every Packaged IDM 4 driver that supports Reporting, has one of these rules, which manages and updates the MSInfo GCV object. Some of this is to automate getting the GUID into it which would be hard to ask someone to type, and hard to get via Package prompts. I see that as an excuse to update the Package prompts process not to do this sort of code but whatever. It fires every driver startup, and updates (if needed0 the MSInfo object.

6. NOVLOFFIENTEX-itp-EntitlementsImpl

There are three rules here.

  1. Intercept MSolDomain (tagged identity query) query response

  • Intercept MSolDomain (tagged identity query) query status

  • Check target of add-association for group membership entitlements

These policies are used to support the model used in Entitlements and querying for values and used by the Reporting components of IDM.

1. Intercept MSolDomain (tagged identity query) query response

This rule seems to be looking for a specific type of query response, for the class "__driver_identification_class__" which is a what they convert some of the queries that the Reporting might send through the DCS (Data Collection Service) or MSG (Managed System Gateway) driver shims. I forget which one injects the queries on behalf of Reporting, but it is one of those two. Just like the User App driver injects queries into other drivers for the CODE MAP refresh operation, where it will query for say all available Groups for the Group entitlement so that when you assign an entitlement to a Resource, the query based values are available in the GUI. (This is the part of the code that the Garnet gemstone project is purported to help with. Time will tell since it is not yet released).

Then further it wants to know if some of the op data is UserAccountEntitlementQuery as in the XPATH below:


If this is true then it does a Strip by XPATH of . (Period) which means the entire event. I am not sure what the exact use case is here, other than to kill the response from responding.

2. Intercept MSolDomain (tagged identity query) query status

This rule will respond to a query that the shim cannot really answer, so in the OTP policies the specific query which Reporting will ask is converted to a form that can be treated as harmless by the shim (the __driver_identification_class__ type queries that basically return the driver versioning info) and it will be converted to something like this:

    <instance class-name="MSolDomain" src-dn="domain.com">
<attr attr-name="DomainName">
<value>Account for domain: domain.com</value>
<attr attr-name="DomainDescription">
<value>User account in Office365domain.com</value>
<attr attr-name="DomainValue">

This is done in a long series of Append XML Elements, Set XML attributes and Append XML Text actions that would be really boring to discuss. I ran an instance event through simulator to get the output, since it was just faster that way.

Looking at the XPATH in the condition block here, I think there is a slight difference from the previous one that might explain what they are doing. The first XPATH above, that strips the current event is if ANY status node is found (the slash slash (//) that it starts with. Whereas this condition is for when up one level, then down, there is a status node, (indicated with a dot dot (..) slash at the beginning).

I think there must be a common case of two status events coming through together, and they strip one then process the other.

The only interesting trick done in the rule is the last one:
<do-strip-xpath expression=".[count(attr)=0]"/>

That Strip by XPATH of .[count(attr)=0] means, if there is a node, that zero <attr> nodes strip it. Since this is targeted at <instance> documents that normally would include <attr> nodes, this means get rid of any empty documents.

3. Check target of add-association for group membership entitlements

This rule is a totally different case from the two before, and is barely related to those two. This is the same as in the Active Directory driver, where you cannot add a user to Active Directory and then make them a member of a group. There is a timing issue, since the DN does not yet exist and can cause issues. Thus the mode for Entitlements is to set an operation property if there is a Group Entitlement in the Subscriber Command Transform policies and then if that is seen on the <add-association> returning from the shim (I.e. after a successful add event) then go look to see if there are any Group Entitlements on this object and then process them, since we know the user has been successfully added.

Thus the conditions for this rule are if the GCV for group entitlements is set to true (drv.entitlement.Group) and it is an <add-association> event and the operation property check-group-entitlements is true (I.e. flagged as we need to add groups after the add) and the Group entitlement is available.

Then in the Actions it will loop over the Entitlement named Group, and using the ECMA function getEntParamField, it will look at the JSON payload and get the ID value, which should be the GUID in Active Directory of the Group into the group-assoc variable. Then it will add the source attribute member, on the group, defined by the Association value we grabbed from the payloads ID field with a target value to be added of the Destination DN, which I would have thought would be in LDAP format at this point, but in fact I think is in Slash format. How will that work? The next token of setting an association-ref XML attribute on the modify event so that the engine can resolve the DN to an Association. The XPATH there is pretty typical for doing that kind of work:

That is, up a level, (from the current operation of <add-assocation>) and look for the last modify event, and the last modify-attr node, and the last add-value node, and the last value node, to set the current events text() node (the association value, since <add-association> events look kind of funny, in that they have just the association value as the text node of the add-association event itself. Like I said, looks kind of funny).

Anyway that is about it for this article, stay tuned for part 11 (Good grief, this is getting a bit long winded. Anyone complaining?)


How To-Best Practice
Comment List
Related Discussions