[AWS] Identity and Access Management (IAM) - 심화

silver's avatar
Nov 28, 2025
[AWS] Identity and Access Management (IAM) - 심화

IAM

IAM(Identity and Access Management)은 AWS 리소스에 대한 접근을 안전하게 관리하는 서비스입니다. 사용자 인증과 권한 부여를 통해 보안을 유지하면서도 필요한 사람에게 필요한 권한을 부여할 수 있습니다.

IAM의 핵심 원칙

  • 최소 권한 원칙 (Least Privilege): 필요한 최소한의 권한만 부여
  • 권한 분리 (Separation of Duties): 한 사람에게 모든 권한 집중 방지
  • 정기적인 권한 검토: 불필요한 권한은 즉시 제거
  • 강력한 인증: MFA(다중 인증) 활성화

IAM의 특징

  • 무료: IAM 사용에 추가 비용 없음
  • 글로벌 서비스: 모든 리전에 적용
  • 세밀한 권한 제어: 리소스 단위까지 제어 가능
  • AWS 서비스 통합: 모든 AWS 서비스와 연동

👥 IAM의 주요 구성 요소

1. 사용자 (Users)

개별 사용자를 나타내는 엔티티

사용자 생성 예제

# IAM 사용자 생성 aws iam create-user --user-name john-developer # 로그인 프로파일 생성 (콘솔 접근) aws iam create-login-profile \ --user-name john-developer \ --password 'MySecurePassword123!' \ --password-reset-required # 프로그래밍 방식 접근을 위한 액세스 키 생성 aws iam create-access-key --user-name john-developer

사용자 유형

  • 루트 사용자: AWS 계정 생성 시 자동으로 생성 (사용 최소화 권장)
  • IAM 사용자: 개별 사용자를 위해 생성하는 계정
  • 페더레이션 사용자: 외부 인증 시스템을 통해 접근

2. 그룹 (Groups)

사용자들의 집합으로, 권한 관리를 단순화
# 그룹 생성 aws iam create-group --group-name Developers # 그룹에 정책 연결 aws iam attach-group-policy \ --group-name Developers \ --policy-arn arn:aws:iam::aws:policy/PowerUserAccess # 사용자를 그룹에 추가 aws iam add-user-to-group \ --user-name john-developer \ --group-name Developers

그룹 관리 모범 사례

  • 역할별로 그룹 생성 (예: Developers, Admins, Analysts)
  • 사용자에게 직접 권한 부여보다 그룹 활용
  • 그룹 네이밍 규칙 정의

3. 역할 (Roles)

AWS 리소스나 서비스가 다른 AWS 서비스에 접근할 때 사용하는 자격 증명

역할의 종류

  • 서비스 역할: EC2, Lambda 등 AWS 서비스용
  • 교차 계정 역할: 다른 AWS 계정의 리소스 접근
  • 웹 ID 역할: 소셜 로그인 사용자용
  • SAML 2.0 페더레이션: 기업 ID 시스템 연동
# EC2용 역할 생성 aws iam create-role \ --role-name EC2-S3-Access-Role \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" }] }' # 역할에 정책 연결 aws iam attach-role-policy \ --role-name EC2-S3-Access-Role \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess # EC2 인스턴스 프로파일 생성 및 연결 aws iam create-instance-profile \ --instance-profile-name EC2-S3-Profile aws iam add-role-to-instance-profile \ --instance-profile-name EC2-S3-Profile \ --role-name EC2-S3-Access-Role

4. 정책 (Policies)

권한을 정의하는 JSON 문서

정책 유형

  • AWS 관리형 정책: AWS에서 미리 정의한 정책
  • 고객 관리형 정책: 사용자가 직접 생성한 정책
  • 인라인 정책: 특정 사용자/그룹/역할에 직접 연결

정책 예제

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowS3BucketAccess", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-company-bucket", "arn:aws:s3:::my-company-bucket/*" ], "Condition": { "IpAddress": { "aws:SourceIp": "203.0.113.0/24" } } } ] }

📋 정책 평가 로직

IAM 정책 평가 순서

AWS는 다음 순서로 권한을 평가
  1. 기본 거부 (Default Deny): 모든 요청은 기본적으로 거부
  1. 명시적 허용 (Explicit Allow): Allow가 있으면 허용
  1. 명시적 거부 (Explicit Deny): Deny가 있으면 최종 거부
┌─────────────────────────────────────┐ │ 1. 기본적으로 모든 요청 거부 │ └──────────────┬──────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 2. Allow 정책이 있는가? │ │ YES → 허용 (다음 단계로) │ │ NO → 거부 (종료) │ └──────────────┬──────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ 3. Deny 정책이 있는가? │ │ YES → 거부 (종료) │ │ NO → 허용 (종료) │ └─────────────────────────────────────┘

정책 우선순위

Explicit Deny > Explicit Allow > Default Deny
// 예제: 특정 사용자만 S3 삭제 권한 거부 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": "*" }, { "Effect": "Deny", "Action": "s3:DeleteObject", "Resource": "*", "Condition": { "StringNotEquals": { "aws:username": "admin" } } } ] }

🔍 Resource-based Policies vs IAM Roles

차이점 비교

구분
IAM Roles
Resource-based Policies
연결 대상
사용자, 서비스
리소스 (S3, SQS 등)
권한 부여 방식
역할 assume 필요
직접 리소스 접근
교차 계정 접근
원본 권한 포기
원본 권한 유지
사용 사례
EC2, Lambda 등
S3 버킷 공유, SNS 토픽

Resource-based Policy 예제

// S3 버킷 정책: 다른 계정에 읽기 권한 부여 { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCrossAccountRead", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-shared-bucket", "arn:aws:s3:::my-shared-bucket/*" ] } ] }

IAM Role vs Resource-based Policy 선택 가이드

IAM Role 사용할 때
  • 임시 자격 증명이 필요할 때
  • 서비스 간 권한 위임 (EC2 → S3)
  • 교차 계정 접근 (감사 로그 필요)
Resource-based Policy 사용 시기:
  • 여러 계정에서 동일 리소스 접근
  • 원본 계정 권한 유지 필요
  • 간단한 권한 부여

🎫 AWS IAM Identity Center (구 AWS SSO)

Identity Center

AWS IAM Identity Center는 여러 AWS 계정과 애플리케이션에 대한 중앙 집중식 접근 관리를 제공

주요 기능

1. 단일 로그인 (SSO)

  • 하나의 자격 증명으로 모든 AWS 계정 접근
  • SAML 2.0 기반 통합
  • Microsoft AD, Okta, Azure AD 연동

2. 다중 계정 관리

# AWS Organizations와 통합 aws sso-admin create-account-assignment \ --instance-arn arn:aws:sso:::instance/ssoins-1234 \ --target-id 123456789012 \ --target-type AWS_ACCOUNT \ --permission-set-arn arn:aws:sso:::permissionSet/ps-5678 \ --principal-type USER \ --principal-id user-id-9012

3. 권한 세트 (Permission Sets)

// 개발자용 권한 세트 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:*", "s3:*", "rds:Describe*" ], "Resource": "*" }, { "Effect": "Deny", "Action": [ "ec2:TerminateInstances", "rds:DeleteDBInstance" ], "Resource": "*" } ] }

Identity Center 아키텍처

┌─────────────────────────────────────────────┐ │ AWS IAM Identity Center │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ Identity Source │ │ │ │ - AWS Managed Microsoft AD │ │ │ │ - External IdP (Okta, Azure AD) │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ Permission Sets │ │ │ │ - Admin Access │ │ │ │ - Developer Access │ │ │ │ - Read-Only Access │ │ │ └─────────────────────────────────────┘ │ └──────────────────┬──────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ AWS Organizations │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Account │ │ Account │ │ Account │ │ │ │ Prod │ │ Dev │ │ Test │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └──────────────────────────────────────────────┘

🏢 AWS Directory Services

Directory Services 유형

1. AWS Managed Microsoft AD

  • 완전 관리형 Active Directory
  • 온프레미스 AD와 신뢰 관계 설정 가능
  • MFA 지원
# Managed Microsoft AD 생성 aws ds create-microsoft-ad \ --name corp.example.com \ --password YourSecurePassword \ --description "Corporate AD" \ --vpc-settings VpcId=vpc-123,SubnetIds=subnet-123,subnet-456

2. AD Connector

  • 온프레미스 AD를 AWS에 연결
  • 사용자 복제 없이 프록시 역할
  • 비용 효율적

3. Simple AD

  • 독립형 디렉터리
  • Linux Samba 4 기반
  • 소규모 조직용

Directory Services 비교

기능
AWS Managed Microsoft AD
AD Connector
Simple AD
Active Directory 호환
완전 호환
프록시
기본 기능
온프레미스 연동
신뢰 관계
직접 연결
불가
사용자 수
수천~수만
제한 없음
~500
가격
높음
중간
낮음

🎮 AWS Control Tower

Control Tower

AWS Control Tower는 다중 계정 AWS 환경을 설정하고 관리하는 서비스입니다. "Landing Zone"을 자동으로 구성하여 모범 사례를 적용

주요 구성 요소

1. Landing Zone

  • 잘 설계된 다중 계정 환경
  • 자동화된 계정 프로비저닝
  • 중앙 집중식 로깅 및 보안

2. Guardrails

  • 예방적 가드레일: SCP로 구현, 작업 차단
  • 탐지 가드레일: Config 규칙으로 구현, 위반 감지
// 예방적 가드레일: 특정 리전만 허용 { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": [ "us-east-1", "eu-west-1" ] } } } ] }

3. Account Factory

  • 표준화된 계정 생성
  • 자동 베이스라인 구성
  • Service Catalog 통합

Control Tower 아키텍처

┌─────────────────────────────────────────────────┐ │ AWS Control Tower │ │ │ │ ┌────────────────────────────────────────┐ │ │ │ Management Account (루트) │ │ │ │ - Organizations │ │ │ │ - Control Tower 설정 │ │ │ └────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────┐ │ │ │ Security OU │ │ │ │ ├─ Log Archive Account (로그 저장) │ │ │ │ └─ Audit Account (보안 감사) │ │ │ └────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────┐ │ │ │ Production OU │ │ │ │ ├─ Production Account 1 │ │ │ │ └─ Production Account 2 │ │ │ └────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────┐ │ │ │ Development OU │ │ │ │ ├─ Dev Account 1 │ │ │ │ └─ Test Account 1 │ │ │ └────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘

Control Tower 가드레일 예제

# 탐지 가드레일: 암호화되지 않은 EBS 볼륨 감지 import boto3 def check_ebs_encryption(): ec2 = boto3.client('ec2') volumes = ec2.describe_volumes() non_compliant = [] for volume in volumes['Volumes']: if not volume.get('Encrypted', False): non_compliant.append(volume['VolumeId']) if non_compliant: print(f"Non-compliant volumes found: {non_compliant}") # SNS 알림 전송 sns = boto3.client('sns') sns.publish( TopicArn='arn:aws:sns:region:account:security-alerts', Subject='Unencrypted EBS Volumes Detected', Message=f'Volumes: {", ".join(non_compliant)}' )

💡 IAM 모범 사례

1. 루트 계정 보호

# MFA 활성화 확인 aws iam get-account-summary | grep AccountMFAEnabled # 루트 계정 액세스 키 삭제 확인 aws iam get-account-summary | grep AccountAccessKeysPresent
루트 계정 사용 규칙:
  • ❌ 일상적인 작업에 사용 금지
  • ✅ MFA 필수 활성화
  • ✅ 강력한 비밀번호 설정
  • ✅ 액세스 키 생성 금지

2. 최소 권한 원칙

// ❌ 나쁜 예: 과도한 권한 { "Effect": "Allow", "Action": "*", "Resource": "*" } // ✅ 좋은 예: 필요한 권한만 { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::my-bucket/uploads/*" }

3. 정기적인 권한 검토

# 사용하지 않는 자격 증명 확인 aws iam generate-credential-report aws iam get-credential-report --query Content --output text | base64 -d > report.csv # 90일 이상 미사용 사용자 찾기 awk -F',' '$5 != "N/A" && $5 != "no_information" { cmd="date -d " $5 " +%s"; cmd | getline last_used; close(cmd); cmd="date +%s"; cmd | getline now; close(cmd); if ((now - last_used) > 7776000) print $1 }' report.csv

4. 역할 사용 우선

# ❌ 나쁜 예: EC2에 액세스 키 하드코딩 import boto3 s3 = boto3.client('s3', aws_access_key_id='AKIAIOSFODNN7EXAMPLE', aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' ) # ✅ 좋은 예: IAM 역할 사용 s3 = boto3.client('s3') # 인스턴스 역할 자동 사용

5. 정책 조건 활용

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": "*", "Condition": { "IpAddress": { "aws:SourceIp": ["203.0.113.0/24"] }, "DateGreaterThan": { "aws:CurrentTime": "2024-01-01T00:00:00Z" }, "DateLessThan": { "aws:CurrentTime": "2024-12-31T23:59:59Z" }, "Bool": { "aws:SecureTransport": "true" } } } ] }

6. IAM Access Analyzer 활용

# Access Analyzer 생성 aws accessanalyzer create-analyzer \ --analyzer-name MyOrgAnalyzer \ --type ORGANIZATION # 외부 접근 가능한 리소스 확인 aws accessanalyzer list-findings \ --analyzer-arn arn:aws:access-analyzer:region:account:analyzer/MyOrgAnalyzer \ --filter '{"status":{"eq":["ACTIVE"]}}'

🛡️ 보안 강화 팁

1. MFA 강제 정책

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyAllExceptListedIfNoMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:GetUser", "iam:ListMFADevices", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "sts:GetSessionToken" ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } } ] }

2. 암호 정책 설정

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 5

3. CloudTrail과 통합

# 의심스러운 IAM 활동 모니터링 import boto3 def monitor_iam_changes(): logs = boto3.client('logs') query = """ fields @timestamp, @message | filter eventName like /CreateUser|DeleteUser|AttachUserPolicy/ | filter userIdentity.type != "Root" | sort @timestamp desc """ response = logs.start_query( logGroupName='/aws/cloudtrail/logs', startTime=int((datetime.now() - timedelta(hours=1)).timestamp()), endTime=int(datetime.now().timestamp()), queryString=query )

📊 실전 시나리오

시나리오 1: 개발팀 권한 설정

#!/bin/bash # 1. 개발자 그룹 생성 aws iam create-group --group-name Developers # 2. 필요한 정책 연결 aws iam attach-group-policy \ --group-name Developers \ --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess aws iam attach-group-policy \ --group-name Developers \ --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess # 3. 프로덕션 리소스 보호 정책 추가 cat > deny-prod-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "StringEquals": { "aws:ResourceTag/Environment": "Production" } } } ] } EOF aws iam put-group-policy \ --group-name Developers \ --policy-name DenyProductionAccess \ --policy-document file://deny-prod-policy.json # 4. 개발자 추가 aws iam create-user --user-name john-dev aws iam add-user-to-group --user-name john-dev --group-name Developers

시나리오 2: 교차 계정 접근 설정

// Account A (신뢰하는 계정)에서 역할 생성 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT-B-ID:root" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "unique-external-id-12345" } } } ] }
# Account B에서 역할 assume aws sts assume-role \ --role-arn arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole \ --role-session-name session1 \ --external-id unique-external-id-12345

시나리오 3: 임시 자격 증명 발급

import boto3 from datetime import datetime, timedelta def generate_temporary_credentials(): sts = boto3.client('sts') # 임시 자격 증명 생성 (1시간 유효) response = sts.get_session_token( DurationSeconds=3600, SerialNumber='arn:aws:iam::123456789012:mfa/user', TokenCode='123456' # MFA 코드 ) credentials = response['Credentials'] return { 'AccessKeyId': credentials['AccessKeyId'], 'SecretAccessKey': credentials['SecretAccessKey'], 'SessionToken': credentials['SessionToken'], 'Expiration': credentials['Expiration'] } # 사용 예제 temp_creds = generate_temporary_credentials() # 임시 자격 증명으로 S3 클라이언트 생성 s3 = boto3.client('s3', aws_access_key_id=temp_creds['AccessKeyId'], aws_secret_access_key=temp_creds['SecretAccessKey'], aws_session_token=temp_creds['SessionToken'] )

🎓 IAM

  1. Q: 루트 사용자로 해야만 하는 작업은?
      • A: 계정 닫기, 결제 정보 변경, 지원 플랜 변경 등
  1. Q: IAM 역할과 IAM 사용자의 차이는?
      • A: 사용자는 영구 자격 증명, 역할은 임시 자격 증명 사용
  1. Q: Policy Evaluation Logic에서 최우선 규칙은?
      • A: Explicit Deny (명시적 거부)
  1. Q: IAM Identity Center의 주요 장점은?
      • A: 단일 로그인으로 여러 AWS 계정 접근 가능
  1. Q: AWS Control Tower의 핵심 구성 요소는?
      • A: Landing Zone, Guardrails, Account Factory

🔧 유용한 IAM 도구

1. IAM Policy Simulator

# 정책 시뮬레이션 aws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::123456789012:user/testuser \ --action-names s3:GetObject \ --resource-arns arn:aws:s3:::my-bucket/file.txt

2. IAM Policy Generator

웹 기반 도구로 GUI를 통해 정책 생성
  • URL: https://awspolicygen.s3.amazonaws.com/policygen.html

3. Parliament (정책 린터)

# Parliament 설치 pip install parliament # 정책 검증 parliament --file policy.json

4. CloudMapper (시각화)

# CloudMapper로 IAM 관계 시각화 git clone https://github.com/duo-labs/cloudmapper.git cd cloudmapper python cloudmapper.py collect python cloudmapper.py webserver

📚 참고 링크

AWS 공식 문서

보안 프레임워크


💡
IAM은 AWS 보안의 핵심이자 시작점으로 적절한 IAM 설정 없이는 안전한 AWS 환경을 구축할 수 없다
  • 최소 권한 원칙: 필요한 최소한의 권한만 부여
  • 역할 우선 사용: 액세스 키보다 IAM 역할 활용
  • 지속적인 모니터링: CloudTrail, Access Analyzer로 감시
  • 자동화: Control Tower, Identity Center로 대규모 관리
 
Share article

silver