Sử Dụng IAM Groups: Gán Policy Trực Tiếp Cho User Hay Dùng Group?

Bạn vừa onboard một developer mới và cần cấp quyền truy cập S3, CodeCommit, CloudWatch. Gán thẳng policy vào user cho nhanh — ai cũng từng làm vậy. Sáu tháng sau, team có 15 người, mỗi người một mớ policy gắn trực tiếp, và không ai còn biết chắc ai đang có quyền gì. Đây là vấn đề cốt lõi mà IAM Groups được thiết kế để giải quyết.

TL;DR — IAM Groups vs. Gán Policy Trực Tiếp

Tiêu chíGán Policy Trực Tiếp (User)IAM Group
Quản lý quyền theo vai tròThủ công, lặp lạiTập trung, nhất quán
Onboard/offboard userPhải gán/xóa từng policyThêm/xóa user khỏi group
Audit quyền truy cậpPhải kiểm tra từng userKiểm tra policy tại group
Rủi ro cấu hình saiCao — dễ bỏ sót hoặc thừa quyềnThấp hơn — policy dùng chung
Giới hạn policies per entity10 managed policies per user10 managed policies per group
Phù hợp với Well-ArchitectedKhông khuyến nghịĐược khuyến nghị

IAM Groups Hoạt Động Như Thế Nào

IAM Group không phải là một identity — group không thể đăng nhập, không có credentials, và không thể là principal trong một resource-based policy. Group đơn thuần là một container chứa IAM users, cho phép gán managed policies hoặc inline policies một lần và áp dụng cho tất cả members.

Khi một IAM user thuộc nhiều group, AWS hợp nhất tất cả permissions từ các group đó cùng với permissions gắn trực tiếp vào user. Đây là union — không có group nào 'ghi đè' group khác. Tuy nhiên, một Explicit Deny ở bất kỳ đâu — dù trong user policy hay group policy — vẫn luôn thắng.

graph TD G1["Group: Developers
S3ReadOnly + CloudWatchLogs"] G2["Group: DevOps
EC2Describe + SSMAccess"] U1["IAM User: alice"] U2["IAM User: bob"] U3["IAM User: carol"] UP["Direct Policy on alice
(nên tránh)"] EP["Effective Permissions = Union
Group policies + Direct policies"] G1 --> U1 G1 --> U2 G2 --> U1 G2 --> U3 UP --> U1 U1 --> EP style UP fill:#ff9999,stroke:#cc0000 style EP fill:#d4edda,stroke:#28a745
  1. IAM User có thể thuộc nhiều group cùng lúc (tối đa 10 groups per user theo giới hạn mặc định).
  2. Permissions được tính là union của tất cả attached policies từ user và tất cả groups mà user là member.
  3. Explicit Deny từ bất kỳ policy nào trong chuỗi đó sẽ override mọi Allow — đây là nguyên tắc IAM evaluation logic cơ bản.
  4. Group không thể nest — bạn không thể đặt group vào trong group khác. Đây là hard limitation của IAM.

Tại Sao Gán Policy Trực Tiếp Vào User Là Vấn Đề

Về mặt kỹ thuật, gán policy trực tiếp vào user hoàn toàn hợp lệ. AWS không ngăn bạn làm điều đó. Vấn đề nằm ở operational overhead khi scale.

Giả sử bạn cần thu hẹp quyền S3 của toàn bộ team Developers — chỉ cho phép s3:GetObject thay vì s3:*. Với direct attachment, bạn phải vào từng user, tìm đúng policy, sửa hoặc thay thế. Với IAM Group, bạn sửa một policy duy nhất tại group — thay đổi propagate ngay lập tức cho tất cả members.

Nghĩ về IAM Group như một role template cho con người — không phải cho service. Bạn định nghĩa 'Developers được làm gì' một lần, rồi gán người vào vai trò đó, không phải ngược lại.

Một vấn đề thực tế khác: khi audit. AWS IAM Access Analyzer và các công cụ như IAM credential report hoạt động ở user level. Nếu mỗi user có một tập policy khác nhau dù cùng vai trò, việc xác minh 'tất cả developers có đúng quyền cần thiết và không có quyền thừa' trở thành công việc thủ công tốn kém.

Tạo IAM Group và Gán Policy — Thực Hành

Dưới đây là quy trình đầy đủ: tạo group, gán managed policy, thêm user vào group, và xác minh.

Bước 1: Tạo IAM Group

Tạo group trước khi gán bất kỳ policy nào — group rỗng hoàn toàn hợp lệ và không phát sinh chi phí.

aws iam create-group \
  --group-name Developers

Bước 2: Gán Managed Policy Vào Group

Gán AWS managed policy hoặc customer managed policy vào group. Ví dụ dưới đây gán AmazonS3ReadOnlyAccess — trong thực tế, bạn nên dùng customer managed policy với quyền tối thiểu cần thiết thay vì AWS managed policy rộng.

aws iam attach-group-policy \
  --group-name Developers \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Bước 3: Thêm IAM User Vào Group

User phải tồn tại trước khi thêm vào group. Lệnh này idempotent — chạy lại không gây lỗi nếu user đã là member.

aws iam add-user-to-group \
  --group-name Developers \
  --user-name alice

Bước 4: Xác Minh Group Membership và Policies

Kiểm tra ai đang trong group và policy nào đang được gán — đây là bước audit cơ bản nhất.

# Liệt kê users trong group
aws iam get-group \
  --group-name Developers

# Liệt kê policies gắn vào group
aws iam list-attached-group-policies \
  --group-name Developers

Bước 5: Xác Minh Effective Permissions Của User

Sau khi thêm user vào group, kiểm tra effective permissions để đảm bảo không có policy trực tiếp nào trên user đang conflict hoặc mở rộng quyền ngoài ý muốn.

# Kiểm tra policies gắn trực tiếp vào user
aws iam list-attached-user-policies \
  --user-name alice

# Kiểm tra user thuộc những group nào
aws iam list-groups-for-user \
  --user-name alice

Xây Dựng Customer Managed Policy Cho Group

AWS managed policies tiện nhưng thường rộng hơn cần thiết. Trong môi trường production, tạo customer managed policy với quyền tối thiểu là best practice theo AWS Well-Architected Framework.

Ví dụ policy cho group Developers — chỉ cho phép đọc objects từ một S3 bucket cụ thể và xem CloudWatch logs:

🔽 Click để xem: Customer Managed Policy cho Developers Group
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3ReadSpecificBucket",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-app-artifacts",
        "arn:aws:s3:::my-app-artifacts/*"
      ]
    },
    {
      "Sid": "CloudWatchLogsReadOnly",
      "Effect": "Allow",
      "Action": [
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams",
        "logs:GetLogEvents",
        "logs:FilterLogEvents"
      ],
      "Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/app/*"
    }
  ]
}

Tạo policy từ file JSON và gán vào group:

# Tạo customer managed policy
aws iam create-policy \
  --policy-name DevelopersBasePolicy \
  --policy-document file://developers-policy.json

# Gán vào group (thay 123456789012 bằng account ID thực)
aws iam attach-group-policy \
  --group-name Developers \
  --policy-arn arn:aws:iam::123456789012:policy/DevelopersBasePolicy

Một Lỗi Thực Tế: Khi Group Policy Không Có Hiệu Lực

Triệu chứng: user alice thuộc group Developers, group có policy cho phép s3:GetObject, nhưng alice vẫn nhận AccessDenied khi truy cập bucket.

Chẩn đoán ban đầu thường là 'policy chưa propagate' hoặc 'cache IAM'. Cả hai đều sai — IAM policy changes có hiệu lực gần như ngay lập tức.

Nguyên nhân thực tế trong phần lớn trường hợp này: S3 bucket có bucket policy với Explicit Deny cho principal * trừ một số role cụ thể, hoặc bucket đang bật Block Public Access kết hợp với một ACL cũ. Bucket policy Explicit Deny override IAM Allow — đây là điểm mà nhiều người bỏ qua khi debug.

# Kiểm tra bucket policy
aws s3api get-bucket-policy \
  --bucket my-app-artifacts

# Kiểm tra Block Public Access settings
aws s3api get-public-access-block \
  --bucket my-app-artifacts

Nếu bucket policy có "Effect": "Deny" với "Principal": "*" và không có điều kiện exclude IAM users, đó là nguyên nhân. Sửa bucket policy để explicitly allow group hoặc thêm condition phù hợp — không phải sửa IAM group policy.

Khi Nào Nên Dùng IAM Roles Thay Vì Groups

IAM Groups chỉ dành cho IAM users — tức là con người. Nếu bạn đang cấp quyền cho:

  • EC2 instances, Lambda functions, ECS tasks → dùng IAM Roles
  • Cross-account access → dùng IAM Roles với trust policy
  • Federated users (SSO, Active Directory) → dùng IAM Identity Center (SSO) với Permission Sets

Trong môi trường enterprise hiện đại, AWS khuyến nghị dùng IAM Identity Center thay vì IAM users và groups truyền thống — đặc biệt khi có nhiều AWS accounts. Tuy nhiên, với single-account setup và team nhỏ, IAM Groups vẫn là giải pháp đơn giản và hiệu quả.

graph TD START["Identity cần cấp quyền"] Q1{"Là con người?"} Q2{"Single account?"} Q3{"Là AWS service
hoặc workload?"} G["IAM User + IAM Group"] SSO["IAM Identity Center
với Permission Sets"] ROLE["IAM Role"] START --> Q1 Q1 -->|"Có"| Q2 Q1 -->|"Không"| Q3 Q2 -->|"Có, team nhỏ"| G Q2 -->|"Nhiều accounts / SSO"| SSO Q3 -->|"Có"| ROLE style G fill:#cce5ff,stroke:#004085 style SSO fill:#d4edda,stroke:#155724 style ROLE fill:#fff3cd,stroke:#856404
  1. Nếu identity là con người trong cùng AWS account → IAM User + IAM Group là lựa chọn phù hợp.
  2. Nếu có nhiều accounts hoặc cần SSO → IAM Identity Center với Permission Sets là hướng được AWS khuyến nghị hiện tại.
  3. Nếu identity là service hoặc workload → IAM Role, không bao giờ dùng IAM User với long-term credentials.

Wrap-Up: Sử Dụng IAM Groups Đúng Cách

Gán policy trực tiếp vào IAM user không sai về mặt kỹ thuật, nhưng không scale được và tạo ra operational debt tích lũy theo thời gian. IAM Groups giải quyết vấn đề này bằng cách tách biệt 'định nghĩa quyền theo vai trò' khỏi 'gán quyền cho từng cá nhân'.

Nguyên tắc vận hành: định nghĩa permissions tại group, quản lý membership tại user. Khi cần thay đổi quyền của một vai trò, sửa một chỗ — không phải mười lăm chỗ.

Tài liệu tham khảo chính thức: AWS IAM User Guide — IAM Groups.

Glossary — Thuật Ngữ Chính

Thuật ngữGiải thích
IAM GroupContainer chứa IAM users để quản lý permissions tập trung. Không phải identity, không thể đăng nhập.
Managed PolicyIAM policy độc lập có thể gán cho nhiều users, groups, hoặc roles. Có hai loại: AWS managed và customer managed.
Explicit DenyDeny statement trong IAM policy luôn override Allow từ bất kỳ policy nào khác trong evaluation chain.
Effective PermissionsTập hợp quyền thực tế của một user sau khi hợp nhất tất cả policies từ user và tất cả groups mà user là member.
IAM Identity CenterDịch vụ AWS quản lý SSO và access cho nhiều accounts, được khuyến nghị thay thế IAM users/groups truyền thống trong môi trường multi-account.

Related Posts

Nhận xét

Bài đăng phổ biến từ blog này

EC2 Không Có Internet Trong Custom VPC: Cách Gắn Internet Gateway và Cập Nhật Route Table

RDS Multi-AZ: Lợi Ích Thực Sự Là Gì và Khi Nào Nên Bật?

Lỗi CORS trên API Gateway: Cách bật CORS và Lambda phải trả về header gì