You try to launch in the wrong Region

Same admin, different Region. Watch the SCP say no, and CloudTrail write it down anyway.

InternetAWS Organization · Todo.ioeu-west-1 · Irelandus-east-1 · N. Virginia (where Todo.io lives)You (Ryan)laptop + browserIAM Identity Centereveryday sign-inAWS Organizationsaccounts + SCPsCloudTrailorganization trailS3 buckettodoio-org-trailAdmin roleAdministratorAccessEC2RunInstancesSame setupfor trying things safelySign in1Step into Prod2Launch in Ireland3Guardrail check4Access denied5Still on the record6

Text version of this diagram.

What sits where:

  • AWS Organization · Todo.io: A group of AWS accounts with one owner (the management account) and one combined bill. contains:
    • Management account · 111111111111: The account that owns the organization and pays the bill. Keep apps out of it. The 12-digit number is its account ID. contains:
      • IAM Identity Center (everyday sign-in): Where people sign in to AWS every day: one login with MFA, then you pick an account and get a role in it.
      • AWS Organizations (accounts + SCPs): Groups many AWS accounts under one owner and one bill. SCPs (service control policies) are rules that cap what those accounts are allowed to do.
      • CloudTrail (organization trail): AWS's activity log: who did what, when and from where. An organization trail records every account in one place.
      • S3 bucket (todoio-org-trail): A named container for files in Amazon S3, AWS's file storage. This one holds the audit trail's log files.
    • Prod account · 222222222222: Production: the AWS account where the real Todo.io runs for real users. The 12-digit number is its account ID. contains:
      • eu-west-1 · Ireland: A Region is a part of the world where AWS has data centers. Most things you build live in one Region. eu-west-1 is in Ireland. contains:
        • EC2 (RunInstances): Elastic Compute Cloud: virtual servers you rent from AWS. RunInstances is the request that starts new ones.
      • us-east-1 · N. Virginia (where Todo.io lives): A Region is a part of the world where AWS has data centers. Most things you build live in one Region. us-east-1 is in northern Virginia.
      • Admin role (AdministratorAccess): A role is a set of permissions you step into for a while, with temporary keys. AdministratorAccess is AWS's ready-made policy that allows everything.
    • Dev account · 333333333333: Development: a separate AWS account for experiments, so a mistake there can't touch Prod. contains:
      • Same setup (for trying things safely): Dev gets the same pieces as Prod, so you can try changes without risking the real app.
  • You (Ryan) (laptop + browser)

Steps, in order:

  1. Sign in. Path: You (Ryan) → IAM Identity Center. You open Todo.io's IAM Identity Center access portal and sign in as ryan with a password and MFA. Not as root. Checks: setting: MFA code accepted → allow.
  2. Step into Prod. Path: IAM Identity Center → Admin role. You pick the Prod account. Identity Center gives you temporary credentials for an IAM role there, built from the AdministratorAccess permission set. Checks: iam: ryan is assigned AdministratorAccess in Prod → allow.
  3. Launch in Ireland. Path: Admin role → EC2. You switch the console to eu-west-1 and launch an EC2 instance. The console calls ec2:RunInstances in that Region.
  4. Guardrail check. Path: EC2 → AWS Organizations. The SCP denies everything outside us-east-1. Your AdministratorAccess doesn't matter: an explicit deny always wins. Checks: scp: OnlyUsEast1: eu-west-1 is denied → deny.
  5. Access denied. Path: EC2 → Admin role. The console shows "You are not authorized to perform this operation." EC2 hides the reason in an encoded message.
  6. Still on the record. Path: EC2 → CloudTrail → S3 bucket. CloudTrail records failed attempts too, with an error code. An auditor can see you tried.
Step 1 of 6
Step 1 of 6
  1. You open Todo.io's IAM Identity Center access portal and sign in as ryan with a password and MFA. Not as root.

    • ⚙Setting MFA code acceptedAllowed
  2. You pick the Prod account. Identity Center gives you temporary credentials for an IAM role there, built from the AdministratorAccess permission set.

    • 🔑IAM ryan is assigned AdministratorAccess in ProdAllowed
    Show me the real thing

    Who AWS thinks you are now

    arn:aws:sts::222222222222:assumed-role/AWSReservedSSO_AdministratorAccess_7a1b2c3d/ryan

    Exam tipBehind the scenes this is sts:AssumeRole. People never get long-lived keys; they borrow a role for a few hours.

  3. You switch the console to eu-west-1 and launch an EC2 instance. The console calls ec2:RunInstances in that Region.

  4. The SCP denies everything outside us-east-1. Your AdministratorAccess doesn't matter: an explicit deny always wins.

    • 🧱SCP OnlyUsEast1: eu-west-1 is deniedDenied

    Exam tipPolicy evaluation: an explicit Deny anywhere wins. Then SCPs must allow, and then an identity or resource policy must allow. Otherwise it is an implicit deny.

  5. The console shows "You are not authorized to perform this operation." EC2 hides the reason in an encoded message.

    Show me the real thing

    The error, and what decoding it reveals (trimmed)

    UnauthorizedOperation: You are not authorized to perform this operation.
    Encoded authorization failure message: 4cAdXq9…
    
    $ aws sts decode-authorization-message --encoded-message 4cAdXq9…
    "allowed": false, "explicitDeny": true,
    "matchedStatements": { "items": [{ "statementId": "OnlyUsEast1", "effect": "DENY", … }] }

    Exam tipEC2 encodes the reason for a denial. sts:DecodeAuthorizationMessage turns it back into readable JSON showing which statement said no.

  6. CloudTrail records failed attempts too, with an error code. An auditor can see you tried.

    Show me the real thing

    The CloudTrail event (trimmed)

    {
      "eventName": "RunInstances",
      "awsRegion": "eu-west-1",
      "recipientAccountId": "222222222222",
      "errorCode": "Client.UnauthorizedOperation"
    }

What to notice

  • AdministratorAccess is not the final word. An SCP Deny overrides it.
  • SCPs are guardrails for whole accounts: they apply to every user and role inside, even root.
  • Denied calls are logged too. CloudTrail is how you'd notice someone poking at things they shouldn't.