When Governance Meets Reality
If you’ve ever spent weeks designing Microsoft Entra ID Governance workflows, you know that feeling — everything looks perfect in the documentation. Your access packages are mapped, lifecycle workflows are aligned, and your policies finally make sense.
Then you run the first test. And suddenly, everything breaks.
You realize that your beautifully designed workflow is only as good as the data it depends on.
Maybe HR lists someone as “Consultant”, but in Entra ID they’re marked as “Employee.”
Maybe your Department field is populated differently across systems — sometimes Finance, sometimes Finance DK, sometimes Økonomi.
Or maybe you have external partners who don’t fit neatly into your userType categories but still need controlled access.
And when access reviews or lifecycle workflows start targeting based on those attributes…
the wrong people get access, and the right ones get locked out.

Sound familiar? You’re not alone.
Most governance issues don’t come from Entra ID itself — they come from data inconsistencies between systems.
Identity Governance doesn’t fail because of bad design; it fails because the data feeding it isn’t aligned with how your organization actually works.
That’s where directory extensions become invaluable.
They don’t fix messy source data — but they give you a dedicated, standardized place to store the information that matters for governance.
For example, you can create your own extension_{guid}_GovernanceDepartment and populate it automatically with the correct, policy-relevant value — even when other systems disagree.
In other words: directory extensions let you take back control of your identity data.
They turn governance from a best-effort process into a predictable, enforceable model built on consistent attributes.
Directory Extensions: The Missing Piece in Governance
Let’s be honest — Entra ID gives us amazing tools for governance: lifecycle workflows, entitlement management, access reviews, conditional access… the list goes on.
But here’s the problem no one talks about:
All of it depends on having the right data in the right place.
The built-in user attributes — things like department, jobTitle, companyName, employeeType — are great, but they’re also shared and reused by every integration, every sync, every human who’s ever updated a user manually.
And that’s exactly how chaos begins.
One system writes “IT”, another writes “Information Technology”, and a third uses “Tech Support.”
You can’t change that in HR, because it breaks payroll.
You can’t change it in the sync, because it affects another country.
And now, your workflow that assigns access to the IT Security package fails because the filter doesn’t match.
That’s where directory extensions quietly save the day.
A directory extension lets you define your own custom attribute — something completely separate from the default Entra ID schema.
It’s like having your own “safe zone” for governance data.
You can create attributes like:
extension_{guid}_LifecycleRoleextension_{guid}_GovernanceDepartmentextension_{guid}_AccessCategoryextension_{guid}_ManagerLevel
And then populate those fields automatically through Microsoft Graph, Power Automate, or your HR connector.
These attributes don’t get overwritten by HR, Intune, or external syncs — they belong to your governance model.
That means you can base your lifecycle workflows, access packages, and policies on your definitions, not on inherited noise from other systems.
A Practical Example
Let’s say you’re building an offboarding workflow.
You want contractors to be offboarded differently than employees.
Normally, you’d target userType or employeeType.
But in your tenant, contractors come from multiple systems — some tagged as “External,” some as “Member,” and others just missing a value.
Instead, you create a directory extension called:
extension_3e3e6f47b2294e5a8d7b1234fabc1234_ContractorStatus
You populate it automatically with "True" for external consultants.
Now your workflow targets this field, not the unreliable system attributes.
✅ Simple.
✅ Reliable.
✅ Governance-friendly.
Governance Through Automation
Directory extensions shine when combined with automation.
Through Microsoft Graph API, you can create, update, and query these attributes programmatically — which means your governance processes can be self-healing.
When HR updates a record, your automation can push standardized values to the right extension.
When an integration detects missing data, it can trigger remediation.
Microsoft’s Graph API Reference for directory extensions explains how to create and manage them — and if you prefer PowerShell, you can automate it all with the same principles using custom functions.
Building a Governance Data Model with Directory Extensions
If you’ve ever opened Entra ID and thought “I just need one more attribute to make this work” — you’re exactly the kind of person directory extensions were made for.
Before you start creating extensions left and right, though, it’s worth building a data model.
A governance data model defines which attributes belong to governance — and how they interact with your workflows, access packages, and policies.
Here’s a simple way to think about it.
Separate System Attributes from Governance Attributes
System attributes are the ones that other integrations rely on — like department, companyName, or employeeType. You can’t safely change them without breaking something.
Governance attributes, on the other hand, are yours to control.
They exist only for your logic — your lifecycle workflows, dynamic groups, and access policies.
| Type | Example | Ownership |
|---|---|---|
| System | department | HR or ERP |
| System | companyName | HR / Integration |
| Governance | extension_3e3e6f47b2294e5a8d7b1234fabc1234_GovernanceRegion | Governance Automation |
| Governance | extension_3e3e6f47b2294e5a8d7b1234fabc1234_EmployeeLifecycleStage | Governance Automation |
Keeping them separate means you can enforce your rules without interfering with anyone else’s systems.
Understanding the Naming Structure
When you create a directory extension, it’s anchored to an App Registration in your tenant — and the name reflects that ownership.
The complete property name follows this format:
extension_<appId>_<AttributeName>
<AppId>is the Client ID (Application ID) of the application that registered the extension.<AttributeName>is the custom suffix you choose (for example:LifecycleRole,GovernanceRegion,AccessLevel).- You don’t define the entire string — the service concatenates
extension_, the AppId, and your attribute name.
extension_3e3e6f47b2294e5a8d7b1234fabc1234_LifecycleRole
That’s the name you’ll use later when patching users through Microsoft Graph or referencing it in dynamic group rules and lifecycle workflows.
Tip: Choose a clear and consistent <AttributeName> suffix, since that’s what you’ll reference in automation, dynamic groups, and governance policies.
Why the app owns the extension
The extension property is created on the application object, not directly on the user. That means:
- The app must have the necessary permissions (typically
Application.ReadWrite.AllorDirectory.ReadWrite.All) to register the extension via the Microsoft Graph API. Microsoft Learn - Because the extension is tied to the application’s AppId, the resulting attribute name is guaranteed unique and tenant-wide.
- When you patch or read the value on a user, you reference that full attribute name and the Graph API recognizes it as belonging to your extension schema.
- According to Microsoft’s docs: “Directory extension attributes are always associated with an application in the tenant. The name of the directory attribute includes the appId of the application in its name.” Microsoft Learn
By understanding this naming and ownership model, you can confidently build and maintain your governance model without accidentally creating duplicates, inconsistent schemas, or unsupported attributes.
Let’s Get Practical: Adding a Custom Extension to a Dynamic Rule
Now that we’ve covered the why, let’s see the how. In our example, we’ll use an auto-assignment policy in an access package, but the same process applies to dynamic rules in security groups, lifecycle workflows, or any dynamic evaluation in Entra ID.
Here’s the catch: custom directory extensions don’t appear in the attribute list by default. Even though the extension exists on the user object and is populated correctly, the portal hides it until you explicitly load it from the owning application.
Click the Pen and Realize Something is Missing
When you open the rule editor for your access package’s auto-assignment policy, you eagerly click the pencil icon ✏️ to edit the rule syntax. You start typing extension_ in the attribute dropdown, expecting to see your newly created attribute.
…but nothing shows up.

At this point, you might panic — your newly created attribute doesn’t show up. Don’t worry — it’s not gone. The portal just doesn’t know which application owns it.
Get Custom Extension Properties
This is the part that makes your extensions visible. Follow these steps:

1. In the rule editor, click “Get custom extension properties”.
2. A new selection window will open. Here, you need to find and select the App Registration that owns your custom extension attributes (the same one whose AppId is in your extension name).

3. After selecting the application, click “Refresh properties”. This tells the portal to load all the extension attributes from that application.

4. Go back to the section properties in the rule editor. You should now see all extension attributes that the application holds, including the ones you just created.
Without this step, even fully populated extensions remain invisible. Loading them from the owning application is what makes them actionable in dynamic rules.
Build Your Dynamic Rule
Now the magic happens. You can write rules like:
(extension_3e3e6f47b2294e5a8d7b1234_GovernanceDepartment -eq "FinanceDK")
Or target a specific lifecycle role:
(extension_3e3e6f47b2294e5a8d7b1234_LifecycleRole -eq "MobileUser")
Hit Save, and your auto-assignment policy goes from concept to operational. Users with the correct custom attributes are automatically included — no manual assignment required.
Test With a Sample User
Always validate with a test user:
PATCH https://graph.microsoft.com/v1.0/users/{id}
{
"extension_3e3e6f47b2294e5a8d7b1234_GovernanceDepartment": "FinanceDK"
}
Wait a moment for the policy to evaluate, then confirm: the user is automatically added to the access package.
Apply the Pattern Across Entra ID
Once you understand this trick, the same approach works anywhere you use dynamic rules:
- Security groups for Conditional Access
- Lifecycle workflow conditions
- Access reviews targeting specific governance roles
By loading the attributes from the owning application, you make your custom extensions visible and actionable, turning governance logic from theory into reality.
Verify and Audit
Even after your rules work, it’s critical to verify the data. In my SISToolbox functions for directory extensions, I’ve built tools to audit and inspect extension attributes, making it easy to catch inconsistencies, missing values, or misalignments before they impact policies.
When Theory Becomes Practice
This example highlights a simple but powerful truth: even the best-designed access packages and workflows only work if your data is visible and usable. Custom extensions give you control over governance attributes, but until you load them from the owning application, they remain hidden — and inaccessible for dynamic rules. That moment, when your attributes finally appear in the portal, is when governance moves from theory into practice.
Once your extensions are visible, it’s equally important to verify and audit the data. My SISToolbox functions for directory extensions are designed for this purpose: to inspect, validate, and catch inconsistencies or missing values before they affect access packages, dynamic groups, or lifecycle workflows.
At its core, governance isn’t just about policies or rules — it’s about ensuring the right data is in the right place at the right time. By combining custom extensions with careful verification and audit practices, you can turn governance into a process that’s reliable, testable, and trustworthy in day-to-day operations.

Discover more from Agder in the cloud
Subscribe to get the latest posts sent to your email.

