Git is only the source of truth for access if Entra agrees with it. Sooner or later, someone with admin rights adds a person to a group directly in the Azure portal: a quick fix during an incident, a favour for a colleague, a step skipped under pressure. That change has no request, no reason and no approver. This post follows one such change and shows what Entitlements as Code does with it, depending on how the organization is set up.
The scenario
Ana works at ACME, a fictional company. She has asked for Contributor on the web-platform project, and her request is waiting for Marco, the group's owner. Someone decides not to wait and adds Ana to the WebPlatform Contributors group by hand in the Azure portal. Through the group, she now has the access.
Git does not list her. Entra and Git now disagree, and that difference is drift.
Animation: in the Azure portal someone adds Ana by hand to the WebPlatform Contributors group, with no request and no approval. Two outcomes, depending on the organization's mode. If it enforces, the membership goes back to what Git says: Ana is removed, and the audit log shows the removal by Entitlements as Code about a minute later. If it observes, nothing is changed and the web app's Drift page lists Ana as added outside Git, with Bring into Git and Remove, each of which opens a pull request for the owners.1HAND CHANGE1HAND CHANGE1HAND CHANGE2ENFORCE2ENFORCE2ENFORCE3OBSERVE3OBSERVEMembers | Microsof…portal.azure.com/#view/Group…Microsoft AzureEHome > Groups >Icon-identity-223ACME WebPlatform ContributorsGroup, Members+Add members↻RefreshNameBBenCChenDDanaAAnaAdded by handAdd membersanaAAnaUser, EngineeringSelectEliAdded by hand: no request, no approvalIf the organization enforcesMembers | Microsof…portal.azure.com/#view/Group…Microsoft AzureEHome > Groups >Icon-identity-223ACME WebPlatform ContributorsGroup, MembersNameBBenCChenDDanaAAnaAdded by handAudit logRemove member: AnaBy Entitlements as Code, 1 min laterBack to what Git saysIf it observesDrift | Entitlements …access.acme.example/driftEntitlements as CodeMDRIFTChanges made outside GitAAna added by handWebPlatform ContributorsBy Eli, in the Azure portalEach one opens a pull requestBring into GitRemoveNothing changes. It is reported.
One change made by hand, two outcomes: put back to what Git says, or reported for a person to decide.
If the organization enforces: back to what Git says
In an organization in enforce mode, Git is the record, and anything else is a mistake by definition. The membership Ana got by hand is removed on the next check of the group, about a minute in our tests, and the audit log in Entra shows that Entitlements as Code removed it.
Ana is not stuck. The way to get the access is the one already open: her request, approved by Marco.
Owners work the same way. An owner added by hand is removed, and the group's owners go back to the ones on record. A group with no owners on record is the exception: its Entra owners are left alone, so a team can bring owners under Git one group at a time.
If the organization observes: reported, and a person decides
Observe mode is read-only. Nothing is written to Entra, so Ana keeps the access she was given by hand. What changes is that it is no longer invisible: the web app's Drift page lists it, with who added it, to which group, and when.
From there, a person decides, with one click:
Bring into Git, if the access is right. It opens a pull request that adds Ana to the group's file, and the group's owner approves it like any request. From then on the access has a record.
Remove, if it is not. It opens a pull request that removes her, approved the same way.
Either way, nothing is removed by a job on its own. Taking access away from someone is a decision, so it stays with the owner, made with a request and recorded like any other.
Drift is not only additions. A member removed by hand, or a group created in Entra that Git does not know about, shows up too.
Side by side
Situation
A member added by hand
The organization enforces
Removed, back to what Git says, about a minute in our tests
The organization observes
Kept for now, listed on the Drift page, brought into Git or removed by its owner
An organization can move from one to the other over time. Observe suits the period when access is still partly granted by hand and Git is catching up. Enforce suits an organization whose records are trusted.
Access that should end, ends
Drift covers access granted outside Git. The other half of keeping access clean is access that was granted properly but is no longer needed.
End dates. A request can say until when. When the date comes, the access ends on its own. The approval already covered the end date, so nobody has to approve it again or remember it, and a pull request tidies the expired line out of Git.
Access reviews. Owners review their groups on a schedule. For each member they choose to keep or remove, and every removal is a request with a reason, recorded like any other.
Animation: Marco opens Reviews in the Entitlements as Code web app, where the quarterly review of the WebPlatform Contributors group lists each member. He keeps Ana, Chen and Dana and removes Ben, who has not used the access for five months; submitting opens one removal pull request. Then Ana's access reaches its end date, 31 January 2027: her My access page shows it expired and a removal pull request. In the Azure portal the group no longer has Ben or Ana, and the audit log shows both removals by Entitlements as Code.1REVIEW1REVIEW1REVIEW2END DATE2END DATE2END DATE3REMOVED3REMOVEDReviews | Entitlements as Codeaccess.acme.example/reviewsEntitlements as CodeMRequest accessApprovalsMy accessReviews1DriftMarcoREVIEWSWho should keep access to your groups?WebPlatform ContributorsQuarterly review, due 15 DecAAnaSince 4 Nov, until 31 Jan 2027KeepRemoveKeepBBenNot used for 5 monthsKeepRemoveRemoveCChenUsed this weekKeepRemoveKeepDDanaUsed todayKeepRemoveKeepSubmit review3 kept, 1 removalPull request #187 opened for Ben's removalMy access | Entitlements as Codeaccess.acme.example/my-accessEntitlements as CodeARequest accessApprovalsMy accessReviewsDriftAnaMY ACCESSWhat you have, and until whenIcon-devops-261web-platformAzure DevOps, acme, ContributorEnds in 7 days, 31 Jan 2027Ask to extendExpired on 31 Jan 2027Removal pull request #188Icon-devops-261docs-siteAzure DevOps, acme, ReaderNo end dateJANUARY 202731Access with an end date ends on its own.Nobody has to remember to remove it.Members | Microsoft Azureportal.azure.com/#view/Groups/MembersMicrosoft AzureSearch resources, services, and docsEHome > Groups | All groups >Icon-identity-223ACME WebPlatform Contributors | MembersGroupOverviewMembersOwnersAudit logsPropertiesNameTypeMember sinceCChenUser3 Jun 2025DDanaUser20 Sep 2025AAnaUserTodayBBenUser12 Mar 2025Audit logRemove member: Ben (review)Remove member: Ana (end date)By Entitlements as CodeRemoved through Git, like any other change
Animation: Marco opens Reviews in the Entitlements as Code web app, where the quarterly review of the WebPlatform Contributors group lists each member. He keeps Ana, Chen and Dana and removes Ben, who has not used the access for five months; submitting opens one removal pull request. Then Ana's access reaches its end date, 31 January 2027: her My access page shows it expired and a removal pull request. In the Azure portal the group no longer has Ben or Ana, and the audit log shows both removals by Entitlements as Code.1REVIEW1REVIEW1REVIEW2END DATE2END DATE2END DATE3REMOVED3REMOVEDReviews | Entitleme…access.acme.example/reviewsEntitlements as CodeMREVIEWSWho should keep access to your groups?WebPlatform ContributorsQuarterly, due 15 DecAAnaUntil 31 Jan 2027KeepRemoveKeepBBenUnused 5 monthsKeepRemoveRemoveCChenUsed this weekKeepRemoveKeepDDanaUsed todayKeepRemoveKeepSubmit reviewBen: removal pull request openedMy access | Entitle…access.acme.example/my-acce…Entitlements as CodeAMY ACCESSWhat you have, and until whenIcon-devops-261web-platformAzure DevOps, acme, ContributorEnds in 7 days, 31 Jan 2027Ask to extendExpired on 31 Jan 2027Removal pull request #188Icon-devops-261docs-siteAzure DevOps, acme, ReaderNo end dateJANUARY 202731Access with an end date ends on its own.Nobody has to remember to remove it.Members | Microsof…portal.azure.com/#view/Group…Microsoft AzureEHome > Groups >Icon-identity-223ACME WebPlatform ContributorsGroup, MembersNameCChenDDanaAAnaBBenAudit logRemove member: Ben (review)Remove member: Ana (end date)By Entitlements as CodeRemoved through Git, like any other change
Reviews and end dates: access that is no longer needed is removed through Git, like any other change.
Together they answer the questions an audit asks: who has access, who approved it, until when, and who checked that it is still needed.
Adopt Entitlements as Code on a live directory without changing it. Import what exists, observe with nothing written, then enforce one organization at a time.