- Published on
EKS OIDC Thumbprint 변경 후 IRSA 403 복구
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서론
EKS에서 IRSA(IAM Roles for Service Accounts)를 쓰다가 어느 날부터 갑자기 애플리케이션이 AWS API 호출에서 403 AccessDenied를 뿜기 시작하는 경우가 있습니다. 특히 “OIDC thumbprint를 변경/재설정했다”거나, “클러스터 OIDC Provider를 다시 만들었다” 같은 이벤트가 있었다면, 원인은 대개 IAM OIDC Provider의 thumbprint/URL 불일치 또는 그로 인한 STS AssumeRoleWithWebIdentity 검증 실패로 수렴합니다.
이 글은 thumbprint 변경 이후 IRSA가 403으로 깨졌을 때, 가장 빠르게 원인을 좁히고 복구하는 실전 절차를 다룹니다. (증상은 403으로 보이지만, 실제로는 STS 단계에서 토큰 검증이 실패하거나, Trust Policy 조건이 어긋나서 거절되는 경우가 많습니다.)
> 참고로 EKS에서 403은 IRSA뿐 아니라 ECR 토큰/권한 이슈로도 자주 발생합니다. 이미지 pull 단계의 403이라면 EKS ImagePullBackOff 403 - ECR 권한·토큰 만료 해결도 함께 확인하세요.
1) 증상 패턴: “IRSA 403”의 대표 로그
IRSA가 깨지면 앱 로그/SDK 예외는 대개 다음 중 하나로 나타납니다.
- AWS SDK 호출 시
AccessDeniedException: User: arn:aws:sts::...:assumed-role/... is not authorized to perform ...NoCredentialProviders/Unable to locate credentials(웹 아이덴티티 토큰 교환 자체가 실패)
- CloudTrail / STS 관점
AssumeRoleWithWebIdentity이벤트가 실패InvalidIdentityToken,AccessDenied,IDPRejectedClaim등
여기서 중요한 포인트는:
- Pod는 정상 실행될 수 있습니다. (Kubernetes 레벨 문제 아님)
- AWS API 호출 시점에만 터집니다.
- thumbprint/Provider 문제가 있으면 STS에서 토큰 검증이 실패하여 결국 403으로 귀결됩니다.
2) IRSA 동작 원리(thumbprint가 왜 중요하나)
IRSA는 다음 흐름입니다.
- Pod에 붙은 ServiceAccount가 projected token(OIDC JWT)을 받음
- AWS SDK는
AWS_WEB_IDENTITY_TOKEN_FILE과AWS_ROLE_ARN을 보고 - STS
AssumeRoleWithWebIdentity호출 - STS는 IAM OIDC Provider 설정을 기반으로
- issuer URL 일치 여부
- 토큰 서명 키(JWKS) 검증
- (필요 시) TLS 체인 검증을 위한 thumbprint 신뢰
- trust policy 조건(
sub,aud) 일치
- 성공하면 임시 자격 증명 발급
즉, thumbprint가 잘못되면 “이 OIDC issuer를 신뢰할 수 없다”로 판정되어 STS 교환이 실패합니다.
3) 10분 진단 체크리스트
아래 순서대로 보면 대부분 빠르게 원인이 드러납니다.
3.1 ServiceAccount annotation 확인
kubectl -n <namespace> get sa <serviceaccount> -o yaml
확인할 것:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/<role-name>- 오타/다른 계정/다른 role 참조 여부
3.2 Pod에 웹 아이덴티티 환경변수/토큰 파일이 있는지
kubectl -n <namespace> exec -it <pod> -- sh -lc 'env | egrep "AWS_ROLE_ARN|AWS_WEB_IDENTITY_TOKEN_FILE"; ls -l $AWS_WEB_IDENTITY_TOKEN_FILE'
AWS_WEB_IDENTITY_TOKEN_FILE이 비어 있거나 파일이 없으면 IRSA 주입이 안 된 것입니다.- 주입은 되는데 403이면 다음 단계로.
3.3 STS 호출 실패 메시지 직접 확인(가능하면)
애플리케이션이 boto3/java sdk 등을 쓴다면, 로그 레벨을 올려 STS 오류 원문을 보세요. InvalidIdentityToken / IDPRejectedClaim이면 OIDC/TrustPolicy 쪽 가능성이 큽니다.
3.4 IAM OIDC Provider가 “클러스터 issuer”와 일치하는지
클러스터 issuer URL 확인:
aws eks describe-cluster --name <cluster> --query "cluster.identity.oidc.issuer" --output text
IAM OIDC Provider 목록에서 해당 URL이 존재하는지 확인:
aws iam list-open-id-connect-providers
각 Provider의 상세를 확인해 URL이 같은지 봅니다.
aws iam get-open-id-connect-provider --open-id-connect-provider-arn <provider-arn>
여기서 Url이 클러스터 issuer와 완전히 같아야 합니다(프로토콜/경로 포함).
4) thumbprint 변경 이후 가장 흔한 원인 4가지
원인 A) IAM OIDC Provider의 thumbprint가 현재 인증서 체인과 불일치
EKS OIDC issuer는 일반적으로 AWS가 관리하는 엔드포인트이며, 중간/루트 체인 변경 등으로 thumbprint가 달라질 수 있습니다. thumbprint를 수동으로 넣거나, Provider를 재생성하면서 잘못된 값을 넣으면 STS가 신뢰를 못 합니다.
원인 B) OIDC Provider를 “새로 만들면서” URL이 달라짐
issuer URL이 조금이라도 다르면(예: 슬래시/경로 포함 여부) 토큰 issuer와 매칭이 깨집니다.
원인 C) Role Trust Policy의 sub/aud 조건이 실제 SA와 불일치
thumbprint를 건드리다 보니 role을 새로 만들고, trust policy 조건을 잘못 넣는 경우가 많습니다.
원인 D) ServiceAccount가 다른 Role을 가리키거나, namespace가 바뀜
system:serviceaccount:<ns>:<sa>가 trust policy와 정확히 일치해야 합니다.
5) 복구 절차(권장): Provider를 “정확히” 재정렬
thumbprint 문제는 애매하게 수동 수정하기보다, 클러스터 issuer에 맞춰 OIDC Provider를 올바르게 재구성하는 편이 안전합니다.
5.1 (권장) eksctl로 OIDC Provider 재연결
가장 실수 적은 방법은 eksctl utils associate-iam-oidc-provider를 쓰는 것입니다.
eksctl utils associate-iam-oidc-provider \
--cluster <cluster> \
--approve
- 이미 존재하면 재사용/검증 흐름을 타며
- 필요 시 올바른 thumbprint로 업데이트/생성합니다(환경에 따라 동작은 다를 수 있으니 결과를 반드시 확인).
5.2 (AWS CLI) OIDC Provider thumbprint 갱신
이미 Provider ARN이 있고 thumbprint만 문제라면 update-open-id-connect-provider-thumbprint로 갱신할 수 있습니다.
aws iam update-open-id-connect-provider-thumbprint \
--open-id-connect-provider-arn <provider-arn> \
--thumbprint-list <thumbprint>
문제는 thumbprint를 어떻게 “정확히” 얻느냐입니다. thumbprint는 보통 OIDC issuer의 TLS 체인에서 특정 CA 인증서(루트/중간)의 SHA1 지문을 사용합니다. 환경에 따라 어떤 인증서를 써야 하는지 달라 혼동이 잦습니다.
실무 팁:
- 가능하면
eksctl을 우선 사용 - 수동으로 할 경우, issuer 도메인의 인증서 체인을 확인하고(중간/루트 포함) AWS 문서/가이드에 맞는 지문을 선택
- thumbprint를 바꾼 뒤에는 반드시 STS AssumeRoleWithWebIdentity가 성공하는지 검증
> thumbprint를 “리프(leaf) 인증서” 지문으로 넣는 실수를 많이 합니다. 체인 변경 시 더 자주 깨질 수 있습니다.
6) Trust Policy 재점검: 403의 절반은 여기서 끝난다
OIDC Provider가 정상이어도, Role의 Trust Policy 조건이 실제 토큰 클레임과 다르면 STS가 거절합니다.
6.1 올바른 Trust Policy 예시
아래는 가장 흔한 형태입니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:aud": "sts.amazonaws.com",
"oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:sub": "system:serviceaccount:<NAMESPACE>:<SERVICEACCOUNT>"
}
}
}
]
}
체크 포인트:
Principal.FederatedARN이 현재 IAM OIDC Provider ARN과 동일한가- Condition key의 prefix(
oidc.eks.<region>.../id/<id>)가 issuer와 정확히 일치하는가 aud가 보통sts.amazonaws.com인가sub가 실제 namespace/sa와 일치하는가
6.2 실제 토큰 클레임 확인(디버그)
Pod 안에서 토큰을 디코드해서 iss, sub, aud를 확인하면 빠릅니다.
kubectl -n <namespace> exec -it <pod> -- sh -lc '
TOKEN=$(cat $AWS_WEB_IDENTITY_TOKEN_FILE);
PAYLOAD=$(echo "$TOKEN" | cut -d. -f2 | tr "-_" "+/" | base64 -d 2>/dev/null);
echo "$PAYLOAD" | sed "s/,/\n/g";
'
iss가 클러스터 issuer와 같은지sub가 trust policy의system:serviceaccount:ns:sa와 같은지aud가sts.amazonaws.com인지
7) 재현/검증: AWS CLI로 AssumeRoleWithWebIdentity 직접 때려보기
애플리케이션을 보기 전에, Pod에서 STS 호출이 되는지 직접 확인하면 원인 분리가 됩니다.
kubectl -n <namespace> exec -it <pod> -- sh -lc '
aws sts assume-role-with-web-identity \
--role-arn "$AWS_ROLE_ARN" \
--role-session-name debug-irsa \
--web-identity-token file://$AWS_WEB_IDENTITY_TOKEN_FILE \
--duration-seconds 900
'
- 여기서 성공하면 IRSA 경로는 정상이며, 이후 403은 권한 정책(permissions policy) 문제일 확률이 큽니다.
- 여기서 실패하면 OIDC Provider/Thumbprint/Trust Policy 문제입니다.
8) “thumbprint 바꾼 뒤” 403이 계속되면 보는 추가 포인트
8.1 Role permissions policy 자체가 부족한 경우
IRSA는 “역할을 assume”하는 것까지 해결합니다. 그 다음은 해당 role에 붙은 정책이 실제 API 권한을 주는지 확인해야 합니다.
- 예: S3 호출 403이면
s3:GetObject/KMS 권한 등 - ECR 403이면 pull 권한, 토큰 갱신, 노드/파드 경로 등
S3의 403 진단은 S3 AccessDenied 403 급발생 - OAC·정책·KMS 30분 진단도 도움이 됩니다.
8.2 STS 엔드포인트/네트워크 이슈(드물지만)
대부분은 정책/신뢰 문제지만, VPC 엔드포인트/프록시/방화벽 환경에서 STS 통신이 비정상인 경우도 있습니다. 이때는 “DNS는 되는데 HTTPS만 실패” 같은 형태로 보일 수 있어, 네트워크 점검 글(EKS Pod DNS는 되는데 HTTPS만 실패할 때 점검)의 체크리스트가 유용합니다.
9) 운영 관점 예방책: thumbprint 변경에 덜 흔들리는 방법
- OIDC Provider를 수동로 자주 건드리지 않기
- 가능하면
eksctl associate-iam-oidc-provider같은 검증된 절차로 관리
- 가능하면
- IRSA 검증용 스모크 테스트를 배포 파이프라인에 포함
- 위의
aws sts assume-role-with-web-identity를 CI/Job로 돌려 조기 감지
- 위의
- CloudTrail에서 STS 실패 이벤트 알람
AssumeRoleWithWebIdentity실패율 급증을 경보로
- Role Trust Policy 템플릿화
- issuer/namespace/sa를 변수로 두고 자동 생성해 오타 방지
10) 결론: 복구의 핵심은 “OIDC Provider-TrustPolicy-토큰 클레임” 정합성
thumbprint 변경 이후 IRSA 403을 복구하는 가장 빠른 길은 다음 3가지를 일치시키는 것입니다.
- 클러스터의 OIDC issuer URL ↔ IAM의 OIDC Provider URL/ARN
- IAM OIDC Provider의 thumbprint가 현재 체인과 호환
- Role Trust Policy의 Condition(aud/sub) ↔ 실제 Pod 토큰 클레임
위 순서로 점검하고, Pod에서 assume-role-with-web-identity를 직접 성공시키면 IRSA 경로는 끝납니다. 그 다음 남는 403은 “권한 정책(permissions)” 문제로 좁혀져 훨씬 빨리 해결할 수 있습니다.