AWS IAM 이해하기
개요
AWS IAM(Identity and Access Management)은 AWS 리소스에 대한 접근을 안전하게 관리하는 서비스입니다. IAM을 사용하면 “누가(Who) 무엇을(What) 할 수 있는지”를 정의하여 AWS 환경의 보안을 제어할 수 있습니다.
이 가이드를 읽고 나면 IAM의 핵심 개념을 이해하고, 실제 프로젝트에서 어떻게 활용할 수 있는지 알게 됩니다.
배경
왜 IAM이 필요한가?
AWS 계정을 처음 만들면 루트 사용자(Root User) 계정이 생성됩니다. 이 계정은 AWS의 모든 리소스와 서비스에 무제한 접근 권한을 가집니다.
하지만 실무에서는 다음과 같은 문제가 발생합니다:
문제 1: 보안 위험
상황: 개발팀 5명이 모두 루트 계정 비밀번호를 공유
위험: 누군가 실수로 프로덕션 데이터베이스를 삭제할 수 있음문제 2: 권한 관리 불가
상황: 인턴 개발자도 결제 정보를 볼 수 있음
위험: 민감한 정보 유출 가능문제 3: 추적 불가능
상황: 누가 EC2 인스턴스를 삭제했는지 알 수 없음
위험: 장애 발생 시 원인 파악 어려움IAM은 이러한 문제를 해결합니다.
IAM 등장 이전의 방식
IAM이 없던 시절에는:
- 하나의 루트 계정을 여러 사람이 공유
- 접근 권한을 세분화할 수 없음
- 누가 무엇을 했는지 추적 불가능
- 보안 사고 발생 시 피해 범위가 광범위
핵심 개념
IAM은 크게 4가지 핵심 요소로 구성됩니다.
1. 사용자 (User)
정의: AWS 리소스에 접근하는 개별 개인 또는 애플리케이션
실제 사용 예시:
회사 상황:
- 개발자 김철수 → IAM 사용자 "kim.chulsoo"
- 개발자 이영희 → IAM 사용자 "lee.younghee"
- CI/CD 시스템 → IAM 사용자 "github-actions"특징:
- 각 사용자는 고유한 자격 증명(비밀번호 또는 액세스 키)을 가짐
- 개인별로 다른 권한을 부여할 수 있음
- 사용자의 모든 활동이 로그로 기록됨
2. 그룹 (Group)
정의: 여러 사용자를 묶어서 관리하는 논리적 집합
실제 사용 예시:
그룹 구조:
┌─────────────────┐
│ Developers │ → 개발 환경 접근 권한
│ - kim.chulsoo │
│ - lee.younghee │
└─────────────────┘
┌─────────────────┐
│ Admins │ → 전체 시스템 관리 권한
│ - admin.park │
└─────────────────┘
┌─────────────────┐
│ ReadOnly │ → 읽기 전용 권한
│ - intern.choi │
└─────────────────┘장점:
- 사용자를 일일이 관리할 필요 없음
- 신규 입사자를 해당 그룹에 추가하면 자동으로 권한 부여
- 권한 변경 시 그룹만 수정하면 됨
3. 역할 (Role)
정의: 임시로 권한을 부여받을 수 있는 자격 증명
사용자 vs 역할의 차이:
사용자 (User):
- 특정 개인이나 애플리케이션에 영구적으로 할당
- 장기 자격 증명 (비밀번호, 액세스 키)
- 예: 개발자 김철수
역할 (Role):
- 필요할 때 임시로 맡는 권한
- 단기 자격 증명 (임시 토큰)
- 예: EC2 인스턴스, Lambda 함수4. 정책 (Policy)
정의: 권한을 JSON 형식으로 정의한 문서
정책의 구조:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow", // 허용 또는 거부
"Action": "s3:GetObject", // 수행할 수 있는 작업
"Resource": "arn:aws:s3:::my-bucket/*" // 대상 리소스
}
]
}동작 원리
IAM의 작동 흐름
┌─────────────┐
│ 사용자 │
│ (kim.chulsoo)│
└──────┬──────┘
│
│ 1. "S3 버킷 목록을 보여줘" 요청
↓
┌─────────────────────┐
│ IAM 평가 엔진 │
│ │
│ 1. 사용자 확인 │ → 김철수가 맞는지 인증
│ 2. 정책 확인 │ → 어떤 권한을 가지고 있는지 조회
│ 3. 권한 평가 │ → S3 목록 조회 권한이 있는지 확인
│ 4. 결정 │ → 허용 또는 거부
└──────┬──────────────┘
│
│ 2. 허용/거부 응답
↓
┌─────────────┐
│ AWS 서비스 │
│ (S3) │ → 허용된 경우에만 버킷 목록 반환
└─────────────┘권한 평가 순서
IAM은 다음 순서로 권한을 평가합니다:
1. 기본적으로 모든 요청은 거부(Deny)
2. 명시적 허용(Allow) 확인
→ 정책에 "Effect": "Allow"가 있는지 확인
3. 명시적 거부(Deny) 확인
→ 정책에 "Effect": "Deny"가 있으면 무조건 거부
→ Deny는 Allow보다 우선순위가 높음
4. 최종 결정
→ Deny가 하나라도 있으면 거부
→ Allow만 있으면 허용
→ 아무것도 없으면 거부주요 특징
특징 1: 최소 권한 원칙 (Principle of Least Privilege)
사용자에게 작업 수행에 필요한 최소한의 권한만 부여하는 것이 안전합니다.
❌ 나쁜 예:
모든 개발자에게 관리자 권한 부여
→ 누구나 프로덕션 리소스 삭제 가능
✅ 좋은 예:
- 주니어 개발자: 개발 환경만 접근
- 시니어 개발자: 개발 + 스테이징 환경 접근
- DevOps 팀: 전체 환경 관리 권한특징 2: 정책 상속
그룹에 정책을 할당하면, 해당 그룹의 모든 사용자가 권한을 상속받습니다.
예시:
┌──────────────────┐
│ Developers 그룹 │
│ │
│ 정책: │
│ - EC2 읽기 │ ─┐
│ - S3 쓰기 │ │
└──────────────────┘ │
│ 상속
┌─────────────┴─────────────┐
│ │
┌─────────┐ ┌─────────┐
│김철수 │ │이영희 │
│ │ │ │
│권한: │ │권한: │
│- EC2 읽기│ │- EC2 읽기│
│- S3 쓰기 │ │- S3 쓰기 │
└─────────┘ └─────────┘특징 3: 멀티 팩터 인증 (MFA)
추가 보안 계층으로 MFA를 활성화할 수 있습니다.
MFA 없이:
1. 사용자명 + 비밀번호만으로 로그인
→ 비밀번호 유출 시 계정 탈취 가능
MFA 사용:
1. 사용자명 + 비밀번호 입력
2. 스마트폰 앱에서 생성된 6자리 코드 입력
→ 비밀번호를 알아도 물리적 기기 없이는 로그인 불가특징 4: 임시 자격 증명
역할을 사용하면 임시 자격 증명이 자동으로 발급됩니다.
임시 자격 증명의 장점:
1. 자동 만료 (보통 1~12시간)
2. 정기적으로 자동 갱신
3. 키 관리 불필요
4. 유출되어도 짧은 시간 후 무효화
영구 자격 증명 (액세스 키):
1. 수동으로 삭제할 때까지 유효
2. 하드코딩하거나 파일에 저장하면 유출 위험
3. 정기적으로 교체해야 함실제 사용 사례
사례 1: 스타트업 팀 권한 구조
회사 구조:
- CEO (1명)
- CTO (1명)
- 백엔드 개발자 (3명)
- 프론트엔드 개발자 (2명)
- 디자이너 (1명)
IAM 구조:
┌─────────────────┐
│ Admins 그룹 │ ← CEO, CTO
│ - 모든 권한 │
└─────────────────┘
┌─────────────────┐
│ Backend 그룹 │ ← 백엔드 개발자 3명
│ - EC2 관리 │
│ - RDS 관리 │
│ - Lambda 관리 │
└─────────────────┘
┌─────────────────┐
│ Frontend 그룹 │ ← 프론트엔드 개발자 2명
│ - S3 관리 │
│ - CloudFront 관리│
└─────────────────┘
┌─────────────────┐
│ Designers 그룹 │ ← 디자이너 1명
│ - S3 읽기만 │
└─────────────────┘사례 2: Lambda 함수의 S3 접근
시나리오:
이미지 업로드 시 자동으로 썸네일을 생성하는 Lambda 함수
구현:
1. "ThumbnailGeneratorRole" 역할 생성
2. 역할에 정책 할당:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::my-images/*",
"arn:aws:s3:::my-thumbnails/*"
]
},
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "*"
}
]
}-
Lambda 함수에 역할 할당
-
Lambda가 자동으로 임시 자격 증명을 받아 S3 접근
### 사례 3: CI/CD 파이프라인 권한
시나리오: GitHub Actions가 자동으로 프론트엔드를 빌드하여 S3에 배포
구현:
-
“GitHubActionsDeployRole” 역할 생성
-
GitHub Actions가 OIDC로 역할을 맡도록 설정:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/main"
}
}
}
]
}- 배포 권한 정책:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"cloudfront:CreateInvalidation"
],
"Resource": [
"arn:aws:s3:::my-website/*",
"arn:aws:cloudfront::123456789012:distribution/EDFDVBD6EXAMPLE"
]
}
]
}장점:
- 액세스 키를 GitHub Secrets에 저장할 필요 없음
- 임시 자격 증명 자동 관리
- 특정 브랜치에서만 배포 가능하도록 제한
## 장점과 한계
### 장점
✅ **세밀한 권한 제어**
- 사용자, 그룹, 역할별로 다른 권한 부여 가능
- 리소스 단위까지 권한 제어 가능
- 시간, IP, MFA 등 조건부 접근 제어
✅ **보안 강화**
- 루트 계정 사용 최소화
- MFA로 추가 보안 계층 제공
- 임시 자격 증명으로 키 관리 부담 감소
✅ **감사 및 규정 준수**
- 모든 작업이 CloudTrail에 로그로 기록됨
- "누가, 언제, 무엇을" 했는지 추적 가능
- 규정 준수 요구사항 충족
✅ **비용 효율성**
- IAM 자체는 무료
- 불필요한 리소스 생성/삭제 방지로 비용 절감
✅ **확장성**
- 수천 명의 사용자 관리 가능
- 여러 AWS 계정 통합 관리 가능
### 한계
⚠️ **학습 곡선**
- 처음 접하는 개발자에게는 개념이 복잡할 수 있음
- 정책 작성에 JSON 지식 필요
- 권한 설정 실수 시 디버깅이 어려움
⚠️ **정책 복잡도**
- 여러 정책이 중첩될 경우 예상치 못한 결과 발생 가능
- Deny 우선 원칙을 이해하지 못하면 권한 문제 발생
⚠️ **관리 부담**
- 사용자/그룹/역할이 많아지면 관리 복잡도 증가
- 퇴사자 권한 회수, 정기적 권한 검토 필요
⚠️ **완벽하지 않은 보안**
- IAM 설정이 잘못되면 여전히 보안 위험 존재
- 사회공학 공격, 피싱 등 다른 공격 벡터 존재
### 트레이드오프
**언제 복잡한 IAM 구조를 사용해야 하는가?**
✅ 복잡한 IAM 구조 권장:
- 팀 규모가 5명 이상
- 프로덕션 환경 운영
- 규정 준수 요구사항 존재
- 여러 AWS 계정 관리
⚠️ 단순한 IAM 구조 권장:
- 개인 프로젝트 또는 소규모 팀 (1-3명)
- 개발/테스트 환경만 사용
- 빠른 프로토타이핑 필요
## 모범 사례
### 1. 루트 계정 보호
절대 하지 말아야 할 것: ❌ 루트 계정으로 일상 작업 수행 ❌ 루트 계정 액세스 키 생성 ❌ 루트 계정 공유
반드시 해야 할 것: ✅ 루트 계정에 MFA 활성화 ✅ 강력한 비밀번호 설정 ✅ 루트 계정은 초기 설정과 긴급 상황에만 사용 ✅ IAM 사용자를 만들어 일상 작업 수행
### 2. 최소 권한 원칙 적용
단계적 권한 부여:
1단계: 읽기 전용 권한 부여 2단계: 개발 환경에서 쓰기 권한 부여 3단계: 검증 후 스테이징 환경 권한 부여 4단계: 필요 시에만 프로덕션 권한 부여
예시: // 신입 개발자 권한 1주차: ReadOnlyAccess 2주차: DevelopmentEnvironmentAccess 1개월 후: StagingEnvironmentAccess 3개월 후: ProductionReadOnlyAccess
### 3. 역할 우선 사용
❌ 피해야 할 패턴: EC2에 액세스 키 저장 → 키 관리 부담, 유출 위험
✅ 권장 패턴: EC2에 역할 할당 → 자동 자격 증명 관리, 안전함
### 4. 정책 버전 관리
정책 변경 시 베스트 프랙티스:
- 현재 정책 백업
- 새 정책 버전 생성
- 개발 환경에서 테스트
- 문제 없으면 프로덕션 적용
- 문제 발생 시 이전 버전으로 롤백
AWS는 정책의 최대 5개 버전을 보관합니다.
### 5. 정기적인 권한 검토
월간 체크리스트:
- 사용하지 않는 IAM 사용자 비활성화
- 90일 이상 미사용 액세스 키 삭제
- 퇴사자 권한 회수 확인
- 과도한 권한을 가진 사용자 검토
도구 활용:
- IAM Access Analyzer: 의도하지 않은 외부 접근 탐지
- AWS IAM Credential Report: 자격 증명 사용 현황 확인
## 관련 개념
### 유사 개념
**AWS Organizations**
- **IAM**: 단일 AWS 계정 내 권한 관리
- **Organizations**: 여러 AWS 계정을 계층 구조로 관리
- 사용 예: 개발, 스테이징, 프로덕션을 별도 계정으로 분리
**AWS SSO (Single Sign-On)**
- **IAM**: AWS 콘솔 및 프로그래밍 방식 접근 제어
- **SSO**: 여러 AWS 계정과 비즈니스 애플리케이션에 단일 로그인
- 사용 예: Google Workspace 계정으로 AWS 로그인
**AWS STS (Security Token Service)**
- **IAM**: 영구 자격 증명 관리
- **STS**: 임시 자격 증명 발급
- 사용 예: 역할을 맡을 때 STS가 임시 토큰 생성
## 일반적인 실수와 해결 방법
### 실수 1: 와일드카드 과다 사용
```json
❌ 위험한 정책:
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
// 모든 서비스의 모든 작업 허용 → 보안 위험
✅ 안전한 정책:
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-specific-bucket/*"
}
// 특정 버킷의 특정 작업만 허용실수 2: 액세스 키를 코드에 하드코딩
❌ 절대 하지 말 것:
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
region: 'ap-northeast-2'
});
// 키가 GitHub에 올라가면 즉시 공격 대상
✅ 올바른 방법:
// 1. 환경변수 사용
const AWS = require('aws-sdk');
// AWS SDK가 자동으로 환경변수에서 자격 증명 로드
// 2. EC2/Lambda의 경우 역할 사용
// 별도 설정 없이 자동으로 임시 자격 증명 사용트러블슈팅
문제 1: “Access Denied” 오류
증상:
An error occurred (AccessDenied) when calling the PutObject operation:
Access Denied원인 및 해결:
1. IAM 정책 확인
→ IAM Policy Simulator로 권한 시뮬레이션
https://policysim.aws.amazon.com/
2. 리소스 정책 확인 (S3 Bucket Policy 등)
→ IAM 정책과 리소스 정책 모두 허용해야 함
3. 서비스 제어 정책(SCP) 확인
→ Organizations의 SCP가 차단하는지 확인
4. 권한 경계(Permission Boundary) 확인
→ 사용자/역할에 권한 경계가 설정되었는지 확인문제 2: 역할을 맡을 수 없음
증상:
User: arn:aws:iam::123456789012:user/developer is not authorized
to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/MyRole원인 및 해결:
1. 역할의 신뢰 관계 확인
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/developer"
},
"Action": "sts:AssumeRole"
}
2. 사용자에게 AssumeRole 권한 부여
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789012:role/MyRole"
}학습 리소스
공식 문서
실습 도구
- IAM Policy Simulator - 정책 테스트
- IAM Access Analyzer - 외부 접근 분석
학습 경로
- 기초: IAM 사용자 생성, 그룹 할당
- 중급: 사용자 정의 정책 작성, 역할 생성
- 고급: 교차 계정 접근, OIDC 통합, 권한 경계
다음 단계
IAM 개념을 이해했다면:
- 실습: 개인 AWS 계정에서 IAM 사용자 및 그룹 생성
- 정책 작성: 간단한 S3 또는 EC2 정책 직접 작성
- 역할 활용: Lambda 함수에 역할 할당 실습
- 보안 강화: MFA 활성화, 액세스 키 교체 자동화
요약
IAM의 핵심:
- 사용자: 개별 개인 또는 애플리케이션
- 그룹: 사용자를 묶어서 관리
- 역할: 임시 권한을 부여받는 자격 증명
- 정책: JSON으로 정의된 권한
기억해야 할 원칙:
- 루트 계정은 보호하고 사용 최소화
- 최소 권한 원칙 적용
- 역할을 우선적으로 사용
- 정기적으로 권한 검토
- MFA로 보안 강화
IAM의 가치:
- 세밀한 접근 제어
- 보안 강화
- 감사 추적
- 확장 가능한 권한 관리
IAM을 제대로 이해하고 활용하면 안전하고 확장 가능한 AWS 환경을 구축할 수 있습니다.