[AWS] S3 IAM 권한 정책

2023. 8. 2. 10:36AWS

S3  버킷 권한 정책을 설정하는 도중에 AmazonS3FullAccess 정책이 아닌 커스텀 된 정책을 적용하는 도중 이슈가 발생.

Aws\S3\Exception\S3Exception: Error executing "PutObject" on .... AWS HTTP error: Client error ..... resulted in a `403 Forbidden` response

특정 iam 계정에 쓰기 권한을 부여하고 업로드 과정에서 403 forbidden 에러가 발생하는 것..

우선은 어떤 이유로 업로드가 안되는건지 AmazonS3FullAccess 정책을 다시 부여하고 업로드 시도를 해보았는데

정상적으로 업로드 처리가 됐다. ( AmazonS3FullAccess 정책이 작동하는 이유는 이 정책이 S3에 대한 전체 접근 권한을 부여하기 때문 )

아무래도 PutObject 권한만 주어서는 처리가 안되는것으로 판단하고 구글링을 해본 결과

첫번째 이유는 

권한 충돌: IAM 정책과 버킷 정책 모두 동일한 작업에 대한 권한을 부여하면서, 이러한 권한이 서로 충돌하는 경우가 있을 수 있고, 예를 들어, IAM 사용자가 속한 IAM 그룹 또는 역할의 정책이 s3:PutObject 작업을 제한하거나 거부하는 경우, 이는 403 오류를 일으킬 수 있다.

두번째 이유는

권한 부족: IAM 사용자가 S3 버킷에 객체를 업로드하는 데 필요한 다른 권한이 없는 경우도 있다. 예를 들어, s3:PutObject 작업 외에도 s3:PutObjectAcl이라는 권한이 필요할 수 있는데, 이 권한은 객체의 ACL을 설정하거나 변경할 수 있는 권한이고, 또한, s3:ListBucket 권한이 필요할 수도 있다.

나의 경우에는 ACL 권한과, ListBucket 권한이 설정이 안되어 있어서 업로드 처리가 안됐었다.

ListBucket은 Amazon S3 권한 중 하나로, 사용자가 특정 S3 버킷의 객체를 나열할 수 있는 권한을 부여,

즉, 해당 권한이 있으면 사용자는 버킷 내의 객체 목록을 확인할 수 있다.

이 권한이 중요한 이유 중 하나는, 객체를 업로드할 때 S3 API가 해당 버킷에 이미 같은 이름의 객체가 있는지 확인하기 위해 내부적으로 ListBucket을 사용할 수 있기 때문 따라서, ListBucket 권한이 없으면 403 오류를 반환하거나 업로드가 실패하는 등의 문제가 발생할 수 있다.

그러므로, PutObject와 같은 기타 작업을 수행하는 사용자에게 ListBucket 권한을 부여하는 것이 일반적으로 좋은 관행이라고 한다.

아래는 내가 설정 한 권한 및 정책들이다. 참고하면 좋을 것 같다.

// 버킷 정책
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject", // 선택적 식별자
            "Effect": "Allow", // 선언이 허용하거나 거부하는 동작
            "Principal": "*", // 정책이 적용되는 AWS 계정이나 IAM 사용자를 지정
            "Action": "s3:GetObject", // 선언이 적용되는 동작
            "Resource": "arn:aws:s3:::버킷명/*" // 선언이 적용되는 리소스
        },
        {
            "Sid": "AdminWriteDeleteObject",
            "Effect": "Allow",
            "Principal": {
                "AWS": "iam 계정의 ARN 값"
            },
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::버킷명/*"
        }
    ]
}
// CORS(Cross-origin 리소스 공유)
[
    {
    	// 모든 종류의 HTTP 헤더를 허용
        "AllowedHeaders": [
            "*"
        ],
        // HTTP 메서드 "PUT", "GET"를 허용
        "AllowedMethods": [
            "GET",
            "PUT"
        ],
        // 모든 출처를 허용
        "AllowedOrigins": [
            "*"
        ],
        // 어떠한 헤더도 노출시키지 않는다는 것을 의미
        "ExposeHeaders": []
    }
]
// iam 정책
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::버킷명",
                "arn:aws:s3:::버킷명/*"
            ]
        }
    ]
}