IAM & AWS Organizations¶
Notes from AWS Apprenticeship — ILT with Kris, February 2026.
Ultra-Short Summary¶
IAM controls what identities can do within an AWS account. AWS Organizations adds a governance layer above accounts — managing multiple accounts from one place using Service Control Policies (SCPs) as guardrails. The mental model: Organizations sets the maximum possible permissions; IAM grants actual permissions within that boundary.
The Permission Hierarchy¶
AWS Organizations (SCP) ← CEILING — nothing can exceed this
↓
IAM Policy ← grants actual permissions within the ceiling
↓
Resource Policy (optional)← cross-account or public access
↓
Session Policy (STS) ← restricts an assumed role session further
SCPs do not grant permissions. They only restrict what IAM can grant. An SCP deny blocks an action even if IAM explicitly allows it.
AWS Organizations¶
What It Does¶
- Centralised governance across multiple AWS accounts
- Hierarchy: Management Account → Root → OUs → Accounts
- Attach SCPs to enforce policy at scale across OUs or individual accounts
- Consolidated billing
Structure¶
Management Account
└── Root
├── Production OU
│ ├── Prod Account A
│ └── Prod Account B
└── Dev OU
├── Dev Account A ← sandbox
└── Dev Account B
Service Control Policies (SCPs)¶
SCPs define the maximum boundary for what any principal in an account or OU can do — including the root user of member accounts.
Key Rules¶
- Explicit SCP deny overrides everything — including IAM allows
- SCPs don't grant permissions — IAM policies still required
- Apply at: Root (whole org), OU, or individual Account
- Management Account is not affected by SCPs — protect it carefully
Common Pattern — Region Restriction¶
Force all workloads to stay in ap-southeast-2:
{
"Effect": "Deny",
"NotAction": [
"iam:*",
"organizations:*",
"route53:*",
"budgets:*",
"sts:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "ap-southeast-2"
}
}
}
NotAction = deny everything except the listed global services. IAM, Orgs, Route 53 are global — exclude them or you'll lock yourself out.
Use Explicit Deny on Sub-Accounts
Use explicit Deny rather than removing Allow statements. Removing an Allow from a child OU doesn't deny the action — only an explicit Deny actually blocks it.
IAM Core Concepts¶
Authentication vs Authorisation¶
| Concept | Question | AWS Example |
|---|---|---|
| Authentication | Who are you? | SAML, IAM credentials, SSO token |
| Authorisation | What can you do? | IAM policies, SCPs, resource policies |
Policy Evaluation Logic¶
1. Explicit DENY anywhere (SCP, IAM, resource policy)? → DENY immediately
2. SCP allows it? → continue
3. IAM policy allows it? → continue
4. Resource policy allows it? → ALLOW
Deny always wins. Everything is implicitly denied unless explicitly allowed.
IAM Policy Structure¶
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3Read",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"StringEquals": {"aws:RequestedRegion": "ap-southeast-2"}
}
}
]
}
| Field | What It Is |
|---|---|
Effect |
Allow or Deny |
Action |
AWS API call e.g. s3:GetObject |
Resource |
ARN of what's being accessed |
Condition |
Optional — restrict by IP, MFA, region, tag, time |
Roles vs Users¶
| Scenario | Use |
|---|---|
| EC2 instance needs S3 access | IAM Role (instance profile) |
| Lambda needs DynamoDB access | IAM Role (execution role) |
| Cross-account access | IAM Role (assume via STS) |
| Human developer → AWS console | IAM Identity Center (SSO) |
| CI/CD pipeline | OIDC federated role (no long-lived keys) |
| Legacy app with hardcoded keys | IAM User (last resort — rotate often) |
Why roles beat users: Roles use temporary STS credentials that expire automatically. Leaked role credentials have a limited damage window. Leaked IAM user keys are persistent until manually rotated.
Identity Federation¶
| Method | Use Case |
|---|---|
| SAML 2.0 | Enterprise SSO (Active Directory, Okta) |
| OIDC | Web/mobile app login (Google, GitHub) |
| IAM Identity Center | Org-level SSO across all accounts — preferred |
| Web Identity Federation | Mobile apps using social login |
Mental Model¶
Organizations = fire code for the building (you can't exceed it, period)
SCP = your floor's access rules
IAM = your keycard
You can't enter a room that:
- The fire code blocks
- Your floor's rules block
- Your keycard doesn't open
All three must allow the action.
SAA Patterns¶
| Scenario | Answer |
|---|---|
| Stop dev accounts launching in us-east-1 | SCP with aws:RequestedRegion condition |
| EC2 needs to read from S3 | IAM Role as instance profile |
| Audit all API calls across all accounts | CloudTrail org-wide trail |
| Enforce MFA for console logins | IAM condition aws:MultiFactorAuthPresent |
| Centralised login across 50+ accounts | IAM Identity Center |
| Deny a service across the whole org | SCP Deny at Root level |
30-Second Takeaway¶
- Organizations + SCPs set the ceiling. IAM grants within it.
- Explicit deny wins always.
- Roles > Users for services, EC2, Lambda — temporary creds are safer.
- IAM Identity Center is the modern replacement for individual IAM users.
- SCP at Root = enforced across the entire org, no exceptions.
Self-Quiz¶
- Can an SCP grant permissions? What does it actually do?
- IAM allows
s3:*. SCP deniess3:DeleteBucket. Can the user delete? - Why use
NotActionin a region restriction SCP instead of listing every service? - What's the difference between an IAM User and an IAM Role? Why prefer roles?
- Walk through the full policy evaluation order.
- What does IAM Identity Center replace and why is it preferred?
- You want sandbox accounts unable to access production resources. Where do you enforce this?
- Why do temporary STS credentials reduce risk vs long-lived IAM user keys?