Hướng dẫn toàn tập về AWS Identity and Access Management (IAM)

Tìm hiểu từ A-Z về AWS IAM, các thành phần như User, Group, Role, Policy và cách quản lý quyền truy cập trên AWS an toàn, chuẩn xác.

Hướng dẫn toàn tập về AWS Identity and Access Management (IAM)

IAM (Identity and Access Management) là dịch vụ quản lý việc truy cập AWS một cách an toàn và bảo mật, kiểm soát đăng nhập và quyền sử dụng dịch vụ của từng danh tính. IAM cho phép tạo thêm các danh tính (identity) trong tài khoản AWS.

Một IAM identity khi được tạo sẽ không có bất cứ quyền sử dụng bất cứ dịch vụ nào, nhưng có thể được cấp quyền tối đa gần tương đương với quyền của Root User. Có 3 loại identity có thể tạo trong IAM là: IAM User, IAM Group, và IAM Role. Tuy nhiên, trước khi đi sâu vào các identity, chúng ta hãy tìm hiểu cách cấp quyền thông qua IAM Policy.

Nội dung bài viết

  1. IAM Policy
    • ARN (Amazon Resource Name)
  2. IAM User
  3. IAM Group
  4. IAM Role
  5. Resource Policy

1. IAM Policy

IAM Policy xác định một identity được phép thực hiện (Allow) hoặc bị chặn (Deny) những hành động gì, trên những dịch vụ nào của AWS. Policy có thể là Identity‑based (gắn vào IAM User/Group/Role), hoặc Resource‑based (gắn trực tiếp vào tài nguyên, ví dụ như S3 bucket policy).

QUAN TRỌNG: Độ ưu tiên khi xác định quyền trong policy, trong trường hợp có xung đột, được sắp xếp từ cao xuống thấp như sau:

  1. Explicit Deny (Từ chối rõ ràng): Đây là mức độ ưu tiên cao nhất. Khi trong policy có một luật “Deny” một hành động trên một tài nguyên bất kỳ, identity được/bị gắn policy này sẽ không được phép thực hiện nó, kể cả khi trong cùng policy có một luật khác “Allow” hành động đó trên cùng tài nguyên đó.
  2. Explicit Allow (Cho phép rõ ràng): Mức độ ưu tiên tiếp theo, cho phép identity thực hiện hành động, trừ khi có một lệnh Explicit Deny vô hiệu hoá nó (Deny có thể trên cùng hoặc khác policy với Allow, do một identity có thể được gán nhiều policy).
  3. Implicit Deny (Ngầm từ chối): Mức độ ưu tiên thấp nhất. Đây là khi trong policy không có lệnh nào đề cập đến một hành động, hành động đó sẽ mặc định bị ngầm từ chối.

Dễ thấy rằng thiết kế này của AWS tập trung cao độ vào vấn đề bảo mật. Hãy phân tích policy dưới đây (lưu ý: cú pháp JSON tiêu chuẩn không hỗ trợ comment, nếu bạn copy policy này để sử dụng, hãy bỏ các comment đi):

{
    "Version": "2012-10-17",
    "Statement": [
        {   
            "Sid": "S3FullAccess",
            "Effect": "Allow", 
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "DenyAccessToABucket",
            "Effect": "Deny", 
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::denied-bucket",
                "arn:aws:s3:::denied-bucket/*" 
            ]
        }
    ]
}

Các trường chính trong Policy:

  • Version: Phiên bản của ngôn ngữ policy (không phải ngày tạo). Giá trị phổ biến luôn là: "2012-10-17".
  • Statement (Bắt buộc): Tập hợp các luật xác định quyền của identity. Mỗi luật (statement) gồm có:
    • Sid (Tuỳ chọn): Dùng để đặt tên định danh, giúp dễ hình dung mục đích cho luật.
    • Effect (Bắt buộc): Nhận giá trị "Allow" hoặc "Deny".
    • Action: Các hành động API bị ảnh hưởng bởi luật (ví dụ: s3:GetObject).
    • Resource: Các tài nguyên AWS bị ảnh hưởng bởi luật.

Ngoài ra còn có thể có Principal (đối tượng áp dụng policy, thường dùng cho resource‑based policy), Condition (điều kiện áp dụng), hoặc các trường phủ định như NotAction, NotResource để loại trừ các hành động hoặc tài nguyên không bị luật ảnh hưởng.

Giải thích ví dụ trên:

  • Luật đầu tiên cho phép (Explicit Allow) thực hiện tất cả hành động trên S3 (như s3:*) trên tất cả tài nguyên (mọi bucket và object trên S3).
  • Luật thứ hai từ chối rõ ràng (Explicit Deny) việc thực hiện tất cả hành động trên bucket có tên denied-bucket và tất cả các object trong bucket đó (xác định bởi denied-bucket/*).

Do đó, dù luật đầu tiên cho phép hoạt động trên toàn bộ bucket, nhưng luật thứ hai là Explicit Deny có độ ưu tiên cao hơn sẽ vô hiệu hoá tất cả các quyền đó. Các hành động và dịch vụ khác không được đề cập sẽ bị ngầm từ chối (Implicit Deny). Tổng hợp lại, identity mang policy này sẽ có quyền làm mọi thứ trên tất cả S3 bucket, ngoại trừ bucket denied-bucket và các object trong đó.

Phân loại Policy:

  • Inline policy: Mỗi identity có một inline policy nhúng trực tiếp, xác định quyền hạn của identity đó và không thể chia sẻ cho identity khác.
  • Managed policy: Có thể tái sử dụng để gán cho nhiều identity. Nó được chia thành:
    • AWS managed policy: AWS cung cấp sẵn, không thể chỉnh sửa.
    • Customer managed policy: Do người dùng tự tạo ra, có thể tuỳ ý thay đổi và quản lý.

Hầu hết các trường hợp thực tế sẽ ưu tiên sử dụng managed policy để dễ quản lý, tái sử dụng, tránh việc phân mảnh quyền hạn.

ARN (Amazon Resource Name)

ARN là cách định danh duy nhất cho bất cứ tài nguyên AWS nào trong bất cứ tài khoản nào. Cú pháp cơ bản như sau:

arn:partition:service:region:account-id:resource-id
arn:partition:service:region:account-id:resource-type/resource-id
arn:partition:service:region:account-id:resource-type:resource-id

Chi tiết các thành phần:

  • arn: Là tiền tố cố định.
  • partition: Vùng dịch vụ của AWS. Có 3 giá trị: "aws" (thương mại toàn cầu), "aws-us-gov" (chính phủ Mỹ), và "aws-cn" (Trung Quốc). Thường chúng ta chỉ dùng "aws".
  • service: Tên dịch vụ (ví dụ: "s3", "iam", "ec2", "lambda").
  • region: Tên khu vực (ví dụ: "us-east-1", "ap-southeast-1"). Các dịch vụ Global (không có region như IAM) sẽ để trống phần này.
  • account-id: Định danh ID tài khoản AWS (chuỗi 12 chữ số). Một vài dịch vụ như S3 cũng sẽ để trống trường này.
  • resource-type / resource-id: Định danh tên/ID tài nguyên cụ thể.

Ví dụ về ARN S3 Bucket:

arn:aws:s3:::techcoban-bucket

ARN này định danh một S3 bucket tên là techcoban-bucket. Chú ý, nó chỉ định danh bucket, không bao gồm object bên trong. Muốn chỉ định object, ta dùng ARN:

arn:aws:s3:::techcoban-bucket/duong-dan-den-object

Hoặc dùng ký tự đại diện wildcard * để lấy tất cả object:

arn:aws:s3:::techcoban-bucket/*

2. IAM User

IAM User là danh tính đại diện cho người hoặc ứng dụng được cấp quyền truy cập tài khoản AWS.

Với người dùng thực tế, IAM User sẽ được cấp tên đăng nhập (IAM username) và mật khẩu, dùng để đăng nhập và sử dụng AWS Management Console theo các quyền được cấp. Ngoài ra, IAM User có thể tạo ra Access Key để sử dụng AWS Command Line Interface (CLI) hoặc gọi API trong code. Access key chính là cơ chế giúp cấp quyền cho ứng dụng hoạt động tương tự như một người dùng thật.

Tại thời điểm viết bài, bạn có thể tạo tối đa 100,000 IAM Users trong một tài khoản AWS (có thể yêu cầu AWS tăng thêm giới hạn).


3. IAM Group

Một cách đơn giản, IAM Group là một tập hợp chứa các IAM User có liên quan, có chung quyền truy cập. Ví dụ: bạn có thể tạo các group Developers, HR, Admins và phân quyền chung cho chúng thay vì đi phân quyền từng User riêng lẻ.

Mặc định policy của IAM Group sẽ được áp dụng cho tất cả user thuộc group đó. Nếu một user được cấp thêm policy riêng biệt thì quyền của họ sẽ là sự kết hợp (gộp) của cả policy cá nhân và policy từ Group (tuân thủ theo nguyên tắc độ ưu tiên policy đã nêu ở phần 1).

Lưu ý:

  • Không thể tạo IAM Group nằm lồng bên trong một IAM Group khác.
  • IAM Group không có thông tin đăng nhập (credential) riêng nên không thể đăng nhập.
  • Không thể chọn IAM Group làm Principal trong Resource Policy.
  • Giới hạn hiện tại: Tối đa 100,000 IAM Group / 1 tài khoản và một IAM User thuộc tối đa 100 Group.

4. IAM Role

Phía trên có đề cập việc sử dụng Access Key của IAM User để cấp quyền cho ứng dụng. Tuy nhiên, cách này không được khuyến khích do nguy cơ lộ lọt bảo mật cao. Thay vào đó, IAM Role là phương pháp best practice được AWS khuyên dùng.

Lý do chọn IAM Role:

  • Bảo mật vượt trội nhờ sử dụng cơ chế cấp quyền tạm thời.
  • Một IAM Role có thể được sử dụng chung (assume) bởi nhiều đối tượng (dịch vụ, User khác tài khoản…) mà không cần tạo hay quản lý nhiều Access Key cứng.

IAM Role cấp quyền sử dụng tài nguyên thông qua một token tạm thời được sinh ra bởi AWS Security Token Service (STS). Token này sẽ tự động hết hạn, giúp giảm rủi ro bảo mật đi rất nhiều.

Các thuật ngữ liên quan đến Role:

  • Principal: Các danh tính được quyền “đóng vai” (assume) Role này. Principal có thể là dịch vụ AWS, IAM User trong cùng/khác tài khoản, hoặc người dùng bên ngoài qua Facebook/Google.
  • Trust Policy: Chính sách xác định những Principal nào được phép sử dụng IAM Role này.
  • Permission Policy: Chính sách quyền hạn xác định IAM Role này có thể làm gì (tương tự như gán Policy cho User).

Ví dụ Trust Policy cho phép IAM User từ một tài khoản khác Assume Role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/techcoban"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Ví dụ Trust Policy cho phép đăng nhập qua Web Identity (Google):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { 
                "Federated": "accounts.google.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity"
        }
    ]
}

Khi một danh tính hợp lệ Assume Role, AWS STS cấp một token tạm thời (có hiệu lực từ 1 giờ đến 12 giờ) chứa toàn bộ quyền đã định nghĩa trong Permission Policy để danh tính đó có thể truy cập tài nguyên.

Các trường hợp sử dụng IAM Role phổ biến:

  1. Dịch vụ AWS nội bộ: Ví dụ EC2 gọi API S3.
  2. Cross-account access: User từ tài khoản A gọi tài nguyên từ tài khoản B.
  3. Web Identity Federation: Ứng dụng di động dùng Google/Facebook Auth truy cập trực tiếp tài nguyên.
  4. SAML 2.0 Identity Provider: Nhân viên công ty dùng Microsoft ADFS (SSO) để truy cập AWS Console mà không cần có IAM User nội bộ AWS.

5. Resource Policy

Khác với Identity-based policy, Resource Policy là chính sách được gán trực tiếp lên chính tài nguyên AWS (S3, SQS, KMS, SNS…), quy định những ai (Principal) được thực hiện hành động gì lên nó.

Ví dụ, dưới đây là một S3 bucket policy cho phép IAM User techcoban thực hiện quyền đọc và ghi dữ liệu lên bucket important-bucket, đồng thời dùng Explicit Deny chặn tất cả mọi người thao tác xoá dữ liệu (s3:DeleteObject).

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/techcoban"
      },
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::important-bucket/*"
    },
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:DeleteObject",
      "Resource": "arn:aws:s3:::important-bucket/*"
    }
  ]
}

Ưu điểm của Resource Policy so với IAM Policy: IAM Policy thông thường chỉ quản lý được các danh tính cùng nằm trong tài khoản. Ngược lại, Resource Policy cung cấp khả năng chia sẻ tài nguyên đa tài khoản (Cross-account access) cực kỳ dễ dàng. Bạn có thể định nghĩa thẳng Principal là một ARN từ một tài khoản bên ngoài.

Ví dụ S3 bucket policy cấp quyền đọc/ghi cho Root User tài khoản 987654321024 vào bucket của tài khoản hiện tại 123456789012:

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

Hy vọng bài viết này giúp bạn nắm vững kiến trúc nền tảng và cách quản lý bảo mật IAM trên AWS!

Bình luận

Bài viết liên quan