본문 바로가기

DevOps

[AEWS 4기] EKS 스터디 4주차 [ EKS 인증/인가 ] - 4개의 인증 흐름

EKS 인증/인가 4종 비교 — 누가, 무엇에 접근하는가

EKS를 운영하다 보면 "권한"이라는 단어가 두 가지 맥락에서 등장한다.

하나는 클라이언트 즉 , 사람(또는 CI/CD)이 kubectl을 칠 수 있는 권한이고,
다른 하나는 Pod가 AWS 리소스(S3, DynamoDB 등)를 호출할 수 있는 권한이다.

이 두 가지는 완전히 다른 레이어에서 동작하지만, 둘 다 IAM을 기반으로 하기 때문에 처음 접하면 헷갈리기 쉽다.

[외부 → Kubernetes API 접근 제어]
├── aws-auth ConfigMap   ← 레거시
└── EKS Access Entry     ← 신규 (2024~)

[Pod → AWS API 접근 제어]
├── IRSA                 ← OIDC 기반
└── Pod Identity         ← EKS 네이티브 (2023~)

이 글에서는 위 4가지 방식을 왜 필요한지, 어떻게 동작하는지, 언제 어떤 걸 써야 하는지 기준으로 비교 정리한다.


들어가기 전에 — 두 가지 질문으로 구분하기

질문 해당 방식
"이 IAM 사용자/역할이 kubectl을 칠 수 있는가?" aws-auth ConfigMap, EKS Access Entry
"이 Pod가 S3 버킷을 읽을 수 있는가?" IRSA, Pod Identity

첫 번째는 Kubernetes API Server에 대한 인증/인가이고,
두 번째는 AWS API에 대한 IAM 권한 위임이다.

서로 독립적으로 동작하므로, kubectl 권한이 있다고 해서 Pod에 AWS 권한이 생기는 것은 아니고, 그 반대도 마찬가지다.


관리자가 kubectl get node 실행 시 과정

"이 IAM 사용자/역할이 kubectl을 칠 수 있는가?"

Kubernetes API Server에 대한 인증/인가 부터 살펴보자

위 그림을 보면 , AUTHZ AUTHN에 대해서 용어정리가 먼저 필요할거 같다.

용어 정리 — AuthN vs AuthZ

인증/인가를 줄여서 AuthN, AuthZ라고 쓰는데, 이 둘은 완전히 다른 단계다.

  AuthN (Authentication, 인증) AuthZ (Authorization, 인가)
질문 "너 누구야?" "너 이거 해도 돼?"
목적 신원 확인 권한 확인
시점 먼저 수행 인증 이후 수행
EKS 예시 IAM 자격증명으로 EKS API 서버에 접근 시도 RBAC으로 해당 사용자가 Pod를 생성할 수 있는지 확인
실패 시 401 Unauthorized 403 Forbidden

쉽게 비유하면:

  • AuthN = 건물 출입증을 보여주는 것 (신분 확인)
  • AuthZ = 출입증은 있지만 서버실에 들어갈 수 있는지 확인하는 것 (권한 확인)

EKS에서의 흐름을 보면:

kubectl get pods
    │
    ▼
1. AuthN (인증) — "이 요청을 보낸 사람이 누구인가?"
   └── IAM 자격증명 → EKS가 IAM으로 신원 확인
    │
    ▼
2. AuthZ (인가) — "이 사람이 pods를 조회할 권한이 있는가?"
   └── Kubernetes RBAC (Role, ClusterRole, RoleBinding 등)
    │
    ▼
3. 응답 반환

즉, aws-auth ConfigMap이나 EKS Access Entry는 AuthN + AuthZ 매핑을 담당하고,
IRSA나 Pod Identity는 Pod에 대한 AWS IAM AuthN/AuthZ를 담당한다.


EKS Access Entry — AuthZ 모드 비교

AuthN은 동일, AuthZ가 다르다

EKS에서 인증(AuthN)은 어떤 모드를 쓰든 IAM 기반으로 동일하다.
차이는 인가(AuthZ)를 누가 처리하느냐에 있다.

EKS 클러스터 생성 시 authentication-mode를 설정할 수 있으며, 세 가지 모드가 존재한다.


세 가지 인증 모드

인증 모드 AuthN (인증) AuthZ (인가) 설명
CONFIG_MAP IAM K8s RBAC만 레거시 방식. aws-auth ConfigMap으로 IAM → K8s 사용자 매핑 후, RBAC으로 권한 제어
API IAM AWS Access Policy만 EKS API로 접근 관리. AWS에서 제공하는 사전 정의 정책으로 AuthZ 처리
API_AND_CONFIG_MAP IAM AWS Access Policy + K8s RBAC 두 방식을 동시에 사용. 마이그레이션 과도기나 세밀한 제어가 필요할 때

각 모드의 AuthZ 흐름

CONFIG_MAP (레거시)

kubectl 요청
    │
    ▼
AuthN: IAM 자격증명 확인
    │
    ▼
aws-auth ConfigMap에서 IAM → K8s 사용자/그룹 매핑
    │
    ▼
AuthZ: K8s RBAC (Role, ClusterRole, RoleBinding)으로 권한 확인

API (EKS Access Entry)

kubectl 요청
    │
    ▼
AuthN: IAM 자격증명 확인
    │
    ▼
AuthZ: AWS Access Policy로 권한 확인 (K8s RBAC 사용 안 함)
    │
    ▼
사전 정의된 정책 적용:
  - AmazonEKSClusterAdminPolicy
  - AmazonEKSAdminPolicy
  - AmazonEKSEditPolicy
  - AmazonEKSViewPolicy

API_AND_CONFIG_MAP (혼합)

kubectl 요청
    │
    ▼
AuthN: IAM 자격증명 확인
    │
    ▼
AuthZ: AWS Access Policy 확인 + K8s RBAC 확인 (둘 다 적용)

언제 어떤 모드를 쓰는가

상황 권장 모드
기존 aws-auth 운영 중, 변경 계획 없음 CONFIG_MAP
신규 클러스터, IaC로 관리하고 싶음 API
기존 → 신규 마이그레이션 중 API_AND_CONFIG_MAP
네임스페이스별 세밀한 권한 제어 필요 API_AND_CONFIG_MAP (AWS 정책으로 큰 틀 + RBAC으로 세부)

주의할 점

  • API 모드의 AWS Access Policy는 사전 정의된 정책만 사용 가능하다. 커스텀 정책을 만들 수 없으므로, 세밀한 제어가 필요하면 API_AND_CONFIG_MAP을 써야 한다.
  • CONFIG_MAPAPI로 바로 전환은 불가하다. 반드시 API_AND_CONFIG_MAP을 거쳐야 한다.
  • API_AND_CONFIG_MAP에서 CONFIG_MAP으로 되돌리는 것도 불가하다. 한번 API를 켜면 되돌릴 수 없다.
CONFIG_MAP → API_AND_CONFIG_MAP → API
     (단방향, 되돌릴 수 없음)

차이점 ( 방안 2 aws-auth ConfigMap 은 deprecated 임. )

  • 정책 중복 시 EKS API 우선되며 ConfigMap은 무시됨!!!
  • 해당 IAM User/Role 확인이 되면 k8s aws-auth configmap에서 mapping 정보를 확인하게 됩니다. ← Authorization Mapping
  • aws-auth 컨피그맵에 'IAM 사용자, 역할 arn, K8S 오브젝트' 로 권한 확인 후 k8s 인가(K8S RBAC) 허가가 되면 최종적으로 동작 실행을 합니다.
  • 참고로 EKS를 생성한 IAM principal은 aws-auth 와 상관없이 kubernetes-admin Username으로 system:masters 그룹에 권한을 가짐 ---> 이제 CONFIGMAP에 없어도 해당 권한을 EKS API로 부여받는것으로 보임
kubectl get cm -n kube-system aws-auth -o yaml

apiVersion: v1
data:
  mapRoles: |
    - rolearn: arn:aws:iam::064711168361:role/myeks-ng-1
      groups:
      - system:bootstrappers
      - system:nodes
      username: system:node:{{EC2PrivateDNSName}}
kind: ConfigMap
metadata:
  creationTimestamp: "2026-04-05T04:36:22Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "1023"
  uid: 47fd2aaf-5fee-42ef-b2ac-fda36cb7cae8


EKS API 방식의 인증/인가 흐름

EKS Access Entry(API 모드)를 사용하면, 기존 aws-auth ConfigMap과 달리 AWS 측에서 IAM 주체를 K8s Subject로 매핑하고, Webhook 기반으로 인가(AuthZ)를 처리한다.

전체 흐름

kubectl get pods
    │
    ▼
① AuthN (인증)
   └── IAM 자격증명 → STS → EKS가 IAM 주체 확인
    │
    ▼
② IAM 주체 → K8s Subject 매핑
   └── EKS Access Entry에 등록된 매핑 정보 참조
   └── 예: arn:aws:iam::123456:role/dev-role → k8s user "user"
    │
    ▼
③ AuthZ (인가) — Webhook 모드
   └── K8s API Server가 Webhook으로 AWS에 인가 요청
   └── AWS Access Policy 기반으로 허용/거부 판단
   └── SubjectAccessReview 리소스를 통해 결과 반환
    │
    ▼
④ 응답 반환

SubjectAccessReview란?

SubjectAccessReview는 Kubernetes API 리소스로, "이 사용자가 이 작업을 할 수 있는가?"를 질의하는 API다.

직접 호출할 수도 있고, API Server 내부에서 인가 판단 시 자동으로 사용된다.

구조

ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
cat > sar-request.yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SubjectAccessReview
spec:
  user: "arn:aws:iam::${ACCOUNT_ID}:user/testuser" # 확인하고 싶은 IAM ARN 또는 K8s User
  groups:
    - system:masters
  resourceAttributes:
    namespace: "kube-system"
    verb: "get"
    resource: "pods"
EOF

응답

status:
  allowed: true                       # 허용 여부
  reason: "RBAC: allowed by ..."      # 판단 근거

직접 확인해보기

특정 사용자가 특정 작업을 할 수 있는지 kubectl auth can-i로 확인할 수 있다. 내부적으로 SubjectAccessReview를 호출한다.

# 내가 default 네임스페이스에서 pods를 조회할 수 있는가?
kubectl auth can-i get pods -n default

 

 


EKS API 모드에서 Webhook 인가가 동작하는 방식

기존 K8s RBAC은 API Server 내부에서 Role/ClusterRole을 직접 조회해서 판단한다.
반면 EKS API 모드의 Webhook 인가는 외부 서비스(AWS)에 판단을 위임한다.

[RBAC 인가 — 기존 방식]
API Server → 내부 RBAC 엔진 → Role/RoleBinding 조회 → 허용/거부

[Webhook 인가 — EKS API 방식]
API Server → Webhook 요청 (SubjectAccessReview) → AWS 인가 서비스
                                                      │
                                                      ▼
                                              AWS Access Policy 확인
                                                      │
                                                      ▼
                                              허용/거부 응답 반환

K8s API Server의 인가 모드 설정

EKS API 모드를 켜면 API Server의 --authorization-modeWebhook이 추가된다:

--authorization-mode=Node,RBAC,Webhook
  • Node: kubelet 요청 인가
  • RBAC: 기존 Role/ClusterRole 기반 인가
  • Webhook: 외부 서비스(AWS)에 인가 위임

API Server는 이 순서대로 체인을 타면서, 하나라도 허용하면 통과시킨다.


사전 정의된 AWS Access Policy 목록

정책 이름 대응하는 K8s 권한 수준
AmazonEKSClusterAdminPolicy cluster-admin (전체 권한)
AmazonEKSAdminPolicy admin (네임스페이스 수준 관리)
AmazonEKSAdminViewPolicy 모든 리소스 읽기 전용
AmazonEKSEditPolicy edit (리소스 생성/수정/삭제)
AmazonEKSViewPolicy view (읽기 전용)

정리

항목 CONFIG_MAP (RBAC) API (Webhook)
AuthZ 판단 위치 K8s API Server 내부 AWS 외부 서비스
권한 정의 Role, ClusterRole, RoleBinding AWS Access Policy (사전 정의)
커스텀 권한 자유롭게 생성 가능 불가 (5개 사전 정의 정책만)
SubjectAccessReview 내부에서 RBAC 엔진이 처리 Webhook으로 AWS에 위임
세밀한 제어 네임스페이스/리소스/verb 단위 정책 단위 (큰 틀만)
  • 주의할 점: "하이브리드" 동작 - 만약 AWS 관리형 정책을 쓰지 않고, 직접 만든 커스텀 RBAC을 쓰고 싶다면 어떻게 될까요?
    1. AWS 웹훅이 먼저 검토하고 "모르는 유저네? 결정 보류(No Opinion)"라고 응답합니다.
    2. 그러면 API 서버는 다음 단계인 내부 RBAC 엔진으로 넘어가서, 사용자가 직접 작성해둔 RoleBinding이 있는지 찾아봅니다.
  • 결국 EKS는 AWS가 관리하는 영역(Managed)과 사용자가 관리하는 영역(Custom RBAC)을 동시에 지원하기 위해 이 웹훅 구조를 사용함.