AWS IAM 완벽 가이드
IAM(Identity and Access Management)은 AWS 리소스에 대한 액세스를 안전하게 제어하는 서비스다. 누가(인증) 무엇을(권한) 할 수 있는지 관리한다.
IAM이란?
핵심 기능
| 기능 | 설명 |
|---|---|
| 인증 (Authentication) | 사용자가 누구인지 확인 |
| 권한 부여 (Authorization) | 어떤 작업을 할 수 있는지 결정 |
| 액세스 관리 | 리소스별 세밀한 권한 제어 |
| 연합 자격 증명 | 외부 ID 공급자 연동 |
특징
- 글로벌 서비스 (리전 선택 불필요)
- 무료 서비스
- 최종 일관성 모델 (변경사항 전파에 시간 소요)
- AWS 계정과 통합
핵심 구성 요소
1. 사용자 (User)
AWS에 액세스하는 개인 또는 애플리케이션을 나타낸다.
사용자 = 자격 증명 + 권한
자격 증명 유형:
| 유형 | 용도 |
|---|---|
| 콘솔 암호 | AWS Management Console 로그인 |
| 액세스 키 (Access Key + Secret Key) | CLI, SDK, API 호출 |
# AWS CLI 자격 증명 설정
aws configure
# AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
# AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Default region name: ap-northeast-2
# Default output format: json
2. 그룹 (Group)
사용자의 집합. 그룹에 정책을 연결하면 모든 그룹 구성원에게 권한이 적용된다.
개발팀 그룹
├── 개발자 A (User)
├── 개발자 B (User)
└── 개발자 C (User)
↓
S3, EC2 접근 정책 적용
특징:
- 사용자는 여러 그룹에 속할 수 있음
- 그룹은 다른 그룹을 포함할 수 없음 (중첩 불가)
- 기본 그룹 없음 (명시적 생성 필요)
3. 역할 (Role)
AWS 서비스나 외부 사용자가 임시로 권한을 얻기 위해 사용한다.
역할 = 신뢰 정책 + 권한 정책
사용 사례:
| 시나리오 | 설명 |
|---|---|
| EC2 → S3 | EC2 인스턴스가 S3에 접근 |
| Lambda → DynamoDB | Lambda 함수가 DynamoDB 접근 |
| 교차 계정 | 다른 AWS 계정의 리소스 접근 |
| 연합 자격 증명 | 외부 사용자(Google, SAML)가 AWS 접근 |
// 신뢰 정책 (Trust Policy) - 누가 이 역할을 맡을 수 있는가
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
4. 정책 (Policy)
권한을 정의하는 JSON 문서. 어떤 리소스에 어떤 작업을 허용/거부할지 명시한다.
정책 (Policy) 상세
정책 구조
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3Read",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.168.1.0/24"
}
}
}
]
}
정책 요소
| 요소 | 필수 | 설명 |
|---|---|---|
| Version | O | 정책 언어 버전 (“2012-10-17” 권장) |
| Statement | O | 권한 명세 배열 |
| Sid | X | 문장 식별자 |
| Effect | O | Allow 또는 Deny |
| Action | O | 허용/거부할 작업 |
| Resource | O | 대상 리소스 ARN |
| Condition | X | 조건부 적용 |
| Principal | * | 정책 적용 대상 (리소스 기반 정책) |
정책 유형
1. 자격 증명 기반 정책 (Identity-based)
사용자, 그룹, 역할에 연결
// 관리형 정책 - AWS 제공 또는 고객 생성
// 인라인 정책 - 특정 자격 증명에 직접 포함
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
2. 리소스 기반 정책 (Resource-based)
S3 버킷, SQS 큐 등 리소스에 직접 연결
// S3 버킷 정책 예시
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/alice"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
정책 평가 로직
1. 기본적으로 모든 요청은 거부 (암시적 거부)
2. 명시적 Allow가 있으면 허용
3. 명시적 Deny가 있으면 무조건 거부 (Allow보다 우선)
요청
↓
명시적 Deny 있음?
↙ ↘
Yes No
↓ ↓
거부 명시적 Allow 있음?
↙ ↘
Yes No
↓ ↓
허용 거부
AWS 관리형 정책
자주 사용되는 AWS 제공 정책
| 정책 이름 | 설명 |
|---|---|
| AdministratorAccess | 모든 AWS 리소스 전체 권한 |
| PowerUserAccess | IAM 제외 모든 서비스 권한 |
| ReadOnlyAccess | 모든 리소스 읽기 전용 |
| AmazonS3FullAccess | S3 전체 권한 |
| AmazonS3ReadOnlyAccess | S3 읽기 전용 |
| AmazonEC2FullAccess | EC2 전체 권한 |
| AmazonRDSFullAccess | RDS 전체 권한 |
| AWSLambdaBasicExecutionRole | Lambda 기본 실행 (CloudWatch Logs) |
실전 정책 예시
EC2 특정 리전만 허용
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-northeast-2"
}
}
}
]
}
특정 태그가 있는 리소스만 접근
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Environment": "Development"
}
}
}
]
}
S3 특정 버킷 + 폴더 접근
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringLike": {
"s3:prefix": ["home/${aws:username}/*"]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-bucket/home/${aws:username}/*"
}
]
}
MFA 필수 정책
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
역할 (Role) 활용
EC2 인스턴스 프로파일
EC2가 다른 AWS 서비스에 접근할 때 사용
# 1. 역할 생성 (AWS Console 또는 CLI)
aws iam create-role \
--role-name EC2-S3-Access \
--assume-role-policy-document file://trust-policy.json
# 2. 정책 연결
aws iam attach-role-policy \
--role-name EC2-S3-Access \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# 3. 인스턴스 프로파일 생성
aws iam create-instance-profile \
--instance-profile-name EC2-S3-Access-Profile
# 4. 역할을 인스턴스 프로파일에 추가
aws iam add-role-to-instance-profile \
--instance-profile-name EC2-S3-Access-Profile \
--role-name EC2-S3-Access
# 5. EC2 인스턴스에 연결
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=EC2-S3-Access-Profile
Lambda 실행 역할
// 신뢰 정책
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
교차 계정 접근
계정 A의 S3 버킷을 계정 B 사용자가 접근
// 계정 A: S3 버킷 정책
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_B_ID:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::shared-bucket",
"arn:aws:s3:::shared-bucket/*"
]
}
]
}
// 계정 B: 사용자 정책
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::shared-bucket",
"arn:aws:s3:::shared-bucket/*"
]
}
]
}
보안 모범 사례
1. 루트 계정 보호
- 루트 계정 사용 최소화
- MFA 활성화 필수
- 액세스 키 생성 금지
- 강력한 암호 사용
2. 최소 권한 원칙
- 필요한 권한만 부여
- 와일드카드(*) 사용 최소화
- 정기적인 권한 검토
3. MFA (Multi-Factor Authentication)
# 가상 MFA 디바이스 활성화
aws iam enable-mfa-device \
--user-name alice \
--serial-number arn:aws:iam::123456789012:mfa/alice \
--authentication-code1 123456 \
--authentication-code2 789012
4. 암호 정책 설정
aws iam update-account-password-policy \
--minimum-password-length 14 \
--require-symbols \
--require-numbers \
--require-uppercase-characters \
--require-lowercase-characters \
--allow-users-to-change-password \
--max-password-age 90 \
--password-reuse-prevention 12
5. 액세스 키 관리
# 액세스 키 나열
aws iam list-access-keys --user-name alice
# 액세스 키 비활성화
aws iam update-access-key \
--user-name alice \
--access-key-id AKIAIOSFODNN7EXAMPLE \
--status Inactive
# 액세스 키 삭제
aws iam delete-access-key \
--user-name alice \
--access-key-id AKIAIOSFODNN7EXAMPLE
# 90일 이상 사용하지 않은 키 조회
aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 -d
IAM Access Analyzer
외부에서 접근 가능한 리소스를 분석하고 보안 위험을 식별한다.
# Access Analyzer 생성
aws accessanalyzer create-analyzer \
--analyzer-name my-analyzer \
--type ACCOUNT
# 분석 결과 조회
aws accessanalyzer list-findings \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-2:123456789012:analyzer/my-analyzer
분석 대상:
- S3 버킷
- IAM 역할
- KMS 키
- Lambda 함수
- SQS 큐
- Secrets Manager
AWS CLI 주요 명령어
사용자 관리
# 사용자 생성
aws iam create-user --user-name alice
# 사용자 목록
aws iam list-users
# 사용자 삭제
aws iam delete-user --user-name alice
# 콘솔 암호 설정
aws iam create-login-profile \
--user-name alice \
--password "P@ssw0rd123!" \
--password-reset-required
# 액세스 키 생성
aws iam create-access-key --user-name alice
그룹 관리
# 그룹 생성
aws iam create-group --group-name Developers
# 사용자를 그룹에 추가
aws iam add-user-to-group --user-name alice --group-name Developers
# 그룹에서 사용자 제거
aws iam remove-user-from-group --user-name alice --group-name Developers
정책 관리
# 정책 생성
aws iam create-policy \
--policy-name MyPolicy \
--policy-document file://policy.json
# 정책 연결 (사용자)
aws iam attach-user-policy \
--user-name alice \
--policy-arn arn:aws:iam::123456789012:policy/MyPolicy
# 정책 연결 (그룹)
aws iam attach-group-policy \
--group-name Developers \
--policy-arn arn:aws:iam::123456789012:policy/MyPolicy
# 정책 연결 (역할)
aws iam attach-role-policy \
--role-name MyRole \
--policy-arn arn:aws:iam::123456789012:policy/MyPolicy
역할 관리
# 역할 생성
aws iam create-role \
--role-name MyRole \
--assume-role-policy-document file://trust-policy.json
# 역할 맡기 (Assume Role)
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/MyRole \
--role-session-name my-session
IAM 정책 시뮬레이터
정책이 예상대로 동작하는지 테스트한다.
# CLI로 정책 시뮬레이션
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/alice \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::my-bucket/file.txt
웹 콘솔: https://policysim.aws.amazon.com/
STS (Security Token Service)
임시 보안 자격 증명을 발급한다.
# 임시 자격 증명 획득
aws sts get-session-token \
--duration-seconds 3600 \
--serial-number arn:aws:iam::123456789012:mfa/alice \
--token-code 123456
# 현재 자격 증명 확인
aws sts get-caller-identity
반환 값:
{
"Credentials": {
"AccessKeyId": "ASIAXXX...",
"SecretAccessKey": "xxx...",
"SessionToken": "xxx...",
"Expiration": "2024-01-02T12:00:00Z"
}
}
정리
| 구성 요소 | 설명 |
|---|---|
| 사용자 (User) | 개인 또는 애플리케이션의 AWS 자격 증명 |
| 그룹 (Group) | 사용자 집합, 정책 일괄 적용 |
| 역할 (Role) | 임시 권한, 서비스/교차 계정 접근 |
| 정책 (Policy) | 권한 정의 JSON 문서 |
핵심 원칙
1. 루트 계정 사용 금지
2. MFA 활성화
3. 최소 권한 원칙
4. 역할 사용 우선 (액세스 키 대신)
5. 정기적인 자격 증명 교체
6. Access Analyzer로 모니터링
IAM은 AWS 보안의 기초다. 잘못된 IAM 설정은 심각한 보안 사고로 이어질 수 있으니 신중하게 관리하자.
댓글