CertNote/ Commute Study Notes
Roadmap
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
  • Week 1
    • 1.AWS Infrastructure Through an Operator's Eyes: Regions, AZs, and the Boundary of Responsibility
    • 2.IAM Operator's Manual: Users, Groups, Roles, Policy Evaluation Algorithm
    • 3.Advanced IAM: Building Guardrails with Permission Boundary, SCP, and Identity Center
    • 4.AWS Organizations: How One Person Operates 100 Accounts
    • 5.Week 1 Consolidated Review: Revisiting the First Week Through Operator Scenarios
  • Week 2
  • Week 3
  • Week 4
  • Week 5
  • Week 6
  • Week 7
  • Week 8
  • Week 9
  • Week 10
  • Week 11
  • Week 12
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
Linux Master 2 · 2급KAIT Linux Master - Level 2
SCS-C03 · SpecialtySecurity - Specialty
Linux Master 1 · 1급KAIT Linux Master - Level 1
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
SQLD · 개발자SQL Developer (SQLD)

© CertNote · 주간랩스

  • About
  • Changelog
  • Contact
  • Terms
  • Privacy
← SOA-C02/Week 1/Day 3

Based on the SOA-C02 exam guide·Report an error

SOA-C02· AssociateWeek 1 · Day 3~21 min read

Day 3 - Advanced IAM: Building Guardrails with Permission Boundary, SCP, and Identity Center

Yesterday's IAM evaluation algorithm described single-account permission flow. But real companies don't operate one account—they segment: Operations, Development, Data Analytics, Security Audit, Billing. Each account then distributes users by department and role. A company with 100 AWS accounts is common (Amazon itself has tens of thousands), and the question becomes: "How do we prevent a developer with AdministratorAccess from obtaining permissions close to company IAM root?" Today's answer: SCP, Permission Boundary, and IAM Identity Center.

All three solve the same goal (delegation safety net) but at different layers. When operators miss that layer distinction, they flounder through "why isn't permission working?" or "why can't I block this?"

The Math of Delegation: SCP ∩ Boundary ∩ Identity Policy

Whether user U in account A can do action X is calculated by:

effective_permission(U, X) =
    SCP_on_account(A)
  ∩ permission_boundary(U)
  ∩ identity_policy(U)
  ∩ (resource_policy(X) OR identity_policy(U))
  ∩ session_policy(if assumed)
  - any_explicit_deny

Each ∩ (intersection) means "only what's Allow-ed here AND also Allow-ed in the next step passes." SCP denies = identity policy irrelevant. Boundary denies = identity policy irrelevant.

The operator value of this structure: safety net for delegation. Security team writes SCP + Boundary guardrails; developers delegate create Roles freely within them.

💡 Related Theory: This model combines capability-based security (authority token) and ABAC. Saltzer & Schroeder's "The Protection of Information in Computer Systems" (1975, CACM) defined Least Privilege; this implements it at distributed scale. Effective permission via policy intersection is a lattice-based access control variant (Denning, 1976). Since Bell-LaPadula (1973) formalized mandatory access control for military security, the "intersection of multiple policies" paradigm became the standard for distributed system security.

Six SCP Operator Patterns

SCP (Service Control Policy) is organization-level guardrail. Regardless of IAM permissions, it makes "this action is impossible in this account." Operators commonly use:

1. Force Specific Regions

{
  "Effect": "Deny",
  "NotAction": ["iam:*", "support:*", "route53:*", "cloudfront:*",
                "organizations:*", "sts:*", "waf:*", "globalaccelerator:*"],
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": ["ap-northeast-2", "us-east-1"]
    }
  }
}

This SCP blocks all regions except ap-northeast-2 and us-east-1 (excluding IAM, support, route53, cloudfront, organizations, sts, waf). Stops "EC2 bitcoin mining in a region the operator doesn't watch" scenarios. Post-account breach, attackers often "spin c6i.32xlarge × 100 in an obscure region." Region-lock SCP blocks that entirely.

2. Block Root User Actions

{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringLike": {
      "aws:PrincipalArn": "arn:aws:iam::*:root"
    }
  }
}

Forces no daily work from root. Management account root is exempt from SCP (exception), so this applies to member accounts only. Since 2024, AWS lets management account centralize root access (aws iam centralize-root-access).

3. Block CloudTrail Disabling

{
  "Effect": "Deny",
  "Action": [
    "cloudtrail:StopLogging",
    "cloudtrail:DeleteTrail",
    "cloudtrail:UpdateTrail",
    "cloudtrail:PutEventSelectors"
  ],
  "Resource": "*"
}

Prevents intruders from covering tracks. GuardDuty flags Stealth:IAMUser/CloudTrailLoggingDisabled, but SCP blocks, not detects.

4. Enforce IMDSv2

{
  "Effect": "Deny",
  "Action": "ec2:RunInstances",
  "Resource": "arn:aws:ec2:*:*:instance/*",
  "Condition": {
    "StringNotEquals": {
      "ec2:MetadataHttpTokens": "required"
    }
  }
}

Forces IMDSv2 on new EC2. Stronger than Config rule—blocks creation itself. Adopted universally post-Capital One.

5. Force S3 Encryption

{
  "Effect": "Deny",
  "Action": "s3:PutObject",
  "Resource": "*",
  "Condition": {
    "Null": {
      "s3:x-amz-server-side-encryption": "true"
    }
  }
}

Blocks S3 PutObject without SSE header. Since 2023, S3 auto-applies SSE-S3 default; add StringNotEquals: aws:kms for KMS-only enforcement.

6. Block Expensive Instance Types (Sandbox OU)

{
  "Effect": "Deny",
  "Action": "ec2:RunInstances",
  "Resource": "arn:aws:ec2:*:*:instance/*",
  "Condition": {
    "ForAnyValue:StringNotLike": {
      "ec2:InstanceType": ["t3.*", "t4g.*", "m5.large", "m5.xlarge"]
    }
  }
}

Applied to dev sandbox OU to block expensive instance accidents. SCP is policy-based, so applies consistently to IaC too.

⚠️ Pitfall: SCP never grants Allow. Even Allow: s3:* in SCP is just a whitelist—real permission granting is IAM Policy. Another: SCP doesn't apply to service-linked roles or AWS service principals' internal API calls.

🔍 Deeper Dive: Removing FullAWSAccess from SCP means account can't do anything. SCP attached to OU applies to all descendant accounts. Pattern: organize OUs by environment (prod, dev, sandbox) → apply appropriate SCP per OU. Sandbox gets "EC2 t3 medium max," Prod gets "region lock + IAM change restriction." Max 5 SCP per account, 5120 character limit per policy. Operators distribute and compose multiple SCPs across OU hierarchy.

📚 Case Study: 2023 SaaS company—GitHub Actions OIDC role too permissive, PR code injection stole IAM admin. But prod OU's SCP denied iam:CreateUser + iam:CreateAccessKey, so attacker couldn't create permanent credentials. After 24 hours, STS token expired and auto-locked. SCP was last-resort breach containment.

Permission Boundary Pattern

If SCP is account-wide ceiling, Permission Boundary is per-user/role ceiling. Most common: "delegate Role creation to developers" while enforcing boundary guardrails.

{
  "Effect": "Allow",
  "Action": ["iam:CreateRole", "iam:AttachRolePolicy", "iam:PutRolePolicy"],
  "Resource": "arn:aws:iam::*:role/Dev-*",
  "Condition": {
    "StringEquals": {
      "iam:PermissionsBoundary":
        "arn:aws:iam::123456789012:policy/DeveloperBoundary"
    }
  }
}

Developer-created Roles must start Dev- and attach DeveloperBoundary. Effective permission = boundary-limited only.

Why This Pattern Matters

If operators create all Roles = bottleneck. If developers get just iam:CreateRole = risky. Boundary = balanced. Security team writes one solid boundary; developers free-build inside it.

Applies to IaC too (Terraform/CDK auto-create Roles). Terraform's aws_iam_role gets forced permissions_boundary attribute, company-managed.

📚 Case Study: 2022 fintech—developer created Lambda Role with AdministratorAccess, SSRF breach exposed RDS. Post-incident: boundary pattern adopted. iam:CreateRole allowed, boundary removes RDS/KMS write, operations require ops team Role assumption. Lambda effective permission bounded; breach contained.

⚠️ Pitfall: Boundary sets Allow ceiling, not Deny. If boundary only has Allow: s3:*, identity policy's other permissions are filtered—S3 only passes. Boundary only applies identity-side; cross-account resource policy Allow can't be blocked by boundary.

IAM Identity Center: User Management Done Right

Creating IAM Users for every employee is anti-pattern:

  1. Repeat MFA enforce, access key rotation, offboarding per account
  2. Cross-account access = users manage N access keys
  3. Offboarding miss = #1 incident cause
  4. MFA device scattered per user

Solution: IAM Identity Center (ex-AWS SSO). Single user source (external IdP or built-in directory), one login for all AWS accounts.

[Employee]
   │
   ├─ Okta / Azure AD / Google Workspace (SAML 2.0 or SCIM)
   │       │
   │       ▼
   │  IAM Identity Center (one login)
   │       │
   ├──────┼──────┬──────┬──────┐
   ▼       ▼      ▼      ▼      ▼
 Prod   Dev    Audit  Logs  Billing
 Account Account Account Account Account
   │
   Each account auto-grants permissions via Permission Set (auto-generated IAM Role)

Permission Set: Identity Center's Permission Container

Permission Set = "permissions a user has in one account." Essence: auto-created IAM Role (AWSReservedSSO_<PSName>_<hash>) + user assumption mapping.

PermissionSet: AdministratorAccess
  - Managed Policy: AdministratorAccess
  - Session Duration: 4 hours
  - User: user@company.com → automatically available all accounts
  - Customer Managed Policy: optional add
  - Permissions Boundary: optional

Operators manage which Permission Set each user has in which account. User logs console → sees accessible account list → clicks → gets STS temp creds → console opens. CLI: aws configure sso + aws sso login for browser auth.

🔍 Deeper Dive: Identity Center credentials are also STS temp. Session 1-12 hours per Permission Set. No permanent access key. CLI also uses aws sso login (browser auth) for temp creds. ~/.aws/sso/cache/ token valid during SSO session (~90 days max), but new STS temp creds issued each use. This is the standard for all automation.

📚 Case Study: Company—200 employees, 100 accounts. Employee had avg 8 access keys. Rotation/offboarding misses = dozens of monthly alerts. Identity Center: keys nearly gone, offboard employee = IdP disable = instant all-account lock. IdP group permissions (e.g., "data-engineers: PowerUser all dev, ReadOnly prod") = zero permission change burden.

ABAC: Tag-Based Permission Grant

For scale, IAM supports ABAC (Attribute-Based Access Control): grant permissions via tags, not user/role IDs.

{
  "Effect": "Allow",
  "Action": ["ec2:StartInstances", "ec2:StopInstances"],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:ResourceTag/Department": "${aws:PrincipalTag/Department}"
    }
  }
}

One policy: "employees start/stop EC2s tagged with their department." No policy explosion for 100 people × 1000 EC2. Identity Center maps IdP attributes (e.g., AD department) to PrincipalTag; department change in IdP = AWS permission auto-change.

💡 Related Theory: ABAC standardized in NIST SP 800-162. RBAC's N×M (role × permission) matrix explodes; ABAC solves via dynamic attribute eval. IAM implements all ABAC elements (subject, resource, environment attributes) via Condition. Google Zanzibar (2019) solved same via ReBAC (Relationship-Based—graph of group membership). AWS = tag ABAC, Google = relation graph, Azure = Resource Hierarchy. Same problem, different answers.

Service-Linked Role: Special Roles Operators Don't Create

AWS services (ECS, Auto Scaling, ELB, GuardDuty) auto-generate dedicated Roles for service-to-service calls. These are Service-Linked Roles (SLR).

Traits:

  • Fixed name: AWSServiceRoleFor*
  • Operator can't modify policy: AWS manages
  • Trust Policy locked: only that service assumes
  • Deletable only when service unused

⚠️ Pitfall: Deleting SLR triggers dependency checks; in-use = rejected. Exam: "ECS cluster auto-generated Role—modify it?" Answer: "Can't—AWS manages." SCP can't block SLR operations (service principal bypass).

CloudTrail IAM Debugging Pattern

Standard denial-trace pattern:

SELECT eventTime, eventName, errorCode, errorMessage,
       userIdentity.type, userIdentity.arn,
       requestParameters.bucketName
FROM cloudtrail_logs
WHERE errorCode = 'AccessDenied'
  AND eventTime > '2025-05-25T00:00:00Z'
ORDER BY eventTime DESC
LIMIT 100;

Four things to check:

  1. userIdentity.type: IAMUser, AssumedRole, AWSService, Root, FederatedUser
  2. userIdentity.arn: exact caller
  3. eventName + requestParameters: action + resource
  4. errorMessage: why denied (which policy)

🔍 Deeper Dive: "explicit deny in identity-based policy" = identity policy denied. "explicit deny in resource-based policy" = resource policy. "implicit deny" = nowhere allowed. "explicit deny in service control policy" = SCP. This one line tells you where to look. Standardized since 2022.

Wrapping Up

Today's diagram: IAM permissions built in multi-layer guardrails. SCP (account-level), Boundary (user/role-level), Identity Policy (actual grant), Resource Policy (target-side allow). Any layer's Deny wins. Identity Center adds auth/SSO atop this, solving N-account user management explosion.

Tomorrow: AWS Organizations and multi-account governance making all this possible. How to manage 100 accounts consistently.

📝 Practice Questions

Click a choice to reveal the answer and explanation.

Question 1

SCP has Allow: s3:*, IAM Policy has Deny: s3:DeleteObject, Bucket Policy has Allow: s3:DeleteObject. Result?

Question 2

Operator wants developers to create Roles but enforce Role must attach DevBoundary policy. Answer?

Question 3

200 employees, 50 accounts. Minimize user management burden?

Question 4

Force all accounts: only ap-northeast-2 and us-east-1 allowed. Best tool?

Question 5

Auto-created AWSServiceRoleForECS from new cluster—modify its permissions?

Question 6

Identity Center user gets STS token via CLI. Which command?

PreviousIAM Operator's Manual: Users, Groups, Roles, Policy Evaluation AlgorithmWeek 1 · Day 2Next AWS Organizations: How One Person Operates 100 AccountsWeek 1 · Day 4

Official references

  • SOA-C02 official exam page(opens in a new tab)
  • AWS Organizations documentation(opens in a new tab)
  • AWS IAM documentation(opens in a new tab)
  • AWS CloudTrail documentation(opens in a new tab)
  • Amazon S3 documentation(opens in a new tab)
  • IAM Identity Center documentation(opens in a new tab)

On this page

  • The Math of Delegation: SCP ∩ Boundary ∩ Identity Policy
  • Six SCP Operator Patterns
  • 1. Force Specific Regions
  • 2. Block Root User Actions
  • 3. Block CloudTrail Disabling
  • 4. Enforce IMDSv2
  • 5. Force S3 Encryption
  • 6. Block Expensive Instance Types (Sandbox OU)
  • Permission Boundary Pattern
  • Why This Pattern Matters
  • IAM Identity Center: User Management Done Right
  • Permission Set: Identity Center's Permission Container
  • ABAC: Tag-Based Permission Grant
  • Service-Linked Role: Special Roles Operators Don't Create
  • CloudTrail IAM Debugging Pattern
  • Wrapping Up
  • Practice Questions