Skip to main content

EKS Authentication & Authorization

Authentication (AuthN) và Authorization (AuthZ) trong EKS hoạt động theo 2 lớp tách biệt: AWS IAM xác thực danh tính, Kubernetes RBAC kiểm soát quyền truy cập vào resource trong cluster.

🔐 1. Tổng quan - Luồng xác thực

Điểm quan trọng:

  • AWS IAM chỉ làm nhiệm vụ xác thực (ai đang gọi?).
  • Kubernetes RBAC mới là nơi kiểm soát quyền (được làm gì?).
  • Mapping giữa IAM identity và K8s user/group được quản lý qua Access Entries (cách mới) hoặc aws-auth ConfigMap (cách cũ).

🗂️ 2. aws-auth ConfigMap (Legacy)

2.1. aws-auth là gì?

aws-auth là một ConfigMap nằm trong namespace kube-system, dùng để map IAM user/role sang Kubernetes username và group.

Đã deprecated

AWS khuyến cáo dùng EKS Access Entries thay thế. aws-auth vẫn hoạt động nhưng dễ gây lỗi vì:

  • Chỉnh sửa sai cú pháp YAML có thể lock out toàn bộ cluster.
  • Không có API riêng, chỉ là ConfigMap thông thường.
  • Không audit trail rõ ràng.

2.2. Cấu trúc aws-auth

apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
# Node group role - bắt buộc để worker node join cluster
- rolearn: arn:aws:iam::123456789012:role/eks-node-group-role
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes

# Dev team role
- rolearn: arn:aws:iam::123456789012:role/dev-team-role
username: dev-user
groups:
- dev-group

mapUsers: |
# Individual IAM user (ít dùng, nên dùng role)
- userarn: arn:aws:iam::123456789012:user/admin-user
username: admin-user
groups:
- system:masters

2.3. Chỉnh sửa aws-auth an toàn

Dùng eksctl thay vì sửa trực tiếp bằng kubectl edit:

# Thêm IAM role
eksctl create iamidentitymapping \
--cluster my-cluster \
--region ap-southeast-1 \
--arn arn:aws:iam::123456789012:role/dev-team-role \
--username dev-user \
--group dev-group

# Xem danh sách mapping
eksctl get iamidentitymapping \
--cluster my-cluster \
--region ap-southeast-1

# Xóa mapping
eksctl delete iamidentitymapping \
--cluster my-cluster \
--region ap-southeast-1 \
--arn arn:aws:iam::123456789012:role/dev-team-role

🔑 3. EKS Access Entries (Cách mới - Khuyên dùng)

3.1. Access Entries là gì?

EKS Access Entries là cách quản lý authentication mapping thông qua AWS API thay vì ConfigMap. Ra đời từ EKS 1.28.

Ưu điểm so với aws-auth:

  • Quản lý qua AWS Console, CLI, SDK, Terraform — có đầy đủ audit trail trong CloudTrail.
  • Không thể vô tình lock out cluster do lỗi YAML.
  • Hỗ trợ IAM Roles, IAM Users, và cả EC2 Instance Profiles.
  • Tích hợp với AWS Identity Center (SSO).

3.2. Access Policy Types

AWS cung cấp sẵn một số policy:

PolicyMô tả
AmazonEKSClusterAdminPolicyFull admin (tương đương system:masters)
AmazonEKSAdminPolicyAdmin nhưng không quản lý cluster-level resource
AmazonEKSEditPolicyĐọc/ghi workload thông thường
AmazonEKSViewPolicyChỉ đọc

3.3. Tạo Access Entry bằng AWS CLI

# Bước 1: Tạo access entry cho IAM Role
aws eks create-access-entry \
--cluster-name my-cluster \
--region ap-southeast-1 \
--principal-arn arn:aws:iam::123456789012:role/dev-team-role \
--type STANDARD \
--kubernetes-groups dev-group

# Bước 2: Gán Access Policy
aws eks associate-access-policy \
--cluster-name my-cluster \
--region ap-southeast-1 \
--principal-arn arn:aws:iam::123456789012:role/dev-team-role \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy \
--access-scope type=namespace,namespaces=dev-namespace
Scope namespace

--access-scope type=namespace,namespaces=dev-namespace giới hạn quyền chỉ trong namespace dev-namespace. Dùng type=cluster để cấp quyền toàn cluster.

3.4. Tạo Access Entry bằng Terraform

resource "aws_eks_access_entry" "dev_team" {
cluster_name = aws_eks_cluster.main.name
principal_arn = "arn:aws:iam::123456789012:role/dev-team-role"
type = "STANDARD"
}

resource "aws_eks_access_policy_association" "dev_team_view" {
cluster_name = aws_eks_cluster.main.name
principal_arn = aws_eks_access_entry.dev_team.principal_arn
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"

access_scope {
type = "namespace"
namespaces = ["dev-namespace"]
}
}

3.5. Enable Access Entry mode cho cluster

Khi tạo cluster mới hoặc migrate:

aws eks update-cluster-config \
--name my-cluster \
--region ap-southeast-1 \
--access-config authenticationMode=API_AND_CONFIG_MAP

Các mode:

  • CONFIG_MAP — Chỉ dùng aws-auth (legacy, default cho cluster cũ).
  • API_AND_CONFIG_MAP — Hỗ trợ cả hai (dùng khi đang migrate).
  • API — Chỉ dùng Access Entries (khuyến nghị cho cluster mới).

🏷️ 4. Kubernetes RBAC

Sau khi IAM identity đã được map sang K8s username/group, RBAC kiểm soát quyền thực sự.

4.1. Các khái niệm chính

  • Role — Cấp quyền trong phạm vi 1 namespace.
  • ClusterRole — Cấp quyền toàn cluster.
  • RoleBinding — Gắn Role vào user/group trong 1 namespace.
  • ClusterRoleBinding — Gắn ClusterRole vào user/group ở phạm vi cluster.

4.2. Ví dụ: Role + RoleBinding cho dev team

# Role: chỉ cho phép xem Pods và Deployments trong namespace dev
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dev-readonly
namespace: dev-namespace
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
---
# RoleBinding: gắn Role vào group "dev-group"
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-readonly-binding
namespace: dev-namespace
subjects:
- kind: Group
name: dev-group # Phải khớp với group trong aws-auth hoặc Access Entry
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-readonly
apiGroup: rbac.authorization.k8s.io

4.3. Kiểm tra quyền

# Kiểm tra quyền của chính mình
kubectl auth can-i get pods -n dev-namespace

# Kiểm tra quyền của user khác (admin)
kubectl auth can-i get pods -n dev-namespace --as=dev-user
kubectl auth can-i create deployments -n dev-namespace --as-group=dev-group --as=fake-user

# Liệt kê tất cả quyền của service account
kubectl auth can-i --list --as=system:serviceaccount:default:my-sa

☁️ 5. IRSA - IAM Roles for Service Accounts

5.1. Vấn đề: Pod cần truy cập AWS

Khi Pod cần gọi AWS API (S3, DynamoDB, SQS...), không được hardcode credentials vào Pod. IRSA là giải pháp chính thống.

5.2. Cơ chế hoạt động

Luồng hoạt động:

  1. EKS cluster có OIDC Provider.
  2. Service Account được annotate với IAM Role ARN.
  3. Pod dùng Service Account đó nhận OIDC token tự động.
  4. AWS SDK trong Pod dùng token để call STS AssumeRoleWithWebIdentity.
  5. STS trả về temporary credentials.

5.3. Thiết lập IRSA

Bước 1: Tạo OIDC Provider cho cluster

eksctl utils associate-iam-oidc-provider \
--cluster my-cluster \
--region ap-southeast-1 \
--approve

Bước 2: Tạo IAM Role với Trust Policy

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.ap-southeast-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.ap-southeast-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:my-service-account",
"oidc.eks.ap-southeast-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
}
}
}
]
}

Bước 3: Annotate Service Account

apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-s3-role

Cách nhanh hơn với eksctl:

eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace default \
--name my-service-account \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approve

5.4. Sử dụng trong Pod

apiVersion: apps/v1
kind: Deployment
metadata:
name: s3-reader
spec:
template:
spec:
serviceAccountName: my-service-account # Dùng SA đã annotate
containers:
- name: app
image: amazon/aws-cli:latest
command: ["aws", "s3", "ls", "s3://my-bucket"]
# AWS SDK tự động lấy credentials từ OIDC token
# Không cần env AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY

🆔 6. EKS Pod Identity (Cách mới hơn IRSA)

6.1. EKS Pod Identity là gì?

EKS Pod Identity là cơ chế thế hệ mới (GA từ EKS 1.28) thay thế IRSA, đơn giản hơn và không phụ thuộc vào OIDC Provider của cluster.

So sánh IRSA vs Pod Identity:

Tiêu chíIRSAEKS Pod Identity
OIDC ProviderCần tạo per clusterKhông cần
Trust PolicyGhi cụ thể cluster OIDC URLDùng pods.eks.amazonaws.com chung
Reusable IAM RolePhải tạo role mới cho từng clusterDùng lại role cho nhiều cluster
Cấu hìnhAnnotate Service AccountPod Identity Association
Cần addonKhôngPod Identity Agent addon

6.2. Thiết lập Pod Identity

Bước 1: Cài Pod Identity Agent addon

aws eks create-addon \
--cluster-name my-cluster \
--addon-name eks-pod-identity-agent \
--region ap-southeast-1

Bước 2: Tạo IAM Role với Trust Policy đơn giản hơn

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}

Bước 3: Tạo Pod Identity Association

aws eks create-pod-identity-association \
--cluster-name my-cluster \
--region ap-southeast-1 \
--namespace default \
--service-account my-service-account \
--role-arn arn:aws:iam::123456789012:role/my-app-role

Hoặc bằng Terraform:

resource "aws_eks_pod_identity_association" "app" {
cluster_name = aws_eks_cluster.main.name
namespace = "default"
service_account = "my-service-account"
role_arn = aws_iam_role.app_role.arn
}
Quan Trọng

AWS khuyến nghị dùng EKS Pod Identity cho cluster mới. Trust Policy không còn gắn với OIDC URL của cluster cụ thể, nên role có thể tái sử dụng dễ dàng.


📊 7. Tóm tắt - So sánh các cơ chế

7.1. Human/System Access vào cluster

Cơ chếTrường hợp dùngKhuyến nghị
aws-auth ConfigMapCluster cũ, trước EKS 1.28⚠️ Legacy, hạn chế dùng
EKS Access EntriesCluster EKS 1.28+✅ Khuyên dùng

7.2. Pod Access vào AWS Services

Cơ chếTrường hợp dùngKhuyến nghị
IRSACluster cũ, tương thích rộng✅ Vẫn hoạt động tốt
EKS Pod IdentityCluster EKS 1.28+✅ Khuyên dùng cho cluster mới

7.3. Checklist bảo mật

  • Không dùng system:masters cho developer — dùng Access Policy có scope namespace.
  • Không hardcode AWS credentials trong Pod — dùng IRSA hoặc Pod Identity.
  • Áp dụng Least Privilege cho cả IAM Policy và RBAC Role.
  • Bật CloudTrail để audit API call lên EKS.
  • Enable Access Logging cho EKS API Server endpoint.
  • Dùng Private Endpoint khi có thể, hạn chế Public Endpoint.