AccessDenied 해결 (IAM 권한 오류를 원인별로 좁히기)
"is not authorized to perform" 와 AccessDenied 오류를 만났을 때 오류 메시지에서 거부한 정책 종류를 읽는 법, 신원 정책, 리소스 정책, SCP, RCP, 권한 경계, 세션 정책, KMS 키 정책 순으로 원인을 좁히는 절차와 확인 명령을 증상, 원인, 해결 순서로 정리합니다.
증상
애플리케이션 로그나 CLI 에 이런 오류가 나옵니다.
An error occurred (AccessDeniedException) when calling the GetSecretValue operation:
User: arn:aws:sts::111122223333:assumed-role/app-prod/i-0abc123 is not authorized to perform:
secretsmanager:GetSecretValue on resource: arn:aws:secretsmanager:ap-northeast-2:111122223333:secret:db-prod-AbCdEf
with an explicit deny in a service control policy오류 문장에는 단서가 네 가지 들어 있습니다.
| 단서 | 위 예에서 | 뜻 |
|---|---|---|
| 누가 | assumed-role/app-prod/i-0abc123 | 실제로 요청한 주체. 생각한 역할이 맞는지 먼저 확인 |
| 무엇을 | secretsmanager:GetSecretValue | 필요한 작업 이름 그대로 |
| 어디에 | 비밀의 ARN | 리소스 ARN, 리전과 계정 |
| 왜 | with an explicit deny in a service control policy | 거부한 정책 종류 |
AWS 는 많은 서비스에서 오류 메시지에 어떤 종류의 정책이 거부했는지(신원 기반, 리소스 기반, SCP, RCP, 권한 경계, 세션 정책)와 명시적 거부인지, 허용이 없어서인지를 함께 알려 줍니다. 이 꼬리 문장부터 읽으면 조사 범위가 절반 이하로 줄어듭니다.
원인
IAM 은 요청마다 모든 정책을 모아 평가합니다. 평가 흐름은 IAM 문서의 그림에 있습니다. 요약하면 이렇습니다.
- 어떤 정책이든 명시적 Deny 가 있으면 거부입니다.
- 조직의 SCP(주체 상한)와 RCP(리소스 상한)가 허용하지 않으면 거부입니다.
- 같은 계정이면 신원 기반 정책 또는 리소스 기반 정책 중 하나가 허용하면 됩니다. 다른 계정이면 둘 다 허용해야 합니다.
- 권한 경계, 세션 정책이 있으면 그 범위 안이어야 합니다.
- KMS 로 암호화된 리소스라면 키 정책도 허용해야 합니다.
| 오류 꼬리 문장 | 흔한 원인 |
|---|---|
because no identity-based policy allows | 역할에 권한이 없음, 작업 이름이나 리소스 ARN 오타 |
with an explicit deny in an identity-based policy | 역할의 다른 정책에 Deny, 조건 키 불일치 |
because no resource-based policy allows | 교차 계정인데 버킷 정책, 키 정책이 상대 계정을 허용하지 않음 |
with an explicit deny in a service control policy | 리전 제한 SCP, 서비스 차단 SCP |
with an explicit deny in a resource control policy | 조직 밖 접근을 막는 RCP |
because no permissions boundary allows | 권한 경계가 그 작업을 포함하지 않음 |
because no session policy allows | AssumeRole 때 넘긴 세션 정책이 좁음 |
KMS AccessDeniedException (원래 서비스 호출에서) | 키 정책이 호출자나 서비스를 허용하지 않음 |
해결
1 단계: 정말 그 주체인지 확인
aws sts get-caller-identity로컬에서 되는데 서버에서 안 되면 대개 다른 자격 증명을 쓰고 있습니다. 환경 변수(AWS_ACCESS_KEY_ID), AWS_PROFILE, 인스턴스 프로필, 컨테이너 작업 역할, EKS Pod Identity 중 무엇이 먼저 잡히는지 SDK 의 자격 증명 체인 순서를 확인합니다.
2 단계: 정책 시뮬레이터로 신원 정책 확인
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::111122223333:role/app-prod \
--action-names secretsmanager:GetSecretValue \
--resource-arns arn:aws:secretsmanager:ap-northeast-2:111122223333:secret:db-prod-AbCdEf결과의 EvalDecision 이 implicitDeny 면 허용문이 없는 것이고, explicitDeny 면 어떤 문장이 막는지 MatchedStatements 에 나옵니다. 시뮬레이터는 SCP 와 리소스 정책을 일부만 반영하므로 결과가 허용이어도 3 단계를 계속합니다.
3 단계: 정책 종류별 확인
- SCP, RCP: 관리 계정이나 위임 관리자에서 계정에 붙은 정책을 봅니다. 리전 제한 SCP 는 IAM, CloudFront, Route 53 같은 전역 서비스를 예외로 두었는지 확인합니다.
- 리소스 정책: S3 버킷 정책, KMS 키 정책, Secrets Manager 리소스 정책, SQS 큐 정책에
Deny와aws:SourceVpce,aws:PrincipalOrgID같은 조건이 있는지 봅니다. - 조건 키:
aws:RequestedRegion,aws:MultiFactorAuthPresent, 태그 조건(aws:ResourceTag/env)이 요청과 맞지 않으면 허용문이 있어도 적용되지 않습니다. - KMS: 암호화된 S3 객체, 비밀, EBS 스냅숏은 원래 작업 외에
kms:Decrypt,kms:GenerateDataKey가 필요합니다.
4 단계: CloudTrail 에서 실패 이벤트 찾기
aws cloudtrail lookup-events --region ap-northeast-2 \
--lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue \
--max-results 10 --query 'Events[].CloudTrailEvent' --output text | grep -i AccessDenied이벤트의 errorCode, errorMessage, userIdentity 로 실제 요청한 주체와 거부 사유를 다시 확인합니다. 교차 계정 접근은 리소스가 있는 계정의 CloudTrail 에도 기록됩니다.
5 단계: 최소 권한으로 고치기
권한이 없어서라면 * 를 주지 말고, 실패한 작업과 리소스 ARN 만 정확히 더합니다. IAM Access Analyzer 의 정책 생성 기능은 CloudTrail 활동을 바탕으로 실제로 쓴 작업만 담은 정책 초안을 만들어 줍니다. re:Invent 2025 에 발표된 오픈 소스 MCP 서버 IAM Policy Autopilot 은 코드를 분석해 필요한 정책 초안을 만들어 줍니다.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-northeast-2:111122223333:secret:db-prod-*"
}]
}자주 보는 함정
- ARN 의 리전, 계정 오타: 서울 리소스인데 정책에
us-east-1이 들어 있습니다. - S3 버킷 ARN 과 객체 ARN 혼동:
ListBucket은arn:aws:s3:::bucket,GetObject는arn:aws:s3:::bucket/*입니다. 자세한 내용은 S3 403 해결 에 있습니다. - 정책 변경 직후: IAM 은 결과적 일관성이라 변경이 전파되는 데 몇 초 걸릴 수 있습니다. 자동화에서 역할을 만든 직후 바로 쓰면 잠깐 실패할 수 있습니다.
- 역할 신뢰 정책:
AssumeRole자체가 실패하면 권한 정책이 아니라 신뢰 정책의Principal과 조건(sts:ExternalId)을 봅니다. - Identity Center 권한 세트: 권한 세트를 고친 뒤 계정에 다시 프로비저닝해야 반영됩니다. IAM Identity Center 참고.