Skip to main content
KBY Technologies Logo
Graduate Track

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.

Building a Governed AWS Landing Zone with Entra ID Federation
Priya Nair 15 July 202611 min read Production Ready 95 min labCloud Infrastructure and Operations

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
Production note
Validate permissions, test changes in a non-production scope, record the previous state, and retain a rollback path before applying operational steps.

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.

RequirementMinimum standardWhy it matters
Entra ID licensingP1 (P2 for risk-based Conditional Access)Federation and Conditional Access both depend on it
Tenant roleGlobal Administrator or Application AdministratorNeeded to register the enterprise application and configure SCIM
AWS management accountRuns no workloadsHolds billing and org policy only — a compromised management account is a compromised organisation
OU structureSandbox, Workloads (Production/NonProduction), SecuritySCPs are only useful if they can target a tier, not the whole tree
Change processTicket and peer review requiredEvery 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  -SynchronizationJobId

Scope 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.

AWS landing zone

Permission setEntra ID groupSession durationMFA requirementTypical use
ReadOnlyAccesssg-aws-readonly8 hoursStandard CA policySupport, audit, observability
OperatorAccesssg-aws-operator4 hoursMFA + compliant deviceOn-call engineers, deploys
AdministratorAccesssg-aws-admin1 hourMFA + compliant device + PIM approvalPlatform team, change windows only
BreakGlassAdminlocal IAM, not federatedManual revokeHardware token, sealed envelopeEntra 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-trail

Enable 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 5

Cross-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.

AWS landing zone

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_POLICY

For 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 GROUP

If 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  -SynchronizationJobId

Never 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.

Leaving Graduate Track
Reader Interaction

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.

Loading comments...

Loading anti-spam check...

Continue the track

Related Graduate tutorials

View learning path