| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- TryHackMe
- AWS 침해사고 사례 분석
- AWS
- 리버싱
- dreamhack
- AWS 아키텍처 분석
- AWS 인프라 분석
- IAM Federation
- AWS 사고 사례 분석
- AWS 3 Tier Architecture
- python
- terraform
- network
- programmers
- 침입 차단 시스템(IPS)
- reversing
- 드림핵
- AWS 인프라 아키텍처
- C
- 운영체제
- 프로그래머스
- 네트워크
- reversing.kr
- Amazon S3
- AWS 보안 아키텍처 분석
- AWS 침해 사고 사례 분석
- operating system
- AWS 보안 사고 사례 모음
- AWS Active Directory
- AWS IAM Role
- Today
- Total
lhywk 님의 블로그
AWS IAM 본문
1. IAM 핵심 구성요소
1-1. IAM User
IAM User는 AWS에서 사람 또는 애플리케이션을 나타내는 자격 증명입니다. 이름과 자격 증명(비밀번호 또는 Access Key)을 가집니다.
IAM User의 특성:
- 기본적으로 아무 권한도 없습니다 -> 명시적으로 부여해야 합니다
- 콘솔 로그인(비밀번호)과 API 접근(Access Key)을 따로 설정
- 하나의 AWS 계정 안에 최대 5,000명의 IAM User 생성 가능
중요한 설계 원칙: IAM User에 직접 Policy를 붙이는 것보다 Group을 통해 관리하는 것이 권장됩니다. 사람 수가 늘어날수록 직접 관리는 어렵습니다.
1-2. IAM Group
Group은 IAM User의 집합입니다. Group에 Policy를 연결하면 그 Group에 속한 모든 User가 동일한 권한을 갖습니다.
Group의 특성:
- Group은 자격 증명이 아닙니다 -> Group 자체로는 로그인하거나 API를 호출할 수 없습니다
- User는 여러 Group에 동시에 속할 수 있습니다
- Group 안에 Group을 넣는 것(중첩)은 불가능합니다
[Group: Developer] → AmazonEC2FullAccess, S3ReadAccess
[Group: DBA] → AmazonRDSFullAccess, S3ReadAccess
[Group: DevOps] → Developer + DBA의 권한을 가진 별도 Group
1-3. IAM Policy
Policy는 JSON 문서로 작성된 권한 정의입니다. "어떤 서비스의 어떤 Action을 어떤 Resource에 허용/거부한다"는 내용을 담습니다.
Policy 기본 구조:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-northeast-2"
}
}
}
]
}
각 요소의 역할:
| 요소 | 설명 | 필수 여부 |
| Version | 정책 언어 버전. 항상 "2012-10-17" 사용 | 권장 |
| Statement | 하나 이상의 권한 정의 블록 배열 | 필수 |
| Sid | Statement 식별자 | 선택 |
| Effect | "Allow" 또는 "Deny" | 필수 |
| Action | 허용/거부할 API 작업 목록 | 필수 |
| Resource | 대상 리소스의 ARN | 필수 |
| Condition | 조건부 적용 (IP, MFA 여부 등) | 선택 |
1-4. Policy의 종류
AWS에서는 총 7가지 정책 유형을 지원합니다.
| 정책 유형 | 설명 | 연결 대상 |
| 자격 증명 기반 정책 (Identity-based) | 가장 일반적인 IAM 정책 | User, Group, Role |
| 리소스 기반 정책 (Resource-based) | 리소스 측에서 접근 제어 | S3 버킷, SQS, Lambda 등 |
| 권한 경계 (Permission Boundary) | 최대 권한 상한선 설정 | User, Role |
| SCP (Service Control Policy) | 계정/OU 단위 최대 권한 제한 | Organizations 계정/OU |
| RCP (Resource Control Policy) | 리소스 단위 최대 권한 제한 | Organizations 계정/OU |
| ACL (Access Control List) | 계정 간 접근 제어 (레거시) | S3 등 일부 서비스 |
| 세션 정책 (Session Policy) | AssumeRole 시 일시적 권한 축소 | STS 세션 |
이 중 이 글에서 집중해 볼 것은 자격 증명 기반 정책, 리소스 기반 정책, 권한 경계입니다.
1-5. 관리형 정책 vs 인라인 정책
자격 증명 기반 정책 안에서도 두 가지 방식이 있습니다.
관리형 정책 (Managed Policy):
- 독립적으로 생성하고 여러 User/Group/Role에 연결 가능
- AWS 관리형: AWS가 만들어 제공 (예: AdministratorAccess, AmazonS3FullAccess)
- 고객 관리형: 직접 만든 정책 -> 재사용 가능, 버전 관리 지원
- 권장 방식: 대부분의 경우 고객 관리형 정책 사용
인라인 정책 (Inline Policy):
- 특정 User/Group/Role 안에 직접 포함된 정책
- 해당 엔터티가 삭제되면 정책도 같이 삭제됨
- 재사용 불가 -> 특수한 경우에만 사용 권장
인라인 정책은 "이 사용자에게만 딱 이 권한을 줄 것이고, 절대 재사용하지 않을 것"이라는 경우에 사용합니다. 대부분은 고객 관리형 정책이 낫습니다.
2. Policy 평가 로직 (중요!)
IAM에서 가장 헷갈리는 부분이 바로 정책이 충돌할 때 어떻게 처리되는가입니다. 이걸 모르면 설계할 때 계속 막히게 됩니다.
2-1. 3가지 핵심 원칙
원칙 1: 기본은 Deny (Implicit Deny) 아무 정책도 없으면 모든 요청은 거부됩니다. 명시적으로 Allow를 부여해야만 허용됩니다.
원칙 2: Explicit Deny는 모든 Allow를 이긴다 어떤 Policy에 명시적 Deny가 있으면 다른 어떤 Policy에 Allow가 있더라도 최종 결과는 Deny입니다.
원칙 3: Allow들은 합산된다 여러 Policy에 Allow가 분산되어 있으면 모든 Allow의 합집합이 실제 권한이 됩니다.
쉽게 기억하는 공식:
최종 권한 = (모든 Allow의 합집합) - (Explicit Deny)
단 Explicit Deny가 있으면 그 항목은 무조건 거부
2-2. 단계별 평가 흐름
AWS가 요청을 받으면 아래 순서로 평가합니다.
요청 수신
↓
1. Explicit Deny 확인 (모든 정책 유형 통틀어)
- 있으면 → 즉시 DENY (끝)
↓
2. Organizations SCP 확인
- SCP가 Allow하지 않으면 → DENY
↓
3. 리소스 기반 정책 확인 (동일 계정 내)
- 리소스 기반 정책에 Allow 있으면 → 자격 증명 기반 정책 없어도 ALLOW 가능
↓
4. Permission Boundary 확인 (설정되어 있는 경우)
- Boundary가 Allow하지 않으면 → DENY
↓
5. 자격 증명 기반 정책 확인
- Allow 있으면 → ALLOW
- Allow 없으면 → DENY (Implicit Deny)
핵심 규칙 요약:
| 상황 | 결과 |
| 어디에든 Explicit Deny | DENY (무조건) |
| SCP가 차단 | DENY |
| Permission Boundary가 차단 | DENY |
| 자격 증명 기반 + 리소스 기반 정책 모두 Allow (동일 계정) | ALLOW |
| 자격 증명 기반 정책에만 Allow (동일 계정) | ALLOW |
| 리소스 기반 정책에만 Allow (동일 계정, IAM User/Role) | ALLOW |
| 아무 Allow도 없음 | DENY (Implicit Deny) |
2-3. 동일 계정 vs 크로스 계정
동일 계정 (Same Account):
- 자격 증명 기반 정책 OR 리소스 기반 정책 중 하나에만 Allow가 있어도 됨
- 두 정책이 합산됨
크로스 계정 (Cross Account):
- 자격 증명 기반 정책 AND 리소스 기반 정책 둘 다 Allow가 있어야 함
2-4. 헷갈리는 케이스 정리
케이스 1: AdministratorAccess + Deny S3
User: AdministratorAccess 정책 있음 (S3 포함 전체 Allow)
+ DenyS3 인라인 정책 있음 (S3 Deny)
결과: S3 접근 불가 Explicit Deny가 AdministratorAccess의 Allow를 이김
케이스 2: 그룹 A에서 Allow, 그룹 B에서 Deny
User: 그룹 A에 속함 (EC2 Allow)
그룹 B에 속함 (EC2 Deny)
결과: EC2 접근 불가 Explicit Deny가 우선
케이스 3: 자격 증명 기반 정책 없음 + 리소스 기반 정책 Allow
User: 자격 증명 기반 정책 없음
S3 버킷: 버킷 정책에 해당 User Allow
결과: 접근 가능 동일 계정 내에서는 리소스 기반 정책만으로도 허용 가능
3. Permission Boundary (권한 경계)
3-1. Permission Boundary가 필요한 이유
Permission Boundary를 이해하려면 다음 시나리오를 생각해봅시다.
"중간 관리자에게 IAM User를 생성할 수 있는 권한을 줘야 한다. 하지만 중간 관리자가 자기 부하 직원에게 자신보다 더 강한 권한을 줄 수 있다면 문제가 된다."
이것이 바로 권한 상승 문제입니다. IAM 관리 권한 자체가 매우 강력하기 때문에 잘못 위임하면 누군가 자신보다 높은 권한을 스스로 획득할 수 있습니다.
Permission Boundary는 이를 막는 장치입니다.
3-2. Permission Boundary란?
Permission Boundary는 자격 증명 기반 정책이 IAM 엔터티에 부여할 수 있는 최대 권한의 상한선입니다. 관리형 정책을 "경계"로 설정합니다.
중요한 특성:
- Permission Boundary는 권한을 부여하지 않습니다 -> 상한선을 정할 뿐입니다
- 실제 권한 = 자격 증명 기반 정책 ∩ Permission Boundary (교집합)
- 두 정책 모두에서 Allow된 것만 실제로 허용됩니다
- Explicit Deny는 경계 내에서도 유효합니다
예시:
자격 증명 기반 정책: S3 Full, EC2 Full, RDS Full
Permission Boundary: S3 Full, EC2 Full
실제 권한: S3 Full, EC2 Full (RDS는 Boundary에 없으므로 차단)
3-3. 사용 사례
사례 1: 개발팀 IAM 위임 관리
- 중앙 보안팀이 Boundary 정책을 정의 (예: DeveloperBoundary -> S3, EC2, Lambda만 허용)
- 개발팀 리드에게 IAM User 생성 권한 부여 (단 반드시 DeveloperBoundary를 Boundary로 설정해야만 생성 가능)
- 개발팀 리드가 만든 사용자는 아무리 강한 Policy를 붙여도 DeveloperBoundary 범위를 벗어날 수 없음
사례 2: CI/CD 파이프라인 역할 제한
- Lambda/EC2 배포 파이프라인이 IAM Role을 생성해야 할 때
- 해당 파이프라인이 만드는 Role에 Boundary를 강제함으로써 배포 자동화 Role이 과도한 권한을 갖지 못하도록 제한
사례 3: 권한 상승 방지
- IAM 관리자에게 AdministratorAccess를 부여하되 Boundary로 Billing 서비스 접근 차단
- 해당 관리자는 Billing 접근 가능한 새 사용자를 만들 수 없음 (Boundary 때문)
3-4. Permission Boundary 동작 확인
Boundary를 이해하는 가장 중요한 포인트:
Permission Boundary만 있고 자격 증명 기반 정책이 없으면 → 아무것도 못 함
자격 증명 기반 정책만 있고 Permission Boundary가 없으면 → 정책대로 작동
둘 다 있으면 → 교집합(AND)만 허용
그림으로 표현하면:
[자격 증명 기반 정책] [Permission Boundary]
S3 ✓ S3 ✓
EC2 ✓ → EC2 ✓ = 실제 권한: S3, EC2
RDS ✓ (RDS 없음)
Lambda ✓ Lambda ✓ = 실제 권한 추가: Lambda
4. IAM Policy 작성 패턴
4-1. 최소 권한 원칙
IAM 설계의 가장 중요한 원칙은 Least Privilege(최소 권한)입니다. 업무에 필요한 최소한의 권한만 부여하는 것입니다.
나쁜 예:
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
좋은 예:
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-app-bucket/*"
}
4-2. Condition을 활용한 세밀한 제어
Condition 요소를 활용하면 단순 Allow/Deny를 넘어 매우 세밀한 접근 제어가 가능합니다.
예시 1: MFA 인증된 경우에만 허용
{
"Effect": "Allow",
"Action": "iam:*",
"Resource": "*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
예시 2: 특정 IP 범위에서만 허용
{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"203.0.113.0/24",
"192.0.2.0/24"
]
}
}
}
예시 3: 특정 태그가 붙은 리소스만 접근 허용
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Environment": "dev"
}
}
}
4-3. 자주 쓰이는 AWS 관리형 정책
| 정책명 | 용도 |
| AdministratorAccess | 전체 관리자 (Billing 제외) |
| PowerUserAccess | IAM/Organizations 제외 전체 서비스 관리 |
| ReadOnlyAccess | 전체 서비스 읽기 전용 |
| IAMFullAccess | IAM 전체 관리 |
| IAMReadOnlyAccess | IAM 읽기 전용 |
| AmazonS3FullAccess | S3 전체 관리 |
| AmazonEC2ReadOnlyAccess | EC2 읽기 전용 |
| SecurityAudit | 보안 감사용 읽기 전용 |
주의: AdministratorAccess는 IAM 조작 권한도 포함됩니다. 실무에서는 실제로 모든 권한이 필요한 경우가 아니라면 PowerUserAccess 또는 커스텀 정책을 사용하는 것이 권장됩니다.
5. 실습: Policy 평가 로직
이 실습은 Explicit Deny와 Permission Boundary의 동작을 직접 확인하는 실습입니다. IAM Policy Simulator를 활용합니다.
실습 준비: 테스트용 IAM User 생성
IAM 콘솔 → Users → Create user
User name: iam-lab-user
AWS Management Console access: 활성화
Custom password 설정
MFA: 실습용이므로 생략 가능
실습 1: Explicit Deny vs Allow 충돌
Step 1: AdministratorAccess 부여
iam-lab-user → Add permissions → Attach policies directly
→ AdministratorAccess 선택 → Add permissions
Step 2: S3 Deny 인라인 정책 추가
iam-lab-user → Add permissions → Create inline policy
→ JSON 편집기에 아래 입력:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllS3",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*"
}
]
}
Policy name: DenyS3Lab → Create policy

Step 3: IAM Policy Simulator로 확인
1. https://policysim.aws.amazon.com 접속
2. Users → iam-lab-user 선택
3. Select service: S3
4. Select actions: GetObject, ListAllMyBuckets
5. [Run Simulation]

Step 4: EC2 확인 (Deny 없는 경우)
Select service: EC2
Select actions: DescribeInstances, RunInstances
[Run Simulation]
Explicit Deny는 모든 Allow를 이긴다.

실습 2: Permission Boundary 동작 확인
AdministratorAccess를 가진 사용자라도 Permission Boundary 밖의 서비스는 사용하지 못함을 확인합니다.
Step 1: Permission Boundary 정책 생성
IAM 콘솔 → Policies → Create policy
JSON 편집기에 아래 입력:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowOnlyEC2AndS3",
"Effect": "Allow",
"Action": [
"ec2:*",
"s3:*"
],
"Resource": "*"
}
]
}
Policy name: LabBoundaryPolicy → Create policy
Step 2: iam-lab-user에 Permission Boundary 설정
1. IAM → Users → iam-lab-user
2. [Permissions] 탭 → [Permissions boundary] 섹션
3. [Set boundary] → LabBoundaryPolicy 검색 후 선택
4. [Set boundary] 클릭
Step 3: IAM Policy Simulator로 확인
1. Users → iam-lab-user 선택
2. Select service: RDS
3. Select actions: DescribeDBInstances
4. [Run Simulation]

Step 4: EC2는 가능한지 확인
Select service: EC2
Select actions: DescribeInstances
[Run Simulation]

실습 3: 권한 상승 방지 패턴
IAM 관리 권한을 위임받은 사용자가 자신보다 높은 권한의 사용자를 만들 수 없도록 합니다.
Step 1: 별도 IAM 관리자 생성
IAM → Users → Create user
User name: delegated-iam-admin
Step 2: delegated-iam-admin에게 IAM 관리 권한 부여 (Boundary 조건 포함)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowIAMWithBoundaryOnly",
"Effect": "Allow",
"Action": [
"iam:CreateUser",
"iam:AttachUserPolicy",
"iam:PutUserPermissionsBoundary"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT_ID:policy/LabBoundaryPolicy"
}
}
},
{
"Sid": "DenyBoundaryModification",
"Effect": "Deny",
"Action": [
"iam:DeleteUserPermissionsBoundary",
"iam:PutUserPermissionsBoundary"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT_ID:policy/LabBoundaryPolicy"
}
}
}
]
}
- delegated-iam-admin은 IAM User를 만들 수 있지만 반드시 LabBoundaryPolicy를 Boundary로 설정해야만 생성 가능합니다
- Boundary를 제거하거나 다른 Boundary로 교체하는 것도 차단됩니다
실습 4: IAM Policy Simulator 활용법
Policy Simulator는 실제 API를 호출하지 않고 권한을 테스트할 수 있는 매우 유용한 도구입니다.
접속: https://policysim.aws.amazon.com
또는: IAM 콘솔 → 우측 메뉴 → Policy Simulator
사용 방법:
- 좌측에서 테스트할 User/Role 선택
- 서비스와 Action 선택
- 필요하면 Resource ARN 지정
- [Run Simulation] → 결과 확인
결과 읽는 법:
- allowed: 해당 Action 허용됨
- implicitly denied: 아무 Allow 없음
- explicitly denied: Deny 정책에 의해 차단됨
- denied by Organizations SCP: SCP에 의해 차단됨
- denied by permission boundary: Permission Boundary에 의해 차단됨
6. 자주 하는 실수들
실수 1: Action에 와일드카드 남용
// 나쁜 예
"Action": "s3:*"
// 좋은 예
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"]
와일드카드는 나중에 새로운 S3 API가 추가되면 자동으로 허용됩니다. 의도치 않은 권한 부여가 생길 수 있습니다.
실수 2: Resource를 "*"로 설정
// 나쁜 예
"Resource": "*"
// 좋은 예
"Resource": "arn:aws:s3:::my-specific-bucket/*"
특정 버킷만 접근 가능하게 해야 하는데 전체 S3에 접근 허용하는 경우가 매우 많습니다.
실수 3: Deny 정책을 너무 많이 만들기 Deny 정책이 많아질수록 권한 문제를 해결하기가 훨씬 어려워집니다. 다른 정책에서 이미 허용된 것을 재정의하는 용도로만 Deny를 사용하는게 좋습니다.
실수 4: Permission Boundary를 권한 부여로 오해 Boundary는 상한선입니다. Boundary에 EC2 Full이 있어도 자격 증명 기반 정책에 EC2 Allow가 없으면 EC2를 사용할 수 없습니다.
실수 5: 그룹 없이 User에 직접 정책 연결 10명정도 까지는 괜찮지만 사람 수가 늘어나면 관리 불가 상태가 됩니다. 처음부터 Group -> Policy 구조로 설계하세요.
7. IAM 설계 체크리스트
[ ] User에 직접 Policy 연결 대신 Group 사용
[ ] 최소 권한 원칙 적용 (필요한 것만 Allow)
[ ] Action에 "*" 최소화, 필요한 Action만 명시
[ ] Resource에 ARN 명시 (가능한 한 구체적으로)
[ ] MFA 조건 추가
[ ] 각 User/Role에 MFA 설정
[ ] IAM Access Analyzer로 미사용 권한 주기적 검토
[ ] 중요 운영 환경에 Permission Boundary 적용
[ ] Policy 변경 전 Policy Simulator로 사전 테스트
[ ] 인라인 정책보다 관리형 정책 우선 사용
이번 글의 내용을 정리합니다.
- IAM의 기본: User는 기본 권한 없음. Group으로 관리. Policy는 JSON 문서
- Policy 평가의 3원칙: 기본 Deny, Explicit Deny 최우선, Allow는 합산
- Permission Boundary: 권한 부여가 아니라 상한선. 자격 증명 기반 정책과의 교집합이 실제 권한
- Policy Simulator: 실제 API 호출 없이 권한 테스트 가능한 도구
참고 자료
'AWS' 카테고리의 다른 글
| AWS CloudFront (0) | 2026.04.02 |
|---|---|
| AWS IAM Role & STS (0) | 2026.04.02 |
| AWS Root User & 계정 초기 보안 (0) | 2026.04.01 |
| Sisense 사고 사례 분석 (1) | 2026.04.01 |
| Banfico 아키텍처 분석 (0) | 2026.03.27 |