지난 4일간 본 것들을 한 줄로 묶으면 "AWS에서 무언가가 동작하려면 ① 어디서(Region/AZ) ② 누가(Principal) ③ 무엇을(Action) ④ 어디에(Resource) ⑤ 어떤 조건(Condition)에서 할 수 있는지가 모두 맞아야 한다"는 문장이 된다. 이게 DVA 시험에서 보안·문제 해결 도메인(합치면 44%)의 90% 답을 결정한다.
오늘은 1주차의 키 개념들을 시나리오 기반으로 다시 묶고, 시험에 자주 나오는 함정 패턴들을 분류한다. 진도가 아니라 정리 회차이므로 문제와 해설을 더 깊게 둔다. 실제 시험 직전에 다시 한 번 훑기 좋은 형태로 정리한다.
[ AWS Global Infrastructure ]
└─ Region (격리된 인프라 단위)
└─ AZ (3+ 물리적 DC 그룹)
└─ EC2/Lambda/RDS 등 실제 자원
└─ IAM (누가 무엇을 할 수 있는가)
├─ User (장기 자격증명)
├─ Group (권한 묶음)
├─ Role (임시 자격증명 발급기)
└─ Policy (JSON 명세서)
└─ Condition (ABAC 엔진)
이 사슬에서 어느 하나라도 끊기면 호출이 실패한다. 시험 시나리오를 풀 때 어느 고리가 문제인지 식별하는 게 빠른 답으로 가는 길이다.
다시 한 번 강조하자면, AWS의 모든 보안 모델은 deny-by-default다. 어떤 자원에 대해서도 명시적 Allow가 없으면 거부된다. SCP 같은 상위 가드레일이 추가로 차단할 수는 있지만 권한을 생성하지는 못한다. 이 모델을 받아들이고 나면 "왜 권한이 안 되지?"라는 질문은 항상 "어디서 Allow가 누락됐나?"의 검색으로 풀린다.
가장 흔한 시나리오. 단순히 "IAM Role을 attach해라"가 항상 답은 아니다. 가능한 원인을 다 짚어보자.
| 원인 | 증상 | 해결 |
|---|---|---|
| IAM Role 미attach | "Unable to locate credentials" | 인스턴스 프로파일 부여 |
| Role 정책에 S3 권한 없음 | AccessDenied | s3:GetObject 등 추가 |
| S3 버킷 정책의 Explicit Deny | AccessDenied | bucket policy 검토 |
| S3 Block Public Access + 잘못된 정책 | AccessDenied | BPA 또는 정책 재구성 |
| VPC Endpoint 없이 private subnet | timeout | S3 Gateway Endpoint 추가 |
| KMS 키로 암호화된 객체 + KMS 권한 없음 | AccessDenied (KMS) | KMS Key Policy + IAM kms:Decrypt |
⚠️ 함정: SSE-KMS로 암호화된 S3 객체는 IAM의
s3:GetObject만으로는 못 읽는다. 같은 Principal에kms:Decrypt도 있어야 하고, KMS Key Policy의 grant 항목에도 그 Principal이 있어야 한다. 시험에서 "S3 권한은 있는데 GetObject가 실패"라는 시나리오는 거의 KMS가 답이다.
🔍 더 깊이: VPC Endpoint 시나리오는 네트워크 레이어의 문제라 IAM 디버깅으로는 안 풀린다. private subnet의 EC2가 S3에 접근할 때 (1) NAT Gateway 경유로 인터넷 통해 가거나, (2) S3 Gateway Endpoint(라우팅 테이블에 prefix-list 추가) 또는 Interface Endpoint(PrivateLink)로 AWS 내부망에서 가야 한다. NAT를 안 쓰고 Endpoint도 없으면 timeout이 난다. AccessDenied가 아니라 timeout이라는 점이 진단의 단서.
선택지를 클릭하면 정답·해설이 펼쳐집니다.
문제 1
한 회사가 모든 직원에게 IAM User를 발급하고 access key로 CLI를 쓰고 있다. CISO가 보안 감사 결과 "장기 키 사용 금지"를 지시했다. 가장 적절한 마이그레이션은?
문제 2
다음 IAM 정책의 효과는? ```json { "Effect": "Allow", "Action": "s3:*", "Resource": "arn:aws:s3:::project-${aws:PrincipalTag/Project}/*", "Condition": {"Null": {"aws:PrincipalTag/Project": "false"}} } ```
문제 3
EC2에서 Lambda로 워크로드를 옮긴 후 코드 변경 없이 같은 IAM 정책으로 동작시키려고 한다. 무엇이 달라지는가?
문제 4
STS의 AssumeRole 응답에 포함되지 않는 것은?
문제 5
한 회사가 SCP로 "us-east-1과 ap-northeast-2만 허용"을 설정했다. IAM User에는 `AdministratorAccess`가 있다. 이 User가 eu-west-1에서 EC2를 시작하려 한다. 결과는?
문제 6
다음 시나리오에서 가장 적절한 디버깅 첫 단계는? "EC2에서 boto3 코드가 `An error occurred (AccessDenied) when calling the GetObject operation`을 반환한다."
문제 7
한 개발자가 `~/.aws/credentials`에 dev profile을 설정했는데, CLI 명령에 `--profile dev`를 명시하지 않으면 default profile의 자격증명이 사용된다. 모든 명령에 자동으로 dev profile이 적용되게 하려면?
문제 8
IAM Policy의 `"Resource": "arn:aws:s3:::my-bucket/${aws:username}/*"`에서 `${aws:username}` 변수가 평가되는 시점은?
문제 9
SigV4 서명이 timestamp 검증에 실패할 때 나오는 에러는?
문제 10
한 회사가 AWS Organizations로 prod와 dev 계정을 분리하고, 개발자들은 IAM Identity Center로 두 계정의 Role을 모두 assume할 수 있다. dev 계정에 큰 사고가 생겨도 prod이 보호되는 이유는?
문제 11
Lambda 함수가 `LimitExceededException`을 받았다. SDK의 default retry 동작은?
문제 12
한 회사가 SaaS 모니터링 도구에게 자기 AWS 계정의 CloudWatch 지표를 읽게 하려고 한다. 가장 안전한 설정은?
Cross-account는 "양쪽 합의"가 원칙. Lambda 함수의 실행 역할에 ① sts:AssumeRole 권한 + 대상 계정 Role ARN 명시, ② 대상 계정 Role의 Trust Policy에 우리 Role을 Principal로 명시, 둘 다 필요하다.
# Lambda 코드 안에서 cross-account 호출
import boto3
sts = boto3.client('sts')
resp = sts.assume_role(
RoleArn='arn:aws:iam::222222222222:role/CrossAccountReadRole',
RoleSessionName='lambda-cross-account'
)
creds = resp['Credentials']
s3 = boto3.client('s3',
aws_access_key_id=creds['AccessKeyId'],
aws_secret_access_key=creds['SecretAccessKey'],
aws_session_token=creds['SessionToken']
)
s3.list_objects_v2(Bucket='other-account-bucket')이 코드의 함정: 받은 임시 자격증명은 1시간 후 만료되는데, Lambda가 워크플로 안에서 보관하다가 재사용하면 만료 후 호출에 실패한다. 매 호출마다 새로 assume하거나, SDK의 RefreshableCredentials를 활용해 자동 갱신을 맡기는 것이 깔끔하다.
sts.amazonaws.com(글로벌) vs sts.ap-northeast-2.amazonaws.com(리전). 시험에서 "us-east-1 장애 시 다른 리전의 워크로드가 자격증명 발급에 실패"라는 시나리오가 나오면 글로벌 STS endpoint를 의심한다. AWS_STS_REGIONAL_ENDPOINTS=regional로 전환.
Permission Boundary는 IAM User/Role의 효과적 최대 권한을 정의하는 메커니즘이다. Boundary에 없는 액션은 Identity Policy에 있어도 차단된다. 흔히 "관리자가 개발자에게 IAM 관리 권한을 위임하면서 너무 큰 권한이 새어 나가지 않도록" 사용한다. 예: 개발자가 만들 수 있는 모든 Role에 Boundary를 강제하면, 그 Role들이 IAM 자체를 건드릴 수 없게 막을 수 있다.
⚠️ 함정: SCP, Permission Boundary, Session Policy의 차이는 시험에 단골이다. SCP는 계정 전체에 적용되는 Organizations 가드레일, Permission Boundary는 특정 IAM Entity의 최대 권한 상한, Session Policy는 AssumeRole 호출 시 inline으로 한 번만 좁히는 일회성 가드레일. 셋 다 "권한을 부여하지 않고 차감만 한다"는 공통점이 있다.
| 도메인 | 비중 | 1주차에서 다룬 영역 |
|---|---|---|
| 개발 (Development) | 32% | SDK, CLI, credential chain |
| 보안 (Security) | 26% | IAM 전체, STS, SigV4 |
| 배포 (Deployment) | 24% | (아직 안 다룸) |
| 문제 해결 (Troubleshooting) | 18% | IAM 정책 시뮬레이션, --debug, get-caller-identity |
1주차의 중요도는 시험에서 보안 26% + 문제해결 18%의 절반 이상이 IAM 관련이라는 점에서 압도적이다. 1주차를 완벽하게 이해하면 시험의 30% 이상은 거저 푸는 셈이다.
ARN(Amazon Resource Name)은 arn:partition:service:region:account-id:resource 형식이다. 시험에 자주 나오는 패턴을 외워두자.
| 자원 | ARN 예시 |
|---|---|
| IAM User | arn:aws:iam::123456789012:user/Alice |
| IAM Role | arn:aws:iam::123456789012:role/MyRole |
| S3 Bucket | arn:aws:s3:::my-bucket (region/account 없음) |
| S3 Object | arn:aws:s3:::my-bucket/path/to/file |
| Lambda Function | arn:aws:lambda:ap-northeast-2:123456789012:function:MyFn |
| Lambda Layer | arn:aws:lambda:ap-northeast-2:123456789012:layer:MyLayer:3 (버전 번호 포함) |
| DynamoDB Table | arn:aws:dynamodb:ap-northeast-2:123456789012:table/MyTable |
| SQS Queue | arn:aws:sqs:ap-northeast-2:123456789012:MyQueue |
| SNS Topic | arn:aws:sns:ap-northeast-2:123456789012:MyTopic |
| KMS Key | arn:aws:kms:ap-northeast-2:123456789012:key/uuid |
| Secrets Manager | arn:aws:secretsmanager:ap-northeast-2:123456789012:secret:Name-randomSuffix |
| Parameter Store | arn:aws:ssm:ap-northeast-2:123456789012:parameter/path/to/param |
💡 암기 팁: S3와 IAM은 글로벌 서비스라 ARN에 region이 비어 있다(
arn:aws:s3:::). 다른 서비스는 region이 채워진다. 또 IAM은 account-id가 들어가지만 S3는 안 들어간다(버킷 이름 자체가 글로벌 unique). 그리고 partition은 일반 AWS는aws, GovCloud는aws-us-gov, 중국 리전은aws-cn이다. 정책을 cross-partition으로 복사하면 partition prefix를 바꾸지 않아 fail하는 경우가 있다.
1주차는 AWS의 "기반"을 깐다. 인프라 지도 위에 IAM이라는 신뢰의 사슬이 얹혀 있고, 그 사슬에 코드의 SDK 호출이 묶인다. 다음 주부터는 이 위에 진짜 컴퓨트(EC2, Lambda, ECS), 데이터(S3, DynamoDB, RDS), 통합(API Gateway, SQS, EventBridge), 배포(CodePipeline 등)가 올라간다.
기억해야 할 핵심 마인드셋: AWS에서 "이게 왜 안 되지?"라는 질문은 거의 항상 "어떤 IAM 평가 단계에서 막혔나?"로 환원된다. SCP, Resource Policy, Identity Policy, Permission Boundary, Session Policy, Explicit Deny — 이 6개 레이어 중 하나가 답이다. 그리고 그 답을 찾는 출발점은 aws sts get-caller-identity와 IAM Policy Simulator다.