Building a Governed AWS Landing Zone with Entra ID Federation
Learn how to build a governed AWS landing zone using Entra ID federation, IAM Identity Center, SCIM provisioning, and Service Control Policies for enterprise-grade security.

Mission brief
What you will achieve
Complete a production-safe implementation and leave with verification and rollback evidence.
Practical steps
8 guided stages
Follow these in order as your working checklist.
Time to set aside
About 95 minutes
Includes configuration, validation and rollback checks.
Tutorial navigation
Before you begin
- AWS Organizations fundamentals
- Entra ID enterprise application and SAML configuration
- IAM permission boundaries and SCP syntax
#Operational requirement
You have been assigned to build the AWS landing zone that replaces the current sprawl of standalone accounts. Before you touch a single organisational unit, understand why this exists. Every unmanaged AWS account is a liability. A project team spins up an account with an undocumented root email address, creates a couple of local IAM users because sorting out SSO “takes too long”, and six months later that account has an EC2 instance sitting behind an open security group, an IAM user holding AdministratorAccess with a password nobody has ever rotated, and zero CloudTrail visibility because no one enabled an organisation trail. When credential-stuffing bots find that account — and they will — there is no Conditional Access policy standing in the way, no Entra ID sign-in log to correlate against, and no way to tell an auditor who actually had access to production data on a given date.
Your job is to close that gap permanently. You will build a single AWS Organizations structure with Entra ID as the authoritative identity provider through AWS IAM Identity Center, enforce guardrails with Service Control Policies at the organisational-unit level, and route every provisioning and decommissioning action through change control. Get the SCPs wrong and you will lock the entire platform team out of production mid-incident, or leave a permission set wide enough that a support analyst can terminate an RDS instance by accident. Either mistake becomes a Sev1 ticket and a conversation with your CISO that nobody enjoys.
#Prerequisites and permissions
Confirm every item below before you open a single console tab. Do not skip the licensing check — half of the SSO failures a junior admin chases turn out to be a missing P1 seat.
| Requirement | Minimum standard | Why it matters |
|---|---|---|
| Entra ID licensing | P1 (P2 for risk-based Conditional Access) | Federation and Conditional Access both depend on it |
| Tenant role | Global Administrator or Application Administrator | Needed to register the enterprise application and configure SCIM |
| AWS management account | Runs no workloads | Holds billing and org policy only — a compromised management account is a compromised organisation |
| OU structure | Sandbox, Workloads (Production/NonProduction), Security | SCPs are only useful if they can target a tier, not the whole tree |
| Change process | Ticket and peer review required | Every SCP attach and permission set edit is a production change |
If your organisation is still running flat under the root OU, stop here and fix that first. SCPs attached at root apply everywhere, including the management account, and that is almost never what you want. Get the delegated administrator for IAM Identity Center assigned to your team specifically — do not leave it shared across every account owner, or you will spend your first month untangling who changed what.
#Implementation steps
#1. Register AWS as an Entra ID enterprise application
Add the gallery application for “AWS IAM Identity Center” rather than building a generic SAML app by hand. The gallery template ships with correct attribute mappings and cuts the risk of a broken assertion later. Assign the application to a security group, never to individual users — call it sg-aws-sso-eligible and manage membership through your existing joiner-mover-leaver process.
1Connect-MgGraph -Scopes "Application.ReadWrite.All"
2Get-MgApplicationTemplate -Filter "displayName eq 'AWS IAM Identity Center'"
3# Instantiate from the returned template ID, then set SSO mode to SAML
4Set-MgServicePrincipal -ServicePrincipalId -PreferredSingleSignOnMode "saml"In IAM Identity Center, point the external identity provider at the Entra ID SAML metadata URL and confirm the NameID format is set to persistent. Map Subject to user.userprincipalname, not the email address attribute — using email here is the single most common mistake and it breaks the moment someone’s UPN and primary SMTP address diverge after a name change.
#2. Enable SCIM provisioning
Manual account assignment does not scale and creates drift you will not notice until an access review. Configure SCIM provisioning from Entra ID so group membership changes propagate automatically into Identity Center.
1New-MgServicePrincipalSynchronizationJob -ServicePrincipalId -TemplateId "awsSSO"
2Start-MgServicePrincipalSynchronizationJob -ServicePrincipalId -SynchronizationJobIdScope the sync to only the security groups relevant to AWS access. Push every group in a 40,000-object tenant into Identity Center and you will hit AWS’s SCIM throttling limits, then spend an afternoon watching retry loops instead of fixing anything.
#3. Define permission sets by risk tier, not by team
Do not build a permission set per department. Departments reorganise; risk tiers do not. Build four sets and map Entra ID groups onto them per account, as below.

| Permission set | Entra ID group | Session duration | MFA requirement | Typical use |
|---|---|---|---|---|
| ReadOnlyAccess | sg-aws-readonly | 8 hours | Standard CA policy | Support, audit, observability |
| OperatorAccess | sg-aws-operator | 4 hours | MFA + compliant device | On-call engineers, deploys |
| AdministratorAccess | sg-aws-admin | 1 hour | MFA + compliant device + PIM approval | Platform team, change windows only |
| BreakGlassAdmin | local IAM, not federated | Manual revoke | Hardware token, sealed envelope | Entra ID tenant outage only |
Keep the break-glass tier deliberately outside federation. If your identity provider is down, your escape hatch cannot depend on it. Store those credentials in a physical safe or a hardware-backed vault under dual custody, and rotate them every single time they are used — no exceptions, no matter how minor the incident felt.
#4. Attach Service Control Policies at the OU level
SCPs are the actual guardrail. Attach a deny policy on the Workloads/Production OU that blocks local IAM user creation outside the management account, restricts deployment regions, and denies disabling CloudTrail.
1{
2 "Version": "2012-10-17",
3 "Statement": [
4 {
5 "Sid": "DenyLocalIAMUserCreation",
6 "Effect": "Deny",
7 "Action": ["iam:CreateUser", "iam:CreateAccessKey"],
8 "Resource": "*"
9 },
10 {
11 "Sid": "DenyRegionsOutsideApproved",
12 "Effect": "Deny",
13 "NotAction": ["iam:*", "organizations:*", "sts:*", "support:*"],
14 "Resource": "*",
15 "Condition": {
16 "StringNotEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-west-2"] }
17 }
18 },
19 {
20 "Sid": "DenyCloudTrailTamper",
21 "Effect": "Deny",
22 "Action": ["cloudtrail:StopLogging", "cloudtrail:DeleteTrail"],
23 "Resource": "*"
24 }
25 ]
26}Get this policy peer-reviewed through change control before it goes anywhere near Production. Test it first against the NonProduction OU using aws organizations attach-policy. An SCP that denies the wrong action on the wrong OU does not throw a friendly warning — it silently breaks every deployment pipeline touching that OU until someone notices the build failures piling up.
#5. Turn on the organisation trail and Config aggregator
1aws cloudtrail create-trail --name org-trail --s3-bucket-name kby-cloudtrail-logs --is-organization-trail --is-multi-region-trail
2aws cloudtrail start-logging --name org-trailEnable AWS Config with an aggregator in the management account so tag-compliance and encryption rules run centrally instead of per-account. An untagged production resource should generate an AWS Config non-compliant finding routed straight into your existing ticketing queue — not discovered three months later during a cost review, by which point nobody remembers who created it.
#Change control and monitoring
Nothing in this landing zone gets built in one sitting, and nothing gets touched again without a ticket. Roll the SCPs out in three stages: attach and test against NonProduction for at least one full sprint, then attach to a single canary account in Production, then extend to the rest of the Production OU only after the canary has run clean for a week. Log every attach, detach, and permission set edit with the change ticket number in the commit message for the SCP repository, because that ticket number is what you hand an auditor.
Wire an alert from AWS Config non-compliance findings and from CloudTrail AccessDenied events on iam:CreateUser into your existing monitoring channel. A spike in denied CreateUser attempts usually means either an SCP is working exactly as designed, or a legacy automation script nobody documented is still trying to provision local users the old way. Both are worth knowing about immediately, not at the next quarterly review.
#Verification
Confirm federation works end to end before you announce the cutover to anyone. Sign in through the IAM Identity Center portal URL using a test account in sg-aws-operator and confirm it lands in the correct account with the correct permission set — not AdministratorAccess by default, which happens when a permission set assignment gets duplicated across accounts during a console copy-paste.
1aws sso-admin list-account-assignments --instance-arn --account-id --permission-set-arn
2aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin --max-results 5Cross-reference the CloudTrail login event timestamp against the Entra ID sign-in log for the same user and confirm the correlation ID chain is intact. This is exactly what your incident responders will rely on during a real investigation, so verify it now, not during a live Sev1 at three in the morning. Finally, attempt iam:CreateUser from inside a Production-OU account; it must return an explicit deny referencing the organisation policy, not a generic permissions error.
#Failure Modes
SCIM group sync lag is the most common support ticket you will generate. A user gets added to sg-aws-operator in Entra ID, tries to sign in five minutes later, and gets told they do not have access to the requested account, because the provisioning job runs on a schedule, not instantly. Check the synchronization job status before assuming the SCP is at fault.

SAML assertion failures usually present as an invalid response in the Identity Center console, and the root cause is almost always clock skew or a NameID format mismatch introduced when someone hand-edits the enterprise application’s claims after the gallery template was applied. Do not hand-edit claims. If a mapping change is genuinely needed, make it through the enterprise application’s SSO configuration blade and re-test against a non-production account first.
SCPs applied too broadly are the lockout scenario every junior admin fears. If a deny statement targets the wrong OU and happens to include sts:AssumeRole, federated sign-in for that entire OU stops working immediately — including for the platform team trying to fix it. This is precisely why the break-glass tier exists outside federation. Use it, detach the offending policy, then do the post-incident review afterwards, not during the outage.
Duplicate UPNs or stale email attributes in Entra ID cause SCIM provisioning errors that surface in the provisioning logs as attribute values containing disallowed characters. This is almost always a legacy on-premises AD sync artefact — a user renamed years ago whose UPN was never cleaned up. Fix it in the source directory. Fixing it in AWS only masks the underlying data-quality problem.
#Rollback
Keep every SCP version in source control with the account and OU it was attached to recorded in the commit message. You cannot roll back what you never versioned. If a policy attachment causes a lockout, use the break-glass credentials to detach it immediately.
1aws organizations detach-policy --policy-id --target-id
2aws organizations list-policies --filter SERVICE_CONTROL_POLICYFor a bad permission set assignment, revoke it rather than deleting the permission set outright — deleting the set also strips historical audit context from the Identity Center console, and that context is exactly what an auditor asks for.
1aws sso-admin delete-account-assignment --instance-arn --account-id --permission-set-arn --principal-id --principal-type GROUPIf SCIM provisioning is misbehaving and creating incorrect assignments faster than you can fix them, disable the synchronization job in Entra ID first to stop the bleeding, correct the source group membership, then restart it.
1Stop-MgServicePrincipalSynchronizationJob -ServicePrincipalId -SynchronizationJobIdNever roll back by deleting the enterprise application itself unless you are decommissioning the entire federation. That severs SCIM state and forces a full re-provisioning cycle across every linked account, which is a far longer outage than the one you were trying to fix.
#Operational Summary
A governed landing zone is not a one-off project you close out and forget. It is a standing control that needs quarterly access reviews, SCP drift detection, and a named owner who gets paged when AWS Config reports a non-compliant resource. Assign the break-glass rotation to a specific person with a calendar reminder, not to “whoever remembers” — that role always ends up unowned within two quarters. Run the permission set assignment list against Entra ID group membership monthly and reconcile any manual assignment that bypassed SCIM, because those are the ones nobody remembers granting six months later, and they are exactly what an audit finding is made of. The entire point of this architecture is simple: when someone asks who had production access on a given date and why, you produce a CloudTrail event, an Entra ID sign-in log, and a change ticket, and all three agree with each other without you having to reconstruct anything from memory.
Reader Support: KBY Technologies is an independent engineering editorial. We may earn a commission from affiliate links when you purchase infrastructure, software, or tools through our recommendations. This helps fund our research and labs.
Advanced suggested reading
Ready to go deeper?
These articles come from KBY’s senior engineering editorial. Expect denser architecture, fewer introductory explanations and deeper production trade-offs.
Tech Fundamentals
Zero-Downtime Cloud Identity Migration from AD
Cloud Identity migration from AD hinges on GCDS key selection, SAML federation cutover order, and dual-delivery mail routing to avoid duplicate accounts and mail loops.
Security & Operations
Detecting DNS Tunnelling via Resolver Entropy
How Shannon entropy scoring, dnstap capture, and PowerDNS Lua hooks catch DNS tunnelling exfiltration that firewall egress rules miss entirely.
Security & Operations
Sudoers NOPASSWD: The Silent Path to Root
Wildcard NOPASSWD entries in sudoers quietly open root shells; here's how the escalation chain forms, how to audit it fleet-wide, and how to fix it.
Comments
Add a thoughtful note on Building a Governed AWS Landing Zone with Entra ID Federation. Comments are checked for spam and held for moderation before appearing.
Continue the track
Related Graduate tutorials
Automating Stale Device Cleanup in Intune and Entra ID
A hands-on runbook for junior engineers to identify, retire and remove stale Intune and Entra ID devices without breaking Conditional Access.
Retiring Legacy Per-User MFA for Entra ID Authentication Policy
A staged runbook for clearing legacy per-user MFA and hardening Entra ID authentication methods without locking out users or losing break-glass access.
Publishing a Production Knowledge-Base Article Safely
A production-safe walkthrough for graduate engineers on drafting, reviewing, staging, approving, publishing, and rolling back knowledge-base articles.