AWS IAM thực chiến: Tại sao nhúng Access Key là tối kỵ, và IAM Role + OIDC giải quyết thế nào?

· ~5 phút đọc

1. IAM User vs. IAM Role: Căn cước công dân vs. Visa nhập cảnh

Để dễ phân biệt IAM User và IAM Role, cứ hình dung:

  • IAM User = Căn cước công dân (gắn với một danh tính cố định):
    • Biết rõ mặt đặt tên (Hudson, Alice).
    • Có thể có mật khẩu hoặc Access Key / Secret Key dài hạn, không tự hết hạn.
    • Có thể đại diện cho người hoặc ứng dụng. Nhưng với người thật đăng nhập làm việc, hiện nên dùng SSO thay vì tạo IAM User riêng.
  • IAM Role = Bộ đồng phục ca trực / Visa tạm thời (không gắn cố định với ai):
    • Đại diện cho một vai trò / chức danh.
    • Ai chứng minh được mình đủ điều kiện thì được “khoác áo vào” để làm việc trong một phiên có thời hạn.
    • Hết ca thì thẻ hết hiệu lực, không có chìa khóa dài hạn mang về nhà.
    • Dùng cho máy chủ (EC2, ECS), tác vụ tự động (Lambda), CI/CD (Bitbucket, GitHub Actions), và cả người dùng qua SSO hoặc assume role.

2. Cơ chế IAM Role: “Bộ lọc visa Mỹ”

Một IAM Role có hai phần cần phân biệt:

1
2
3
4
5
6
7
8
9
10
11
12
[ Đối tượng xin quyền: Bitbucket ]
|
v
1. TRUST POLICY (Vòng xét duyệt visa)
"Ai có quyền mượn chiếc thẻ này?"
Không đủ điều kiện? -> Chặn từ cửa khẩu.
|
| Hợp lệ, được cấp phiên làm việc
v
2. PERMISSIONS POLICY (Quyền hạn visa)
"Được làm những trò gì trên AWS?"
Có thẻ rồi vẫn chỉ được làm đúng quyền.
  • Vòng 1: Trust Policy (assumed_by khi khai báo Role bằng AWS CDK Python): Kiểm tra ai được assume role và với điều kiện nào. Kẻ lạ gõ cửa thì chặn ngay từ vòng gửi xe, chưa được cấp credentials của role.
  • Vòng 2: Permissions Policy: Khi đã được mượn thẻ, bạn chỉ được làm đúng việc cho phép. Ví dụ: chỉ được đẩy ảnh Docker lên ECR, không được xóa Database. Quyền thực tế còn chịu giới hạn của các policy khác nếu có, chứ không phải cứ role cho phép là làm được tất cả.

3. Tại sao nhúng Access Key & Secret Key vào code là bad practice?

Nhúng key cố định vào code hay lưu trong cấu hình CI/CD vẫn chạy được (works). Nhưng hardcode vào code là tối kỵ; lưu trong CI/CD secrets đỡ hơn, vẫn còn bài toán giữ và xoay vòng key dài hạn.

1. Rủi ro “cháy túi” sau một đêm (Leaked Credentials)

Lỡ tay git push nhầm file cấu hình lên GitHub hoặc vô tình in key ra log CI/CD. Bot của hacker quét tự động và có thể tóm key rất nhanh. Nếu key có quyền đủ rộng, chúng có thể bật hàng loạt máy chủ ảo đào tiền mã hóa -> Bạn có thể nợ AWS hàng chục nghìn USD chỉ sau một đêm.

2. Chìa khóa “bất tử” (Không tự hết hạn)

Key cố định sống cho đến khi bị vô hiệu hóa hoặc xóa. Không có cơ chế rotate riêng thì nó cứ nằm đó. Nhân viên cũ nghỉ việc vẫn có thể giữ key này.

3. Gánh nặng audit bảo mật (Compliance)

Dùng key dài hạn thì phải quản lý ai giữ key, key có quyền gì, rotate và thu hồi thế nào. SOC 2 hay ISO 27001 không cấm tuyệt đối mọi Access Key tĩnh, nhưng key bị chia sẻ, không kiểm soát hoặc không thu hồi đúng lúc là vấn đề khi audit.

4. IAM Role + OIDC (OpenID Connect)

Thay vì giữ chìa khóa dài hạn, Bitbucket và AWS chơi trò “soi con dấu để phát chìa khóa tạm”:

  1. Tin tưởng trước: Bạn đăng ký OIDC provider của Bitbucket với AWS, gồm issuer URL và audience. Trust Policy của role giới hạn repo nào được mượn thẻ, có thể giới hạn thêm deployment environment. AWS lấy public key từ provider để kiểm tra chữ ký, không phải bạn dán một public key cố định vào role.
  2. Đóng dấu số: Khi step CI/CD đã bật OIDC chạy, Bitbucket cấp token có chữ ký, ghi rõ danh tính của step, repo và environment nếu có.
  3. Cấp chìa khóa tạm: Pipeline gửi token tới AWS STS qua AssumeRoleWithWebIdentity. AWS kiểm tra chữ ký, issuer, audience, thời hạn token và điều kiện trong Trust Policy -> Cấp bộ credentials tạm gồm Access Key ID, Secret Access Key và Session Token.
  4. Hết hạn: Credentials chỉ dùng được trong thời hạn đã cấp. Với luồng này, có thể yêu cầu từ 15 phút đến thời lượng tối đa role cho phép, mặc định là 1 giờ. Hết hạn thì credentials mất hiệu lực, không phải tự biến mất khỏi file hay log.

Pipeline không cần lưu AWS key dài hạn. Key tạm vẫn cần giữ kín trong lúc còn hiệu lực, nhưng lộ rồi thì không dùng mãi được như key cố định.

5. Nhớ mấy điều này là đủ

  • Người thật đăng nhập: Dùng IAM Identity Center (SSO), bật MFA.
  • Server / Bot / CI/CD chạy: Ưu tiên IAM Role. EC2 dùng Instance Profile, ECS dùng Task Role, Lambda dùng Execution Role; CI/CD bên ngoài AWS có thể dùng OIDC.
  • Không hardcode key dài hạn vào code. Nếu CI/CD hỗ trợ OIDC thì dùng nó, đừng tạo key cố định rồi dán vào cấu hình cho nhanh.
  • AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY trong biến môi trường không tự nó là sai: credentials tạm cũng có thể được truyền theo cách này, kèm AWS_SESSION_TOKEN. Vấn đề là nguồn credentials, thời hạn và cách giữ kín chúng.
Home