소개
애플리케이션은 S3에 저장된 비공개 내보내기 파일을 읽어야 합니다. 고객 키로 새 업로드를 암호화하고 읽기 수행자에게 접근 권한을 부여하며 객체 권한과 키 권한이 실제 다운로드에 어떤 영향을 주는지 테스트합니다.
S3에서 파일 저장하고 검색하기, KMS로 비공개 내보내기 파일 암호화 및 복호화와 해당 실습의 IAM 선행 실습을 먼저 완료하세요. 이 새 VM에는 테스트용 내보내기 파일, 읽기 역할 세션과 독립적인 참조 리소스가 제공됩니다.
인증 시험 관련 주제
이 실습은 다음 시험 주제에 대한 실습 경험을 제공합니다.
- Cloud Practitioner (CLF-C02) · 태스크 2.2: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- Solutions Architect – Associate (SAA-C03) · 태스크 1.3: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- Developer – Associate (DVA-C02) · 태스크 2.2: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- CloudOps Engineer – Associate (SOA-C03) · 태스크 4.2: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- Security – Specialty (SCS-C03) · 태스크 5.2: 기초 실습: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- Data Engineer – Associate (DEA-C01) · 태스크 4.3: 기초 실습: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- DevOps Engineer – Professional (DOP-C02) · 태스크 6.2: 기초 실습: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
- Solutions Architect – Professional (SAP-C02) · 태스크 2.3: 기초 실습: S3 저장 데이터 암호화와 별도의 객체 및 키 권한.
암호화된 객체 저장소 준비
이 단계에서는 고객 KMS 키를 만들고 새 버킷이 이를 기본으로 사용하도록 설정합니다. 버킷은 객체를 보관하며 각 객체에는 exports/private-export.json과 같은 키가 있습니다. **KMS를 사용하는 서버 측 암호화 (SSE-KMS)**를 사용하면 S3가 선택한 키로 저장된 객체를 암호화합니다. 기본 암호화는 각 클라이언트가 암호화 옵션을 반복하지 않아도 새 업로드에 적용됩니다.
제공된 테스트용 private-export.json을 사용하세요. export-reader 역할 세션은 객체나 키에 접근할 권한 없이 시작합니다. 참조 버킷, 객체와 키를 유지하세요. Terminal 옆에서 AWS View를 열어 키/버킷 상태, 읽기 수행자에게 부여된 권한과 안전한 바이트 비교 결과를 확인하세요.
프로젝트 디렉터리에서 시작하고 제공된 운영자 신원을 확인하세요. cd는 디렉터리를 변경하고 호출자 쿼리는 자격 증명을 노출하지 않고 신원 ARN을 반환합니다.
cd /home/labex/project
aws sts get-caller-identity --query Arn --output text
labex-sec02-operator 사용자가 나와야 합니다. 대칭 고객 키와 읽기 쉬운 별칭을 만드세요. --query는 ARN을 선택하고 --output text는 JSON 따옴표를 제거하며 $(...)는 결과를 셸 변수에 저장합니다.
KEY_ARN=$(aws kms create-key \
--description labex-sec02-owned-export \
--query KeyMetadata.Arn \
--output text)
aws kms create-alias \
--alias-name alias/labex-sec02-private-export \
--target-key-id "$KEY_ARN"
이름 충돌을 피하려면 타임스탬프 접미사가 있는 일회용 버킷 이름을 사용하세요. labex-sec02-owned- 접두사는 본인 버킷과 제공된 참조 버킷을 구별합니다. 이 단원은 us-east-1을 사용하므로 버킷 생성 시 위치 제약 조건이 필요하지 않습니다.
BUCKET="labex-sec02-owned-$(date +%s)"
aws s3api create-bucket \
--bucket "$BUCKET" \
--region us-east-1 \
--query Location \
--output text
정확한 키 ARN으로 SSE-KMS를 설정하세요. S3 버킷 키는 반복되는 KMS 요청을 줄일 수 있습니다. 여기서는 각 객체가 자체 KMS 암호화 컨텍스트를 사용하도록 비활성화합니다. 기본 규칙을 일반 JSON 파일로 작성하세요. here-document는 $KEY_ARN을 확장하고 file://는 저장된 설정을 불러옵니다.
cat > bucket-encryption.json <<EOF
{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "$KEY_ARN"
},
"BucketKeyEnabled": false
}
]
}
EOF
aws s3api put-bucket-encryption --bucket "$BUCKET" \
--server-side-encryption-configuration file://bucket-encryption.json
aws s3api get-bucket-encryption \
--bucket "$BUCKET" \
--query ServerSideEncryptionConfiguration
aws:kms, 본인의 키 ARN과 BucketKeyEnabled: false가 나와야 합니다. 이후 명령을 위해 이 Terminal에서 KEY_ARN과 BUCKET을 유지하세요. AWS View에서 소유한 키는 활성화되어 있으며 버킷에는 아직 객체가 없습니다.
읽기 수행자에게 필요한 두 권한 부여
이 단계에서는 내보내기 파일을 업로드하고 역할이 원래 바이트를 복구하도록 합니다. 업로드에는 선택한 키의 kms:GenerateDataKey가 필요합니다. SSE-KMS는 데이터 키로 객체 바이트를 암호화합니다. KMS는 이 데이터 키를 보호합니다. S3는 암호화된 객체와 암호화하여 감싼 데이터 키를 저장한 다음 권한이 있는 읽기 수행자가 객체를 다운로드할 때 복호화를 요청합니다. 키 자료가 CLI 출력에 나타날 필요는 없습니다.

이 SSE-KMS 객체를 읽으려면 객체 접근 권한과 키 복호화 권한이 모두 필요합니다.
s3api put-object로 제공된 파일을 업로드하세요. 버킷 기본값이 암호화 설정을 제공하며 --body private-export.json은 지정된 로컬 파일을 객체 바이트로 읽습니다. 작은 내보내기 파일에는 이 단일 파트 API를 사용하세요.
aws s3api put-object \
--bucket "$BUCKET" \
--key exports/private-export.json \
--body private-export.json \
--query '{Encryption:ServerSideEncryption,Key:SSEKMSKeyId,BucketKey:BucketKeyEnabled}'
aws s3api head-object \
--bucket "$BUCKET" \
--key exports/private-export.json \
--query '{Encryption:ServerSideEncryption,Key:SSEKMSKeyId,Bytes:ContentLength}'
aws:kms, 소유한 키 ARN과 원래 파일 크기가 나와야 합니다. 메타데이터만으로 읽기 수행자가 복호화할 수 있는지는 알 수 없습니다. 먼저 객체 접근 권한만 부여하세요. 객체 ARN은 버킷과 객체 키를 포함하며 버킷 ARN과 다릅니다. 다음 here-document는 정책 파일을 쓰고 그 안의 $BUCKET을 확장합니다.
cat > read-object.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::$BUCKET/exports/private-export.json"
}
]
}
EOF
aws iam put-role-policy \
--role-name labex-sec02-export-reader \
--policy-name ReadExportObject \
--policy-document file://read-object.json
--profile export-reader로 준비된 읽기 수행자 세션을 선택하세요. 이 시도는 AccessDenied로 실패해야 합니다. 역할은 이 객체를 읽을 수 있지만 아직 KMS 복호화 권한이 없습니다.
aws \
--profile export-reader s3api get-object \
--bucket "$BUCKET" \
--key exports/private-export.json reader-export.json
해당 역할에 정확한 키의 kms:Decrypt만 부여하세요. 다운로드에는 키 관리나 kms:GenerateDataKey가 필요하지 않습니다.
cat > decrypt-key.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "$KEY_ARN"
}
]
}
EOF
aws iam put-role-policy \
--role-name labex-sec02-export-reader \
--policy-name DecryptExportKey \
--policy-document file://decrypt-key.json
aws \
--profile export-reader s3api get-object \
--bucket "$BUCKET" \
--key exports/private-export.json reader-export.json \
--query '{Encryption:ServerSideEncryption,Key:SSEKMSKeyId}'
chmod 600 reader-export.json
cmp private-export.json reader-export.json
바이트 내용이 일치하면 cmp는 아무것도 출력하지 않고 성공을 반환합니다. 이제 AWS View에는 저장된 암호문과 반환된 바이트가 제공된 내보내기 파일과 일치하는 읽기 수행자의 GetObject가 표시되어야 합니다. 이는 별개의 관찰 결과입니다. 암호화된 저장소는 저장된 바이트를 보호하고 범위가 제한된 권한은 조회를 제어합니다.

권한 및 키 상태 실패 진단
이 단계에서는 누락된 복호화 권한과 비활성화된 키를 구별합니다. 한 번에 조건 하나만 바뀌도록 객체 권한을 유지하세요.
읽기 수행자의 키 권한을 제거한 다음 같은 객체 다운로드를 다시 시도하세요. 역할에는 여전히 s3:GetObject가 있지만 요청은 AccessDenied로 실패해야 합니다.
aws iam delete-role-policy \
--role-name labex-sec02-export-reader \
--policy-name DecryptExportKey
aws \
--profile export-reader s3api get-object \
--bucket "$BUCKET" \
--key exports/private-export.json reader-export.json
남아 있는 객체 정책을 확인하세요. 여전히 이 내보내기 객체만 지정해야 합니다.
aws iam get-role-policy \
--role-name labex-sec02-export-reader \
--policy-name ReadExportObject \
--query PolicyDocument
정확한 키 권한을 복구하고 본인 키를 비활성화하세요. 비활성화된 키는 여전히 존재하지만 암호화 작업을 수행할 수 없습니다. 관련 없는 참조 키를 변경하지 마세요.
aws iam put-role-policy \
--role-name labex-sec02-export-reader \
--policy-name DecryptExportKey \
--policy-document file://decrypt-key.json
aws kms disable-key --key-id "$KEY_ARN"
aws \
--profile export-reader s3api get-object \
--bucket "$BUCKET" \
--key exports/private-export.json reader-export.json
비활성화된 키로 인한 실패가 나와야 합니다. IAM 권한이 있어도 비활성화된 키를 사용할 수는 없습니다. 네이티브 상태를 확인한 다음 키를 활성화하고 객체를 다시 가져오세요.
aws kms describe-key --key-id "$KEY_ARN" --query KeyMetadata.KeyState --output text
aws kms enable-key --key-id "$KEY_ARN"
aws \
--profile export-reader s3api get-object \
--bucket "$BUCKET" \
--key exports/private-export.json reader-export.json \
--query ServerSideEncryption \
--output text
chmod 600 reader-export.json
cmp private-export.json reader-export.json
aws:kms가 나오고 비교가 성공해야 합니다. AWS View는 실패한 요청과 성공적인 복구를 함께 보여 주며 참조 버킷과 키는 계속 사용할 수 있습니다. 
다운로드가 실패해도 이전 로컬 파일이 남아 있을 수 있습니다. 따라서 파일 존재 여부만으로 요청 성공을 증명할 수 없습니다. 서명된 읽기와 비교가 복구를 증명합니다.
소유한 리소스 제거 및 키 삭제 예약
이 단계에서는 해당 내보내기 리소스를 정확히 정리합니다. 앞선 기능 검사를 먼저 마치세요. S3 버킷은 비어 있어야 삭제할 수 있습니다. 고객 KMS 키는 즉시 사라지는 대신 삭제 대기 기간을 사용합니다.
지정한 본인 내보내기 객체만 삭제한 다음 버킷을 삭제하세요. 인벤토리 목록 조회가 성공하는지 확인하고 본인의 $BUCKET은 없으며 labex-sec02-reference는 남아 있는지 확인하세요.
aws s3api delete-object --bucket "$BUCKET" --key exports/private-export.json
aws s3api delete-bucket --bucket "$BUCKET"
aws s3api list-buckets --query 'Buckets[].Name'
추가한 두 권한과 소유한 별칭을 제거하세요. 제공된 읽기 역할은 세션 준비물이므로 이 역할이나 관련 없는 참조 리소스를 삭제하지 마세요.
aws iam delete-role-policy \
--role-name labex-sec02-export-reader \
--policy-name ReadExportObject
aws iam delete-role-policy \
--role-name labex-sec02-export-reader \
--policy-name DecryptExportKey
aws iam list-role-policies --role-name labex-sec02-export-reader --query PolicyNames
aws kms delete-alias --alias-name alias/labex-sec02-private-export
최소 기간인 7일로 본인 키의 삭제를 예약한 다음 네이티브 상태를 읽으세요. 예약하면 즉시 사용할 수 없게 되지만 이미 삭제되었다는 것을 증명하지는 않습니다.
aws kms schedule-key-deletion \
--key-id "$KEY_ARN" \
--pending-window-in-days 7 \
--query DeletionDate \
--output text
aws kms describe-key --key-id "$KEY_ARN" --query KeyMetadata.KeyState --output text
aws kms describe-key \
--key-id alias/labex-sec02-reference \
--query KeyMetadata.KeyState \
--output text
본인 키는 PendingDeletion, 참조 키는 Enabled여야 합니다. 이름이 지정된 로컬 파일을 제거하세요. 이 명령들은 관련 없는 프로젝트 파일을 그대로 둡니다.
rm -f private-export.json reader-export.json read-object.json decrypt-key.json bucket-encryption.json
일회용 CLI 프로필을 제거하기 전에 이 단계의 검증을 실행하세요. 인증 오류가 아닌 성공한 네이티브 인벤토리 쿼리가 정리를 증명합니다.
rm -f /home/labex/.aws/credentials /home/labex/.aws/config
unset KEY_ARN BUCKET
요약
버킷 기본값으로 SSE-KMS를 설정하고 암호화된 내보내기 파일을 업로드했으며 객체 하나와 키 하나로 범위를 제한한 역할로 원래 바이트를 복구했습니다. kms:Decrypt를 취소하거나 키를 비활성화하면 객체 권한을 변경하지 않아도 각각 읽기가 차단되었습니다. 접근을 복구한 다음 참조 버킷과 키를 유지하면서 소유한 S3 리소스만 삭제하고 소유한 KMS 키의 삭제를 예약했습니다.



