OPS

[AWS 실무 팁] S3 aws s3 sync 시 AccessDenied 해결법

찻잔속청개구리 2025. 4. 22. 23:34
반응형

최근 실무에서 aws s3 sync 명령어를 사용해 데이터를 업로드할 때 AccessDenied 에러가 자주 발생한 시기가 있었다. 
단순히 권한 부족이라고 보기에는 의심스러운 상황이었고, 정책을 하나씩 검토하면서 해결했다.

이번 포스트에서는 해당 문제를 어떻게 접근했고, 어떤 항목들을 확인해서 해결했는지 실무 기준으로 정리해봤다.

 

🧭 개념 정의

먼저 개념부터 명확히 정리하자.

S3 명령어 사용자 aws s3 sync 명령어를 실행한 IAM 사용자
S3 버킷 데이터를 저장하려는 대상 버킷
KMS 키 버킷에 설정된 암호화 키 (예: aws/s3 또는 customer-managed key alias/mkr-xxx)

 

✅ 확인해야 할 핵심 포인트 3가지

문제가 생겼을 때, 아래 3가지만 집중적으로 점검하면 된다.


1. ✅ S3 버킷 정책이 S3 명령어 사용자를 허용하는가?

S3 버킷의 정책(Policy)에서 aws s3 sync를 실행한 주체(사용자 또는 Role)에 대해 PutObject, ListBucket 등이 허용되어야 한다.

{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::<ACCOUNT_ID>:user/<USERNAME>"
  },
  "Action": [
    "s3:PutObject",
    "s3:GetObject",
    "s3:ListBucket"
  ],
  "Resource": [
    "arn:aws:s3:::<your-bucket-name>",
    "arn:aws:s3:::<your-bucket-name>/*"
  ]
}
 

✅ 주의: Resource에는 본 버킷만 정확히 포함되어 있어야 하며, /* 포함 여부를 꼭 확인할 것


2. ✅ S3가 사용하는 KMS 키 정책에 S3 명령어 사용자가 포함되어 있는가?

S3가 SSE-KMS(고객 키 사용) 방식으로 암호화되어 있다면,
S3가 사용하는 KMS 키 정책에 명령어 사용자가 명시적으로 있어야 PutObject가 가능하다.

{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::<ACCOUNT_ID>:user/<USERNAME>"
  },
  "Action": [
    "kms:Encrypt",
    "kms:Decrypt",
    "kms:GenerateDataKey*"
  ],
  "Resource": "*"
}

🔐 KMS 키 ARN은 보통 arn:aws:kms:region:account-id:key/mkr-xxxx-xxxx 형태임


3. ✅ S3 명령어 사용자의 IAM 정책에 S3 + KMS 권한이 모두 포함되어 있는가?

마지막으로, 명령어를 실행한 IAM 사용자 혹은 Role에 부여된 정책에서 아래 권한들이 제대로 부여되어 있는지 확인한다.

📁 S3 관련 권한

"Action": [
  "s3:PutObject",
  "s3:GetObject",
  "s3:ListBucket"
]
 

🔐 KMS 관련 권한

"Action": [
  "kms:Encrypt",
  "kms:Decrypt",
  "kms:GenerateDataKey*"
]
 

⚠️ 자주 하는 실수

 
❌ S3 버킷에만 권한을 줌 -> KMS 키 정책을 빼먹어서 암호화/복호화에 실패
❌ S3 정책에 /* 리소스를 빼먹음 -> 버킷 안의 객체에 대한 권한이 빠져서 PutObject 실패
❌ KMS 권한을 사용자에 직접 안 주고, Assume Role 권한만 줌 -> Role에는 있는데 실행한 주체가 다르면 실패함

 

반응형