Obiz Solutions

AWS IAM là gì?

IAM (Identity and Access Management) là dịch vụ AWS quản lý ai được làm gì trong một tài khoản AWS. Không có thao tác nào trên AWS — tạo S3 bucket, invalidate cache CloudFront, khởi chạy server — được thực hiện mà không qua kiểm tra IAM trước. Pipeline deploy của site này (xem Obiz Solutions — chính website này) dựa vào IAM để GitHub Actions có thể đẩy file lên S3 mà không cần giữ mật khẩu nào.

Các khái niệm cốt lõi

  • User — một danh tính cho người dùng hoặc ứng dụng, thường có credential tồn tại lâu dài (mật khẩu, access key).
  • Role — một danh tính không có credential riêng. Một thứ khác (người dùng, dịch vụ, hệ thống bên ngoài) assume nó tạm thời để nhận về credential ngắn hạn. Đây là cách GitHub Actions dùng.
  • Policy — một document JSON quy định hành động nào được phép hoặc bị từ chối trên tài nguyên nào. Được gắn vào user, group, hoặc role.
  • Group — tập hợp user dùng chung một bộ policy.

Cấu trúc một policy

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

Mỗi statement trả lời ba câu hỏi: Effect (Allow/Deny), Action (gọi API nào), Resource (ARN cụ thể nào). Một policy ghi “cho phép s3:* trên *” vẫn chạy được, nhưng cấp quyền rộng hơn nhiều so với một script deploy thực sự cần — chỉ cấp đúng những gì được dùng gọi là nguyên tắc đặc quyền tối thiểu (least privilege).

Role + OIDC: không lưu AWS key

Cách cũ để GitHub Actions gọi được AWS là tạo access key dài hạn cho một IAM user rồi dán vào GitHub secret — một credential không tự hết hạn, và là rủi ro thật sự nếu repo (hoặc secret đó) từng bị lộ.

Cách site này dùng thay thế: đăng ký một OIDC identity provider cho token.actions.githubusercontent.com trong tài khoản AWS, và trust policy của một IAM role cho phép provider đó cấp quyền sts:AssumeRoleWithWebIdentity — nhưng chỉ khi request đến từ đúng repo này:

{
  "Effect": "Allow",
  "Principal": {
    "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
  },
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringLike": {
      "token.actions.githubusercontent.com:sub": "repo:GITHUB_ORG/REPO:ref:refs/heads/main"
    }
  }
}

Mỗi lần workflow chạy sẽ nhận một credential mới, ngắn hạn, và không có gì được lưu lại. Permissions policy của role sau đó giới hạn credential đó thực sự làm được gì — với repo này là s3:PutObject/DeleteObject/ListBucket trên một bucket và cloudfront:CreateInvalidation trên một distribution (xem đầy đủ ở README của project).

Vài nguyên tắc nên nhớ

  • Ưu tiên role thay vì access key dài hạn của user, đặc biệt cho bất kỳ thứ gì tự động (CI/CD, Lambda, EC2).
  • Giới hạn policy vào ARN tài nguyên cụ thể thay vì * bất cứ khi nào có thể.
  • Khối Condition trong trust policy mới thật sự giới hạn ai được assume role — nếu không có nó, bất kỳ danh tính nào được provider tin tưởng cũng có thể.

Tài liệu tham khảo

Tài liệu chính thức: docs.aws.amazon.com/IAM