A new access tool should not start by writing to a live directory. Your Entra groups already have members and owners, and your platforms already grant access through those groups. If the tool enforced its files on day one and the files were wrong, every mistake would become a change in someone's access. So Entitlements as Code starts read-only, and enforcing is something you switch on later, one organization at a time.
The examples use a fictional company, ACME, with two Azure DevOps organizations: ACME, where its product teams work, and LABS, a smaller one for experiments.
Import what exists, observe with nothing written, then enforce one organization at a time.
Step 1: import what already exists
Nobody should have to write the access files by hand for a directory that already exists. Entitlements as Code imports the groups you have today, with their members and owners, and writes one file per group into Git. Each file is linked to its existing group in Entra, so nothing is created twice.
From then on, the files describe the access people have today, not the access someone thinks they have. That is the right starting point: first Git has to match reality, and only then do you change reality through Git.
Read the import with the group owners. It records what exists; it does not judge it. Some memberships will look wrong. Note them, but resist fixing everything in the first change. Fixes are easier to review as separate, small requests, each with its own reason.
Step 2: observe, with nothing written
Every organization starts in observe mode. Nothing is written: no members, no owners, no groups. Users are a special case in every mode: they are read from Entra and never changed.
What you get while nothing changes:
Requests and approvals, on real data. People ask in the web app, owners approve, and every change is reviewed and recorded as a pull request.
Checks on your actual groups. Naming, duplicate members, circular nesting and sensitive groups with no owner are flagged before anyone has to spot them.
A drift report. The web app lists the access granted outside Git. During observe, that is usually access still granted the old way, by hand. Each one can be brought into Git for review, or removed.
Since nothing is written, an approved request in an organization that observes is recorded but not applied. Observe is for getting Git and Entra to agree, not for granting access yet.
What to check before enforcing
Use the observe period to get three things right:
Drift close to zero. Each difference is either access to bring into Git or access to question. When the report is empty, Git and Entra agree.
Owners on every group. In enforce mode, the owners on record become the group's owners in Entra, and owners added by hand are removed. A group with no owners on record leaves its Entra owners alone, so you can bring owners in one group at a time.
Owners who will approve. Approvals come from the owners. Make sure each group has owners who know they now review the requests.
Step 3: enforce one organization at a time
When an organization is ready, an EaC admin switches it to enforce in the web app. The switch is itself a request: it opens a pull request, another EaC admin approves it, and it has an author and a history like every other change.
Animation: in the Entitlements as Code web app an EaC admin opens Organizations, where ACME and LABS are both in observe mode: read only, differences reported. The admin switches ACME to enforce; a dialog explains that merged changes will be applied and changes made by hand reverted, and that this opens a pull request. In Azure DevOps the pull request Enforce ACME is approved by another EaC admin and completed. Back in the web app ACME shows Enforce while LABS stays in Observe.1SWITCH1SWITCH1SWITCH2APPROVE2APPROVE2APPROVE3ENFORCED3ENFORCEDOrganizations | Entit…access.acme.example/organiza…Entitlements as CodeEORGANIZATIONSHow Entitlements as Code treats each oneIcon-devops-261ACMEAzure DevOps, 48 groupsGit and Entra matchObserveIcon-devops-261LABSAzure DevOps, 12 groups3 differences to reviewObserveSwitch to enforceSwitch to enforceSwitch ACME to enforce?Merged changes will be applied,and changes made by handwill be reverted. LABS is notaffected. This opens a pullrequest for the EaC admins.Open pull requestCancelPull request #151 opened for approvalIcon-devops-261Pull request 151 | Az…dev.azure.com/acme/access/_g…Icon-devops-261Repos/Pull requestsDActiveCompletedPull request 151Enforce ACMEEEli wants to merge settings/acme-enforce into mainOverviewFilesDescriptionSwitch acme from observe to enforce.Requested by Eli in Entitlements as Code.LABS stays in observe.ReviewersDDanaEaC admin, approved in Entitlements as CodeRequiredApprovedChecksAccess files are validEaC admin approvalMerged by Entitlements as CodeOrganizations | Entit…access.acme.example/organiza…Entitlements as CodeEORGANIZATIONSHow Entitlements as Code treats each oneIcon-devops-261ACMEAzure DevOps, 48 groupsGit and Entra matchObserveEnforceApplies Git, reverts hand changesIcon-devops-261LABSAzure DevOps, 12 groups3 differences to reviewObserveACME enforces. LABS keeps observing.
One request switches ACME to enforce. LABS keeps observing.
From then on, for that organization only:
Approved requests are applied. The change reaches Entra and every platform that follows the groups, with no ticket and nobody in an admin console.
Changes made by hand go back to what Git says. A member or owner added outside Git is removed; one removed outside Git is put back.
Users stay read-only. They are still only read from Entra.
Other organizations keep their own mode. One that still observes stays read-only until it is switched.
Why one organization at a time
Each organization has its own groups, owners and habits. Switching one keeps the effect small and easy to watch: you learn how the first one behaves, fix what the observe period missed, and then move to the next. An organization whose owners are not ready can wait in observe mode without holding back the others.
The order is the same for every organization: import, observe until Git matches Entra, then enforce.