Microsoft 365 License Management with Entra ID Governance (No Code Approach)

By Sandra Saluti Apr 22, 2026

Managing Microsoft 365 licenses at scale sounds simple—until it isn’t.

In many environments, licenses are assigned dynamically based on attributes or groups. That works well for baseline access, but breaks down the moment users need temporary changes, exceptions, or upgrades.

This post walks through a governance-based approach using Entra ID Governance—combining access packages, approval flows, and lifecycle workflows—to make license management controlled, auditable, and reversible.

When the model starts to break

The attribute-based licensing model works well—until it has to handle exceptions.
As long as everything is automated and based on attributes or groups, things stay predictable. But once manual changes are introduced, that structure starts to break down.

A typical flow looks like this:

  1. A user requests additional access
  2. The request is handled by the service desk
  3. A license group is assigned manually
  4. No expiration or ownership is set
  5. The license stays assigned indefinitely

Even when the process works, it introduces delay and dependency on manual handling. Each step makes sense on its own. But over time, it creates problems. The system still works—but it’s no longer under control.

The problem isn’t the licensing model itself. The problem is that changes to it aren’t controlled. Once manual assignments are made without expiration or tracking, the system slowly fills up with exceptions.
And in reality, those exceptions rarely get cleaned up.

Architecture: A governance-based approach

Instead of assigning licenses directly, we introduce a simple structure that separates how access is requested, assigned, and removed.
The goal is not to replace the existing licensing model—but to add control around it.
The design is based on three core components:

  • Access packages → control how users request access
  • Groups → handle the actual license assignment
  • Lifecycle workflows → handle changes and cleanup over time

This separation keeps the setup simple and avoids mixing logic across different parts of the system.
It also makes the model easier to manage over time:

  • Changes can be made without breaking the whole setup
  • Access can be reviewed and removed automatically
  • Exceptions can be handled without losing control

The result is a model where license assignment is still flexible—but no longer unmanaged.

Step 1: Create your license groups

Start by creating groups that are only used for license assignment.

Create one group per license tier, and keep each group focused on a single purpose: assigning licenses—nothing else. Example LIC-M365-Tier1, LIC-M365-Tier2 and LIC-M365-Tier3.

Each group should be linked directly to a specific license or license bundle.

These groups are the foundation of the setup. Keeping them simple makes license assignment predictable and easier to manage over time. It also makes it clear why a user has a license—and just as important, when it should be removed.

If groups are reused for multiple purposes, things quickly become unclear. You lose visibility, and removing access becomes harder than it should be.

Avoid:

  • Reusing existing groups that already control other access
  • Mixing license assignment with roles or application access
  • Adding users manually outside the governed flow

With this in place, you get a clear separation between how access is requested and how licenses are assigned. This makes it possible to add approvals, expiration, and automation later—without changing the underlying licensing model.

Step 2: Build your access packages

With your license groups in place, the next step is to control how access is requested. Instead of assigning users directly to license groups, access is requested through access packages. Create one access package per license tier and link each package to its corresponding group. Each access package should only include the group responsible for license assignment — avoid bundling additional access or roles, keep them focused.

When creating the package you configure who can request it, how they request it, and how long the access lasts. Scope it to members in your directory, which covers both employees and subcontractors provisioned as regular member accounts. Enable self-service under the Requests tab so users can go to myaccess.microsoft.com and request access themselves — no IT involvement needed. Under the Lifecycle tab, set an expiration on the assignment. This is what separates a governed assignment from a permanent one, and Step 3 covers the specific settings in detail.

Without this layer, license assignment becomes a direct group operation again—and governance is lost.

Step 3: Configure the policy with approval and expiration

This is where the temporary access problem gets solved. Two settings change the behavior completely: The access package itself is just a container — the policy is where the behaviour is defined. This is where the temporary access problem gets solved. Two settings change everything: approval and expiration.

Under the Requests tab, enable approval and set your approver. For a standard license upgrade the user’s manager is usually enough. For elevated tiers or exception cases you can add a second approver — for example a license administrator — using the multi-stage approval option.

Under the Lifecycle tab, set the expiration. Set access package assignments to expire after a fixed duration — for subcontractors on a six-month contract, 180 days is a natural starting point. If you want users to define their own end date, enable users can request a specific timeline within the allowed maximum. For renewals, enable allow users to extend access and set require approval to grant extension to Yes — so every renewal is a conscious decision, not a silent continuation.

With this in place, the user goes to myaccess.microsoft.com, requests the upgraded tier, provides a justification and an end date, and the request lands in the approver’s inbox. The approver gets an email with all the details and can approve or deny directly — no service desk involved. When the expiry date arrives the access is removed automatically. If the need continues, the user requests a renewal — the same process, the same approval.

Step 4: Set up the lifecycle workflow to handle the transition

Workflows are what turn policy into enforcement


Up to this point, access is controlled at the time of request. Lifecycle workflows ensure it stays controlled over time. Without them, access is granted—but rarely removed. With them, expired access is cleaned up automatically and the system stays consistent.

In this setup, workflows are used to:

  • Remove access when assignments expire
  • Handle changes in user state (like role or department)
  • Ensure licenses are not left assigned without a valid reason

This is what closes the loop. Access is not just granted—it’s also maintained and cleaned up over time.

Workflow 1: Remove conflicting tiers on upgrade

This workflow ensures that a user only has one license tier at a time when upgrading.

In ID Governance > Lifecycle workflows, create a new workflow using the Employee group membership changes template. Set the trigger to Group membership change — Added to group, and scope it to all of your license groups.

Add the task Remove access package assignment for user and configure it for each of the other license tiers. When a user is added to LIC-M365-Tier3, the workflow fires and runs adminRemove on any active conflicting assignments.

The result: the user ends up with exactly one license tier. No stacking, no manual cleanup.

Workflow 2: Restore the Tier 1 baseline on expiry or removal

This workflow restores the baseline license when higher-tier access is removed or expires.

Create a second workflow, again using the Employee group membership changes template. This time set the trigger to Group membership change — Removed from group, and scope it to LIC-M365-Tier2 and LIC-M365-Tier3.

Add the task Add user to groups and configure it to add the user to LIC-M365-Tier1.

Known limitations

It is worth being transparent about a limitation here. Because Workflow 1 and Workflow 2 operate independently, there will be a short window where the user has no license — the higher tier has been removed, and the Tier 1 restoration has not yet completed. For most scenarios this gap is negligible, but it is real.

If zero-gap transitions are a hard requirement, this approach reaches its natural limit. A more complete solution would use a custom extension to trigger a Logic App, giving you precise control over the sequencing and timing of group assignments. That is outside the scope of this post, but it is the natural next step as your governance model matures.

Example: subcontractor license upgrade

Here is how that plays out in practice:

Supporting exceptions without losing control

Some requests will fall outside the standard tiers. Create a dedicated exception access package with a stricter approval chain — for example requiring both a manager and a license administrator. Set a shorter maximum duration and require approval for any extension. The exception is still possible. It just has an owner, an approval record, and an end date. That is all the difference between a workaround and a governed process.

Final thoughts

The approach described here is intentionally simple. No custom code, no external dependencies, and no service desk in the critical path. The manager — the person who actually knows whether the need is legitimate — gets the request, not IT. Every assignment, approval, and removal is recorded.

It is a starting point, not a finished product. The license gap on downgrade is a real limitation, and organizations with stricter requirements will want to go further — custom extensions in lifecycle workflows and Logic Apps can close that gap entirely.

There are many ways to solve the license governance problem. This is one way to get started with little effort, a clear audit trail, and a process that enforces itself.

Author

  • I work with Microsoft Entra ID Governance and identity automation — lifecycle workflows, access packages, and the real-world edge cases that break standard solutions. Based in Sweden, working with organizations on their identity governance journey. Find me on LinkedIn.

    View all posts

Discover more from Agder in the cloud

Subscribe to get the latest posts sent to your email.

By Sandra Saluti

I work with Microsoft Entra ID Governance and identity automation — lifecycle workflows, access packages, and the real-world edge cases that break standard solutions. Based in Sweden, working with organizations on their identity governance journey. Find me on LinkedIn.

Leave a Reply