My Microsoft Entra HR and Inbound Provisioning – World’s Best Boss Edition post is now up on the new Core Infrastructure and Security Tech Community site.
Hello everyone, this is David Loder again, with another topic inspired by a recent customer interaction. They had a complex on-prem AD setup that was preventing them from showing their desired management org structure in the M365 Exchange Online Global Address List.
In this article we are going to look at the Entra ID HR/Inbound
Provisioning flows, specifically at the boss manager attribute. Almost
all customers with which I work are still running hybrid environments. Therefore,
we’ll be looking at how HR/Inbound Provisioning gets the manager data to Active
Directory correctly so that Entra Connect Sync provides accurate data to the
tenant. If you happen to be working with a cloud-only tenant, then there’s no
drama for the manager attribute, and all scenarios work without issue. There
can be complexity with the manager attribute so there’s some foundational
understanding that’s needed to understand why the manager attribute can be
challenging and how we can overcome these problems. Finally, I’ll bring all
this knowledge together to show a design that can help customers easily handle the
most complex AD and sync environments.
We’ll begin with the simplest example: a single forest,
single domain AD environment. We have a single provisioning
agent installed, and the single domain registered with the agent.
If we have a manager Alice with a reporting employee Bob, we
can send a
transaction to the API endpoint that will create both Alice and Bob and set
Alice as Bob’s manager.
{
"userName": "EMP1222",
"nickName": "EMP1222",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":
{
"manager": {
"value": ""
},
"employeeNumber": "1222"
},
"name": {
"familyName": "Manager",
"givenName": "Alice"
},
"externalId": "1222",
"active": true,
"displayName": "Alice Manager"
},
{
"userName": "EMP1513",
"nickName": "EMP1513",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":
{
"manager": {
"value":
"1222"
},
"employeeNumber": "1513"
},
"name": {
"familyName": "Employee",
"givenName": "Bob"
},
"externalId": "1513",
"active": true,
"displayName": "Bob Employee"
}
Note the direction of that relationship: we say Bob has
Alice as their manager, not that Alice has Bob as a reporting employee. In AD,
one can have only a single manager, while one might have several reporting
employees. That aligns with the API template in that we provide the manager ID
on the employee record.
If we review the provisioning log for that transaction,
we’ll see the creation of Bob (ordering of the Creates can be indeterminate)
but do not attempt to set manager during the Create step. Next, we see the
creation of Alice. Finally, there is an Update to Bob’s account to set Alice as
their manager.
If the user accounts happen to be provisioned in the reverse
order, we’ll still observe the same outcome. The sync engine is smart enough to
skip setting manager references until it reaches the end of its cycle. If we
had sent a transaction that only contained Bob but still listed Alice as their
manager, Bob would have finished the provisioning cycle with no manager in AD
because the sync engine doesn’t know anything about Alice yet.
This sequence of events is necessary because of the somewhat
unique properties of the manager attribute from a schema perspective. So, let’s
refresh our knowledge on how the manager attribute works in Active Directory.
This knowledge is important to understand how to handle some of the more
complex setups we’ll get to later in the article.
The schema definition for manager has these important
attributes:
Get-ADObject -LDAPFilter 'cn=manager' -SearchBase
((Get-ADRootDSE).schemaNamingContext) -Properties linkid,attributesyntax,isSingleValued
attributesyntax :
2.5.5.1
DistinguishedName :
CN=Manager,CN=Schema,CN=Configuration,DC=contoso,DC=com
isSingleValued :
True
linkid : 42
Name :
Manager
ObjectClass :
attributeSchema
ObjectGUID :
acbc9875-5e6f-4f6a-84d3-9205d843f218
Linkid, being 42, is an even number, meaning this is the
writeable side of a linked-pair;
directReports being the read-only side with linkid 43. The attributesyntax of 2.5.5.1
indicates this is an Object
(DN) syntax. Object DN syntax means that the value we want to write must
point to the distinguished name (DN) of another object of which the Domain
Controller already has knowledge. This is an important constraint as we’ll see
later.
The next item of importance is observed in the provisioning
logs with the outcome of the Create steps. If we look at the details of Alice’s
creation, we see an item called ‘Target ID’ being returned with a GUID value.
If we look at Alice’s account in AD, we’ll notice that
Target ID is their objectGUID.
Then, if we look at the update step for Bob, where Bob’s
manager value is set, we’ll notice that same objectGUID value.
There are several ways to represent Object (DN) values. The
most common is the DN string (e.g. CN=Alice Manager,OU=userids,DC=contoso,DC=com),
but there are other representations. If one searches AD using the LDAP_SERVER_EXTENDED_DN_OID
control, then Object (DN) based attributes will also return the objectGUID
and SID values where applicable. If we were to LDAP
trace the Cloud Sync agent, we would see that the queries, the search
results and the modify commands are all using LDAP_SERVER_EXTENDED_DN_OID. This
allows the agent to set the manager attribute via the manager’s objectGUID. No
searching the directory is necessary to find their current DN, and objectGUID
is unchanging within the forest. So long as the provisioning engine knows the objectGUID
(Target ID) of the manager, the manager reference will be correctly set. But
this means that both the manager and employee must have been provisioned (or
joined) within this one HR/Inbound provisioning app so it has knowledge of the
manager’s objectGUID.
Coincidentally, as I was finalizing this writeup, a
colleague reached out to me about a customer that had a PoC running with
Workday against an already populated AD. The problem was their newly
provisioned test users had no manager. My first question was had they
provisioned the manager yet through their on-demand provision testing.
Now that we’ve covered the basic use case, let’s introduce
the first complexity and have the AD forest be multi-domain. For this example,
we’ll continue to have Alice be the manager, but their account will reside in
the root domain and Bob’s in a child domain. In this scenario, we would again
see the same flow. Both Alice and Bob’s accounts are created in their
respective domains. Then Bob’s account is updated, using the Target ID of Alice
for setting the manager value. The single-forest, multi-domain scenario really
isn’t different from the single domain scenario. The same steps are followed by
the provisioning agent that is connected to the domain in which Bob’s account
resides.
With the single forest story complete and a base
understanding of how the manager attribute functions in both AD and the
provisioning engine, we need to increase the complexity once again.
I was having discussions with a multinational company about
a problem they were having. In their current business model, each region has
its own AD forest. All the forests are brought together with Entra Connect Sync
into a single Entra ID tenant. Currently, all employees have an in-region
manager, which is reflected in AD and the Global Address List data, partially built
using the manager attribute in AD. Cross-region managers were rare and a
cross-region manager was not shown in AD, the GAL, or any other tools. I was
brought in because their business was changing. Cross-region managers were
about to become much more common, and they wanted that manager relationship
shown in the M365 services (Teams, Outlook) instead of the current in-region
manager.
If this was years ago, and on-premises AD was the only
directory, then without hesitation, we would have stood up a MIM
GALSync solution. That traditional on-prem solution syncs a copy of the
manager into the other forest as a contact object, then uses that contact
object to be the DN for the manager attribute. Because the contact object is
present in the same forest as the reporting employee’s account, the restriction
that manager points to an object that already exists in that forest is
satisfied.
Let’s illustrate the scenario to explain how the traditional
on-prem solution worked. Start by assuming we have two domains, EMEA and
AMERICA, each in their own forest. Alice’s account is in AMERICA and Bob’s is
in EMEA. The MIM GALSync process would create a contact for Alice in EMEA and
keep it in sync with Alice’s GAL details like name and email address. Bob’s AD manager
attribute can then be updated to point to Alice’s contact object. Both objects
are in EMEA so we can successfully write that DN value to Bob’s manager
attribute, and tools like Outlook, which displays the GAL, can show that Alice
is Bob’s cross-region manager.
The default
sync rules in Entra Connect Sync understand this traditional GALSync
scenario. The “In from AD – Contact Join” rule will join Alice’s contact object
in EMEA with their user object in AMERICA, based on the default join rule using
the mail attribute. With the default rules, user objects are higher precedence
than contact objects, so most of the data contributed to Alice’s metaverse
person object should reflect their AMERICA user details.
We can confirm that Alice’s metaverse person object is
having data contributed from both connector space objects. The AMERICA
connector being their main user object, and the EMEA connector being the GALSync
contact.
Bob, only having an account in the EMEA domain, will have
their metaverse data contributed solely from that domain.
Notice that the referential integrity within Entra Connect
Sync has established the link to Bob’s manager as Alice’s metaverse person
object. The hyperlink indicates a referential link to another object and can be
clicked to view Alice’s metaverse person object. Because both Alice’s EMEA contact
and AMERICA user objects are joined together to the same metaverse person
object, Bob’s manager reference, that exists solely in the EMEA domain, maintains
referential integrity as Entra Connect Sync translates the reference from the EMEA
connector space to the metaverse.
With Alice’s user and contact objects successfully joined in
the metaverse, only a single user object for Alice is provisioned into the
Entra tenant. And Bob’s Entra user object has Alice’s Entra user object as its
manager.
When all the proper data is provided and all the joins work
correctly, the referential integrity of the manager relationship is maintained
through each layer in Entra Connect Sync. That starts with the inbound AD
connector space, merges in the metaverse with default joins, this consolidated
outcome is then outbound provisioned to the Entra connector space and finally
exported to the Entra tenant.
Whew. We have finally covered enough background details to
help our customer modernize their HR provisioning. We covered the constraints
of the manager attribute in AD. We covered updating the manager attribute with
Entra’s HR provisioning app. And we covered how Entra Connect Sync needs to
maintain referential integrity to correctly sync the manager attribute in a
multi-forest environment.
Now, how do we accomplish the goal of getting cross-region
managers to show up in an M365 Exchange Online GAL, from a multi-forest AD
environment, without the use of MIM GALSync? We’ll assume only the M365
Exchange Online GAL needs to be properly populated. If all human-based
mailboxes are located in ExO, only the ExO GAL needs to display the desired
content. Our solution doesn’t have to correctly populate an existing on-prem
Exchange org GAL because no one will view it. If that wasn’t the case, we
likely be stuck with an on-prem GALSync solution.
Let’s review our technical design constraints.
- The customer still needs to provision users into their corresponding regional AD forest.
- Entra HR/Inbound provisioning can only provision user objects.
- Entra HR/Inbound provisioning can only set manager values when both the manager and the employee are present within the same provisioning app.
- One Entra HR/Inbound provisioning app can only target a single AD forest.
- The AD manager attribute can only target objects that exist in the same forest.
- Referential integrity within Entra Connect Sync starts with a singular connector space.
Because the AD manager attribute can only target an object in the same forest, and Entra HR/Inbound provisioning can only provision users, let’s see what happens if we decide to provision a copy of all the AMERICA users into EMEA. We could introduce a new provisioning app and match the provisioning logic for EMEA users but put the new AMERICA users in a different OU. We’d probably want the AMERICA users to be disabled, so add more logic to disable AMERICA users but not EMEA users. Then we need to worry about Entra Connect Sync. With two user objects, default precedence is chosen by which AD connector was added first. Either their disabled EMEA user or their enabled AMERICA would win precedence. We’d have to do some rule customization to keep the real EMEA users operating with the desired default flows but prevent the EMEA copy of AMERICA-based users from contributing any values. Yet we’d still have to allow the joins to happen to maintain referential integrity. If we somehow managed to craft all the necessary sync rules and provisioning app config, we’ve now introduced a new failure mode that didn’t exist before. If there are any cross-forest group memberships across a trust, we’ve made it such that an admin can accidentally select the disabled in-forest user instead of remembering to select the real cross-forest user.
That seems like a lot of customization to ensure we don’t
break anything existing. What if we take a slightly different approach where we
purposefully avoid needing to customize any existing flows in the HR/Inbound
provisioning app or in Entra Connect Sync?
The design I offered to my customer was to introduce a
“consolidation forest”. Rather than reusing an existing forest and having to work
around all the challenges with customizations to not break existing processes, we
use a brand-new forest just to contain all the manager references in a single
domain. The new forest would only need a Domain Admin, a GMSA for the new cloud
provisioning agent, and a read-only user account for the existing Entra Connect
Sync. This forest doesn’t need to trust any existing forests. No one except the
existing Entra Connect Sync and the new cloud provisioning agent need to
communicate with it. It doesn’t require redundancy or backup as we could
repopulate it from the HR/Inbound provisioning app. With a new forest we can
introduce a new HR/Inbound provisioning app without changing any existing ones.
All the users provisioned can be disabled. We only need to flow a single
joinable attribute like mail; and, of course, manager. The existing Entra Connect
Sync rules remain unchanged. New sync rules for the new forest can all be
disabled except for a simple join-only rule that only contributes manager.
Our final architecture diagram looks like this.
In all, I think the consolidation forest is a more elegant
solution. Very little additional infrastructure is needed when you’re already
in a multi-forest environment. No customization to existing flows and very
simple configs needed for the new forest.
The customer was thrilled with this solution. It satisfied
their business case needs. They could continue with a desired path for
HR/Inbound provisioning. They didn’t have to introduce any new services into
their portfolio. And their sync architecture remained highly standardized to a
default setup.
Thanks for spending a little bit of your time with me.
-Dave















