Walking through the Office 365 IDM driver – Part 13
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 started down the Input Transform policy set getting through the first six policy objects.
In part eleven of this series I finished the Input Transform policy set and got through the Publisher Event Transform policy set.
In part twelve of this series I got through the Match, Create, Placement, and almost all of the Command transform policy sets.
In this article I will continue down the Publisher channel finishing the Command Transform.
Command Transformation Policy Set:
There are eight policy objects in this policy set.
I got through the first two in the last article, now for the third.
There are three rules in this policy object.
- Strip Login Disabled from operation (Disable Option)
- Veto Group Add
- GroupMembership entitlement: veto membership without entitlement
1. Strip Login Disabled from operation (Disable Option)
If the GCV drv.entitlement.UserAccount is true, this is an event for a user, and login disabled is available (means a value is being added at least) then strip out the Login Disabled. S
I think the logic here is that if the Entitlement is being used to grant access, and the user is associated, if Login Disabled is changing in Office 365 then either your sent through an entitlement change to cause it, and you do not want that flowing back to the IDV. After all, you might have meant to just remove his O365 access nothing else.
Or else, if it is changing in Office 365 to disabled, because and Admin went in and did it by hand, then likely this should not be allowed to flow if you are using the entitlement method.
I think this is not a wise choice, since it is hard to tell if it was the Admin who did it or a loopback from an Entitlement change and I think I would prefer to handle those differently. (I might do a check if the entitlement exists on the user to decide if it were up to me).
2. Veto Group Add
If the GCV for enabling the use of Group Entitlements (drv.entitlement.Group) is true. and a Group is being added, then it vetoes it.
Again I think this is meant as a form of loopback protection. Or at the very least, if someone in the Office 365 web interface created a group, if there is no entitlement for it to block it being created in the vault.
This poses an interesting question of how you make a group. It used to be you would create a group in eDirectory and it would synchronize to the connected systems, Office 365 in this case. Even more so, the group had to exist in eDirectory in order to allow membership changes to be synced. Then with valued entitlements we got the notion of a Group Entitlement that meant a group in the target system, that might not exist in eDirectory could get membership changes transmitted.
Which brings me to the question of, with a Group Entitlement model, how do you get the IDM system to create a new group in the target system? I guess you do not? I guess you are expected to create it there via the normal interfaces, and then you can use it? If so, then this rule makes sense as it is trying to keep groups from syncing from the target back to eDirectory since they are meant to be independent.
Now of course you could create a new Group entitlement type that creates the groups, but to whom would you grant it? A group in eDirectory? But that is generally blocked from sync in an entitlement model.
It feels like there is a small piece missing here, to me.
3. GroupMembership entitlement: veto membership without entitlement
This rule starts the same as the previous one, if the GCV drv.entitlement.Group is true, which means Groups are handled through entitlements, and a Group object is being modified or added then strip out the XPATH of:
./add-attr[@attr-name="Member"] | ./modify-attr[@attr-name="Member"]
That is two things, separated by a logical OR symbol, the pipe (|). Because the XML for an <add> event differs slightly from a <modify> event you have to handle both cases in XPATH explicitly.
Of course, this is why there is a token known as Strip Operation Attribute which knows how to do both these things properly. If you have seen my book on IDM tokens you will have noticed as I discussed each token, I tried to offer an XPATH alternative for how it could be done. Of course my point there was to teach XPATH through examples. If after discussing what a particular token does, you see an XPATH example of how to do the same, you should get an appreciation for how to do stuff in XPATH. Here is sort of the opposite lesson I hope you would have taken. That is, often the tokens exist for a good reason, and are simpler to use than the XPATH equivalent.
A truly simple <add: document might look like:
<?xml version="1.0" encoding="UTF-8"?><nds dtdversion="4.0" ndsversion="8.x">
Thus the first half of the XPATH is look for something under (a child of) the current context node (the <add> node) add-attr, with a predicate (The  means a predicate, like SQL's WHERE statement) testing for an XML attribute of that node, named attr-name (The @ sign indicates you want an XML attribute) with a value of Member.
The modify XDS event look a bit different.
<?xml version="1.0" encoding="UTF-8"?><nds dtdversion="4.0" ndsversion="8.x">
Here the second half of the XPATH is looking for the modify-attr node, with an attr-name XML attribute value of Member.
Now this strip is at the level of the add-attr and modify-attr nodes, which does not mean much in the add case, since you can only add values in an object add. But in the case of a modify there are three possible children, add-value, remove-value and remove-all-values. This strip by XPATH will remove all the children, which is probably what is wanted.
Regardless, the simpler way to have done it would have been with a Strip Operation Attribute for Member token. Simple to read, and simpler to manage and debug.
These last five policy objects are really the very standard Password policy objects that almost all drivers share in common. You can read about how they work in great detail in these three articles, which explain how the Subscriber and Publisher channel versions work, as well as how password tunneling works. (Answering the question: If the Universal Password is stored in nspmPassword, why do we always work with nspmDistributionPassword. WHy do we need to use Distribution Password instead of Universal Password. Surprisingly, there is a reason. A good reason? I dunno, you read it and be the judge. But there actually is a reason!)
The basic goal here, is to convert from a <password> node in an <add> event or in a <modify-password> event to a <modify> of nspmDistributionPassword.
That is, the shim usually handles passwords not as a standard attribute. It is fairly rare to see a password attribute simply sync raw to the other side. Usually it needs to call some special case handling to encode or encrypt it. Thus the shim usually sends a <modify-password> event when it detects a password change.
Thus here we wish to convert that, based on the settings in the Password Management GCVs to an appropriate <modify> event. This is where we would block password sync on the Publisher channel, assuming it made it this far.
In some drivers (new bidirectional eDirectory for example) it gets a bit silly as the event comes in as a modify of nspmDistributionPassword, but then gets converted to a <modify-password> event and then converted back to a <modify> of nspmDistributionPassword. Fairly silly, but it does add value in the sense that the policies are the same (Plus one custom one) and the troubleshooting path is consistent across drivers. Extra processing yes, but conformity is of value. Also it means one package can be updated to support multiple drivers, which makes life a lot easier on the support side of the house.
There is at least one very interesting thing about how the Packages for Password Policies work. Each driver in fact loads up two packages. The first is the Common, Password Synchronization, Password Synchronization Common package. This delivers all the policies that are shared across the many drivers and a filter extension to add the nspmDistributionPassword, set as Subscriber synchronize, Publisher Ignore. (Which also looks weird but is correct and important to be left that way).
However it has no linkage. That is, the policies get added to your driver, in the Subscriber and Publisher containers as appropriate, but they do not get linked into any policy sets. Which looks kind of funny.
Then every driver has a specific package called Password Synchronization, that usually delivers no or very few policies, but does deliver the GCV object that has all the synchronization options, that Designer and iManager render into a series of simpler tick box choices. You see this, if you click on a driver in Designer, right click the driver line, and a Password Management option is there. Now this has been broken and fixed and broken again with the addition of packages since it initially looked the DirXML-ConfigValues attribute to read the settings. But of course in the case of Packages, that i snow in a GCV object (DirXML-GlobalConfig) that holds it. Then in some version of Designer they fixed it, so it looked at all the possible GCV objects for the attributes it needs and worked. Then it broke again. This also sucks since it was broken, last I looked, in the Dataflow master view. That is, if you are on the Modeler view (Where you see your drivers and trees all laid out nicely) and then at the bottom there is a Dataflow tab, which is super powerful and many folk do not know about it. This will show in a single view, all the filter settings for all drivers in your project. Thus if you wanted to know, where am I syncing Login Disabled, without this, you would have to go to each driver, open the Filter, expand User, look for the attribute to see. In this view, you expand user in the proper driverset, and then read across the line as it shows you all the values for all the drivers in a line. I wish they could pin the header (Like in Excel) since in an object class with lots of attributes and lots of drivers, as you scroll down to your attribute, it can be hard to remember which column is which driver.
Possibly the best feature is if you right click on an attribute row entry, in a specific column, you can adjust the setting and it is saved into the drivers filter.
Imagine how much time it would take if management told you to stop syncing Login Disabled across 20 drivers. You would have to open 20 filter objects, make the change, save. Then you could compare the driverset and push out all the changes. With a project that is large, Designer gets slower and slower, so that could be an onerous task. However, in this view, expand User, find the Login Disabled attribute, then click your way along that line setting each channel to ignore. Lots of clicking, but one view. Then compare the driverset to push out the changes.
Anyway, in addition to showing just the attributes in the filter you can adjust it to show Password Sync, which was not looking at all GCVs last I checked, alas. But that too would be a great way to make bulk changes easily.
Simplest way I know to reliably show the current settings is in the actual GCV with the password sync GCV's there is an icon next to them in Designer that pops up the Password Management settings.
In the case of our package, it actually delivered two policies as well, one for the Subscriber Command Transform that was discussed in part 8 of this series, and an Output Transform policy that was discussed in part 9 of this series.
But the main thing it does, is link in the various policies delivered in the Password Sync Common package to the appropriate places and in the appropriate order. This way a driver that does not need some of the policies implemented, can just not link them in.
This is a pretty reasonable model for handling this, and works pretty well so far.
That about wraps up my walk through of all the policies. But wait, there is more!
When I started this series lo so many years ago, I noted the specific packages I was reviewing.
- NOVLOFFIBASE 18.104.22.16830111115820 Base package
- NOVLOFFIDCFG 22.214.171.12430111153536 Default configuration
- NOVOFFAUDENT 126.96.36.19921212171705 Audit Entitlements
- NOVLOFFIATRK 188.8.131.5230101164900 Account tracking for Identity Audit
- NOVLOFFIPSWD 184.108.40.20630110125335 Password Synchronization
- NOVLOFMSINFO 220.127.116.1121217151110 Managed System Info
- NOVLOFFENT 18.104.22.16830110181516 Entitlement support
- NOVLOFFIOPTL 22.214.171.12430110140328 Optional Packages
I also picked up some package dependencies and got:
- Account Tracking Common 126.96.36.19920718113432
- Audit Entitlements Common 1.0.0
- Data Collection Common 1.0.0
- Password Synchronization Common 188.8.131.5220423124853
There were a couple of driver set packages that came in via dependencies as well:
- Advanced Java Class 1.0.1
- Common Settings 1.0.01
In the intervening year or so, these have all been updated. So lets see what it looks like with the new packages. Designer 4.02 Auto Update 2 I think added the ability to compare packages. So I will compare the version I used against the latest packages, and report back on what has changed. Lets see if anyone read my articles and fixed the issues I noted.