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
Conditiontrong 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