소개
정책 마이그레이션 후 보고서 읽기 신원이 AccessDenied를 반환합니다. 호출자, 요청한 작업, 리소스, 거부 문을 확인하며 reader의 제한된 범위를 보존하면서 불일치를 하나씩 수정합니다.
먼저 보고서 읽기 신원에 최소 권한 부여하기에서 정책 필드와 명시적 Deny를 익히세요. 새 VM은 관리용 default와 작업용 reader를 준비합니다. /home/labex/project에서 작업하고 AWS View에서 저장된 정책을 실제 읽기와 비교하세요.
인증 시험 관련 주제
| 인증 | 시험 태스크 | 실습 내용 |
|---|---|---|
| Solutions Architect – Associate (SAA-C03) | 태스크 1.1 | 권한 부여 진단과 접근 경계 검증. |
| Developer – Associate (DVA-C02) | 태스크 2.1 | 권한 부여 진단과 접근 경계 검증. |
| CloudOps Engineer – Associate (SOA-C03) | 태스크 4.1 | 권한 부여 진단과 접근 경계 검증. |
| Security – Specialty (SCS-C03) | 태스크 4.2 | 기초 실습: 권한 부여 진단과 접근 경계 검증. |
| Data Engineer – Associate (DEA-C01) | 태스크 4.2 | 기초 실습: 권한 부여 진단과 접근 경계 검증. |
실습 개요

호출자를 확인하고 요청한 작업 수정하기
이 단계에서는 신원 실수와 정책 불일치를 구분한 뒤 Allow 작업을 수정합니다. 같은 명령도 자격 증명이 다르면 인가 결과가 달라질 수 있습니다.
이전된 정책에는 여러 불일치가 있습니다. 한 필드를 수정해도 다른 필드나 명시적 Deny가 계속 요청을 거부할 수 있습니다. 변경할 때마다 저장된 문서를 확인하고 같은 조회자 요청을 반복하세요. AccessDenied 응답이 그대로라는 사실만으로는 해당 수정이 올바른지 알 수 없습니다.

cd /home/labex/project
aws sts get-caller-identity --query Arn --output text
aws sts get-caller-identity --profile reader --query Arn --output text
user/iam05-operator와 user/report-reader를 예상하세요. 보고서 작업은 운영자가 아닌 reader를 사용합니다. 운영자로 객체 존재를 확인한 뒤 reader로 작업 실패를 재현하세요.
aws s3api get-object \
--bucket labex-iam05-reports \
--key reports/today.txt operator-report.txt
cat operator-report.txt
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt reader-before.txt || true
운영자는 Daily orders: 145를 받고 reader는 AccessDenied를 받습니다. 키 누락이나 연결 오류라면 다른 조사가 필요합니다. || true는 붙여 넣은 순서에서 예상된 실패 요청이 끝나도록 합니다.
reader의 정책을 나열하고 저장된 문서를 읽으세요. 이는 작업에 운영자 접근을 빌려 주려는 시도가 아니라 작업 신원에 대한 운영자 조회입니다.
aws iam list-user-policies --user-name report-reader
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
Allow는 s3:ListBucket을 지정하지만 오류는 GetObject를 지정합니다. ListBucket은 객체 이름을 나열하고 버킷 ARN을 사용하며 객체 바이트를 다운로드하지 않습니다. 다음 불일치를 별도로 진단할 수 있도록 현재 Resource와 Deny를 유지하고 Allow Action만 GetObject로 변경하세요.
cat > repair-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports"},
{"Effect":"Deny","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/*"}
]}
JSON
aws iam put-user-policy \
--user-name report-reader \
--policy-name LabReport \
--policy-document file://repair-policy.json
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt reader-action-fix.txt || true
여전히 AccessDenied를 반환합니다. Action은 이제 올바르지만 필드 하나를 수정했다고 해서 모든 적용 가능한 검사가 통과하는 것은 아닙니다.
완전한 객체 ARN 일치시키기
이 단계에서는 거부 문을 보존하면서 Resource를 수정합니다. GetObject는 키를 포함하는 객체 ARN에 적용됩니다. 버킷 ARN arn:aws:s3:::labex-iam05-reports는 arn:aws:s3:::labex-iam05-reports/reports/today.txt와 일치하지 않습니다.
Allow Resource를 정확한 오늘 객체 ARN으로 교체하세요. 버킷이나 키 전체에 *를 사용하지 마세요. 작업에는 필요한 입력 하나가 있습니다.
cat > repair-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/today.txt"},
{"Effect":"Deny","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/*"}
]}
JSON
aws iam put-user-policy \
--user-name report-reader \
--policy-name LabReport \
--policy-document file://repair-policy.json
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt reader-resource-fix.txt || true
다시 AccessDenied를 예상하세요. 이제 Allow가 Action과 Resource 모두에 일치하므로 남은 문을 확인합니다. Deny도 오늘을 포함한 reports/*의 GetObject와 일치합니다. 일치하는 명시적 Deny는 Allow보다 우선합니다. 문서에서 Allow를 뒤로 이동해도 이를 무시할 수 없습니다.
접근을 확대하지 않고 Deny 수정하기
이 단계에서는 마이그레이션된 Deny 범위를 수정하고 최소 수정을 확인합니다. 의도한 보호는 비공개 데이터를 지키며 보고서 입력을 거부해서는 안 됩니다. 보호를 제거하거나 더 넓은 권한을 추가하는 대신 정확한 읽기 Allow를 유지하고 Deny를 private/*로 좁히세요.
cat > repair-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/reports/today.txt"},
{"Effect":"Deny","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam05-reports/private/*"}
]}
JSON
aws iam put-user-policy \
--user-name report-reader \
--policy-name LabReport \
--policy-document file://repair-policy.json
aws s3api get-object \
--profile reader \
--bucket labex-iam05-reports \
--key reports/today.txt today.txt
cat today.txt
Daily orders: 145를 예상하세요. 같은 reader로 주변 리소스를 테스트합니다. 완료된 수정이 범위를 확대해서는 안 됩니다.
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/yesterday.txt yesterday-denied.txt || true
aws s3api get-object --profile reader --bucket labex-iam05-reports --key private/payroll.txt payroll-denied.txt || true
aws s3api get-object --profile reader --bucket labex-iam05-reference --key reference.txt reference-denied.txt || true
세 요청 모두 AccessDenied를 반환해야 합니다. 필요한 읽기 권한은 쓰기도 허용해서는 안 됩니다. 제공된 대체 파일을 시도한 뒤 원래 보고서 바이트가 변경되지 않았는지 확인하세요.
aws s3api put-object --profile reader --bucket labex-iam05-reports --key reports/today.txt --body upload.txt || true
aws s3api get-object \
--profile reader \
--bucket labex-iam05-reports \
--key reports/today.txt today.txt
cat today.txt
aws iam get-user-policy \
--user-name report-reader \
--policy-name LabReport \
--query PolicyDocument
PutObject AccessDenied와 변경되지 않은 Daily orders: 145를 예상하세요. AWS View에는 이제 오늘은 Readable, 다른 리소스는 Denied로 표시됩니다. 정책 확인은 수정을 설명하고 실제 요청은 효과를 보여 줍니다.

수정한 권한을 회수하고 소유 데이터 정리하기
이 단계에서는 LabReport를 제거하고 보고서가 아직 존재하는 동안 접근이 회수되었음을 증명합니다. 그런 다음 소유한 보고서 버킷과 키 세 개만 삭제합니다.
aws iam delete-user-policy --user-name report-reader --policy-name LabReport
aws iam list-user-policies --user-name report-reader
aws s3api get-object --profile reader --bucket labex-iam05-reports --key reports/today.txt revoked.txt || true
빈 정책 목록과 AccessDenied를 예상하세요. 정책 회수와 데이터 삭제는 별도 검사입니다. 참조 버킷은 변경하지 마세요.
aws s3api delete-object --bucket labex-iam05-reports --key reports/today.txt
aws s3api delete-object --bucket labex-iam05-reports --key reports/yesterday.txt
aws s3api delete-object --bucket labex-iam05-reports --key private/payroll.txt
aws s3api list-objects-v2 --bucket labex-iam05-reports
성공한 인증 응답에서 KeyCount: 0이고 Contents에 남은 객체 항목이 없는지 확인하세요.
aws s3api delete-bucket --bucket labex-iam05-reports
aws s3api list-buckets --query 'Buckets[].Name'
aws s3api get-object --bucket labex-iam05-reference --key reference.txt reference.txt
cat reference.txt
Platform reference: keep이 있는 참조 버킷만 남습니다. 서비스 실패는 삭제를 증명하지 않습니다. 환경이 끝나면 준비된 신원이 회수됩니다. 작업 정책과 소유한 연습 데이터는 제거되었습니다.
요약
호출자를 확인하고 실패한 작업을 Allow Action과 비교하며 완전한 객체 ARN을 일치시켰습니다. 겹치는 명시적 Deny도 수정했습니다. 중간 실패는 남은 장애 요인을 식별하는 데 도움이 되었습니다. 최종 reader는 필요한 보고서만 읽을 수 있었으며 쓰거나 관련 없는 데이터를 읽을 수는 없었습니다. 수정된 권한을 회수하고 범위를 지정한 정리를 완료했습니다. 접근을 진단할 때 같은 신원을 사용하고 성공 요청과 금지된 요청을 모두 테스트하세요.
자세한 내용은 AWS 공식 문서를 참고하세요: IAM 액세스 거부 오류 진단.



