devHọc Dev
Bài học

Ngày 3: IAM Nâng Cao

Tuần 1 – Ngày 3

Mục tiêu học tập

  • Hiểu sâu về IAM Policies và cách evaluate
  • Nắm vững IAM Roles và cross-account access
  • Hiểu Permission Boundaries và SCPs

1. IAM Policy Evaluation Logic

Thứ tự đánh giá

1. Explicit DENY  →  Nếu có → DENY (dừng lại)
          ↓
2. SCPs (Org)     →  Nếu không Allow → DENY
          ↓
3. Resource Policy →  Nếu Allow → ALLOW (cho cross-account)
          ↓
4. Permission Boundary →  Nếu không Allow → DENY
          ↓
5. Session Policy  →  Nếu không Allow → DENY
          ↓
6. Identity Policy →  Nếu Allow → ALLOW
          ↓
7. Implicit DENY   →  Mặc định DENY

Nguyên tắc quan trọng

  • Explicit Deny luôn thắng
  • Deny by default - không có Allow = Deny
  • Cross-account: Cần Allow từ CẢ HAI phía

2. Các loại IAM Policies

Identity-based Policies

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

Resource-based Policies

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:root"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

So sánh

LoạiAttached toPrincipal field
Identity-basedUser, Group, RoleKhông có
Resource-basedResource (S3, SQS, etc.)Bắt buộc

3. IAM Roles

Cấu trúc Role

IAMRoleTrustPolicy(Aiđưcassumerolenày?)Principal:Account,Service,FederatedUserPermissionPolicy(Rolenàyđưclàmgì?)ActionsvàResourcesPermissionBoundary(Optional)Giihntiđacapermissions

Trust Policy Example

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Các loại Roles phổ biến

LoạiPrincipalUse case
Service RoleAWS ServiceEC2 instance profile
Cross-account RoleAWS AccountAccess từ account khác
Identity Provider RoleFederatedSSO, SAML, OIDC

4. Cross-Account Access

Cách 1: Resource-based Policy

AccountA(ResourceOwner)AccountB(Requester)S3BucketIAMUserBucketPolicyUserPolicyAllowAccountBAllowS3access

Cách 2: IAM Role (Khuyến nghị)

AccountA(Trusting)AccountB(Trusted)IAMRoleIAMUserTrustPolicy:Permission:AllowAccountBAssumests:AssumeRoleRolePermissions:S3access

So sánh 2 cách

AspectResource PolicyIAM Role
AuditKhó hơnDễ hơn (CloudTrail)
FlexibilityChỉ 1 resourceNhiều resources
Best PracticeOne-off accessRegular access

5. Permission Boundaries

Định nghĩa

  • Giới hạn maximum permissions mà identity-based policy có thể cấp
  • Không cấp permissions, chỉ giới hạn

Ví dụ

PermissionBoundary:IdentityPolicy:Allow:EC2,S3,RDSAllow:EC2,S3,LambdaEffectivePermissions:EC2,S3(intersection)

Use case

  • Cho phép developers tự tạo roles nhưng giới hạn permissions
  • Delegated administration

6. Service Control Policies (SCPs)

Đặc điểm

  • Áp dụng ở AWS Organizations level
  • Ảnh hưởng tất cả principals trong account
  • KHÔNG ảnh hưởng management account

SCP Strategies

Strategy 1: Deny List (Khuyến nghị)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "organizations:LeaveOrganization"
      ],
      "Resource": "*"
    }
  ]
}

Strategy 2: Allow List

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:*",
        "s3:*"
      ],
      "Resource": "*"
    }
  ]
}

7. IAM Best Practices cho Professional level

  1. Least Privilege: Cấp quyền tối thiểu cần thiết
  2. Use Roles: Không dùng long-term credentials
  3. Enable MFA: Đặc biệt cho privileged actions
  4. Rotate Credentials: Định kỳ rotate access keys
  5. Use Conditions: Giới hạn theo IP, MFA, thời gian
  6. Audit Regularly: Dùng IAM Access Analyzer

8. Confused Deputy Problem & ExternalId

Vấn đề

Khi bạn cho bên thứ 3 (SaaS monitoring, partner, MSP...) assume một role trong account của mình, bên thứ 3 đó trở thành "deputy" — một entity có quyền hành động thay mặt nhiều khách hàng. Confused deputy xảy ra khi attacker lừa deputy dùng quyền của nó lên account KHÔNG thuộc về attacker:

SaaSProvider(Deputy)Account:999988887777CustomerABiếtRoleARNcaAAssumeRoleAccountA(chínhch)AttackerĐăngkýdchv,AssumeRoleAccountA(đoánRoleARNkhaiRoleARNcaA!(attackerđcđưccaAARNdatacaAquaSaaS)KHÔNGphisecret)
  • Role ARN có format đoán được (arn:aws:iam::<account-id>:role/<tên>), account ID không phải bí mật.
  • Attacker đăng ký cùng SaaS, khai Role ARN của nạn nhân → SaaS (deputy) vô tình assume role của nạn nhân và trả kết quả cho attacker.

Giải pháp: sts:ExternalId

Bên thứ 3 cấp cho MỖI khách hàng một ExternalId duy nhất (unique per-customer, do provider sinh ra — khách hàng không tự chọn). Trust policy của customer chỉ cho phép AssumeRole khi ExternalId khớp:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::999988887777:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "cust-a1b2c3-unique"
        }
      }
    }
  ]
}

Khi provider gọi AssumeRole, họ truyền ExternalId gắn với khách hàng đang request. Attacker khai Role ARN của nạn nhân nhưng ExternalId trong request là của attacker → không khớp condition → AccessDenied.

Lưu ý Professional:

  • ExternalId không phải secret (không thay thế MFA/credentials) — nó chỉ là "scoping mechanism" chống confused deputy, chống dùng nhầm chứ không chống lộ credentials.
  • Provider phải là bên sinh ra và gắn cứng ExternalId per-customer; nếu để khách hàng tự nhập ExternalId tuỳ ý thì attacker nhập trùng được → vô hiệu.
  • IAM Access Analyzer flag các role trust bên thứ 3 mà thiếu ExternalId condition.

Biến thể service-to-service: aws:SourceArn / aws:SourceAccount

Confused deputy cũng xảy ra giữa các AWS service: ví dụ SNS topic hoặc S3 bucket của attacker gọi KMS key / Lambda / SQS của bạn, vì service principal (sns.amazonaws.com, s3.amazonaws.com) là CHUNG cho mọi account. Chặn bằng condition trong resource policy:

{
  "Effect": "Allow",
  "Principal": { "Service": "sns.amazonaws.com" },
  "Action": ["kms:GenerateDataKey*", "kms:Decrypt"],
  "Resource": "*",
  "Condition": {
    "ArnLike": {
      "aws:SourceArn": "arn:aws:sns:us-east-1:111122223333:my-topic"
    },
    "StringEquals": {
      "aws:SourceAccount": "111122223333"
    }
  }
}
Tình huốngCơ chế chống confused deputy
Bên thứ 3 (human/app) assume role cross-accountsts:ExternalId trong trust policy
AWS service gọi resource thay mặt bạn (SNS→KMS, S3→SQS...)aws:SourceArn + aws:SourceAccount trong resource policy

Exam keywords: "third-party access", "SaaS provider needs access", "prevent confused deputy" → nghĩ ngay đến ExternalId. "Service acting on your behalf" → aws:SourceArn/aws:SourceAccount.

9. Custom Identity Broker

Khi nào cần?

Khi corporate IdP nội bộ KHÔNG hỗ trợ SAML 2.0 hoặc OIDC (legacy LDAP, hệ thống auth tự viết...) — không dùng được SAML federation hay IAM Identity Center trực tiếp. Bạn phải tự viết một Identity Broker: app trung gian tự authenticate user với IdP, rồi gọi STS lấy temporary credentials.

Luồng hoạt động

1.Login2.VerifyUserIdentityCorporateBrokerIdP(LDAP..)(appt3.OK+viết)userinfo4.BrokerTmapuserIAMrole/policySTSAssumeRolehocGetFederationToken5.Tempcreds(hocconsolesign-inURL)6.GiAWSAPI/mAWSConsoleAWSConsole/API
  1. User authenticate với broker; broker verify với corporate IdP.
  2. Broker tự xác định user được map vào IAM role/policy nào (đây là khác biệt lớn nhất so với SAML — không có assertion attribute mapping tự động).
  3. Broker gọi STS:
    • AssumeRole (khuyến nghị): credentials 15 phút–12 giờ, permissions = role policy (∩ session policy nếu truyền).
    • GetFederationToken: gọi bằng long-term credentials của IAM user (broker chạy on-prem), tối đa 36 giờ; permissions = identity policy của IAM user ∩ session policy truyền vào — BẮT BUỘC truyền session policy, nếu không token gần như không có quyền gì.
  4. Broker trả temporary credentials cho user (API/CLI), hoặc tạo console sign-in URL qua federation endpoint (https://signin.aws.amazon.com/federation với action getSigninTokenlogin).

Trade-offs (Professional level)

  • Bạn phải TỰ chịu trách nhiệm: verify identity, mapping user→role, vault credentials của broker, audit. Broker trở thành high-value target — chính nó cũng là một deputy cần bảo vệ.
  • Multi-account: broker có thể assume role vào từng member account (hub-spoke từ identity account) — nhưng tự quản lý mapping ở scale lớn rất tốn công → đây là lý do AWS khuyến nghị migrate IdP sang SAML/OIDC hoặc IAM Identity Center khi có thể.

So sánh nhanh: khi nào dùng gì?

AspectSAML Federation / Identity CenterCustom Identity BrokerCognito
Điều kiện IdPIdP hỗ trợ SAML 2.0/OIDCIdP KHÔNG hỗ trợ chuẩn nàoWeb/mobile app users (không phải workforce)
Ai map user → permissionsIdP assertion attributes → role tự độngBroker phải TỰ code logic mappingIdentity Pool role mapping (rules/token claims)
Ai gọi STSAWS tự xử lý (AssumeRoleWithSAML/WithWebIdentity)Broker tự gọi AssumeRole/GetFederationTokenCognito Identity Pool gọi hộ
Operational overheadThấpCao (tự build + maintain)Thấp
Use case điển hìnhWorkforce SSO vào Console/CLILegacy IdP, yêu cầu auth đặc thùCustomer-facing app cần AWS creds scoped

Exam keywords: "identity provider does NOT support SAML" → Custom Identity Broker + STS. "Mobile/web app users" → Cognito. "SAML 2.0-compliant IdP" → SAML federation / IAM Identity Center.

10. Câu hỏi ôn tập

  1. Khi có Explicit Deny và Explicit Allow, kết quả là gì?

    Xem đáp án

    Explicit Deny luôn thắng — kết quả là DENY bất kể có bao nhiêu Allow statements. Đây là nguyên tắc cốt lõi của IAM policy evaluation: Explicit Deny > Explicit Allow > Implicit Deny (default). Áp dụng khi đánh giá tất cả policies: identity-based, resource-based, SCP, Permission Boundary, session policies.

  2. Cross-account access bằng Role khác Resource Policy như thế nào?

    Xem đáp án

    Role: principal B assume role trong account A → nhận temporary credentials → dùng credentials để access resources trong A. Cần trust policy (who can assume) + permission policy (what can do). Resource Policy (ví dụ S3 bucket policy): grant principal từ account B access trực tiếp, không cần assume role. Resource policy đơn giản hơn cho specific resources; Role dùng khi cần access nhiều resources hoặc cần assume identity khác.

  3. Permission Boundary có thể cấp thêm quyền không?

    Xem đáp án

    Không — Permission Boundary chỉ giới hạn permissions tối đa (ceiling), không grant permissions. Effective permissions = intersection của Identity-based policy AND Permission Boundary. Ví dụ: Boundary cho phép S3+EC2, Identity policy cho phép S3+DynamoDB → effective chỉ là S3. Dùng Boundary để cho phép admins tạo roles/users nhưng không vượt quá scope đã định — delegate IAM safely.

  4. SCP có ảnh hưởng đến management account không?

    Xem đáp án

    Không — Management account (root account của AWS Organization) không bị SCP apply, kể cả SCP attach vào root OU. SCPs chỉ affect member accounts. Best practice: không deploy workloads trong management account và dùng dedicated member accounts cho workloads. Management account chỉ dùng cho billing, organization management, Control Tower setup.

  5. Một SaaS provider cần assume role vào account của nhiều khách hàng. Làm sao chống confused deputy?

    Xem đáp án

    Dùng condition sts:ExternalId trong trust policy của role: provider sinh một ExternalId duy nhất per-customer và truyền nó trong mỗi AssumeRole call; trust policy của khách hàng chỉ Allow khi ExternalId khớp. Attacker biết Role ARN của nạn nhân (ARN không phải secret) nhưng ExternalId gắn với tài khoản SaaS của attacker không khớp → AccessDenied. Lưu ý: ExternalId không phải secret/không thay thế credentials — chỉ chống dùng nhầm quyền. Với biến thể service-to-service (SNS/S3 gọi KMS...), dùng aws:SourceArn + aws:SourceAccount trong resource policy.

  6. Corporate IdP không hỗ trợ SAML 2.0 — làm sao cho nhân viên access AWS Console mà không tạo IAM user?

    Xem đáp án

    Xây Custom Identity Broker: broker authenticate user với corporate IdP, tự xác định IAM role/policy tương ứng, gọi STS AssumeRole (hoặc GetFederationToken) lấy temporary credentials, rồi tạo console sign-in URL qua federation endpoint (https://signin.aws.amazon.com/federation). Khác SAML federation: broker phải TỰ code logic mapping user → role (SAML thì IdP assertion làm việc này). Nếu IdP hỗ trợ SAML/OIDC → luôn ưu tiên SAML federation / IAM Identity Center (ít operational overhead hơn). Nếu là app user (web/mobile) → Cognito.

11. Bài tập thực hành

  • Tạo IAM Role cho EC2 instance với quyền đọc S3
  • Thử cross-account access (nếu có 2 accounts)
  • Tạo policy với conditions (IP restriction)

Tài liệu tham khảo chính thức


Ngày tiếp theo: VPC Fundamentals Review