AWS

[AWS] IAM

cc_blog 2026. 8. 3. 20:58
[Cloud Computing] AWS IAM 완전 정리 — 동작 방식까지 전부
CLOUD COMPUTING · SECURITY

AWS IAM

"누가, 무엇을, 어디에" 할 수 있는지를 결정하는 AWS의 심장부. 정책 JSON 구조부터 평가 로직, Role·AssumeRole·STS 동작 원리, Permission Boundary·SCP, Federation까지 — 어디에도 없는 완전판.

CategoryLevelReadsStatus
Cloud Computing · Security중급 ~ 고급약 28분VERIFIED
Part 1
IAM 기초
개념 · 왜 필요한가 · 핵심 구성요소
01 · Concept

IAM(Identity and Access Management)이란?

IAM은 "누가(Identity) 무엇을(Action) 어떤 리소스에(Resource) 할 수 있는지"를 정의하고 통제하는 AWS의 인증·인가 서비스다.

AWS의 모든 API 호출 — EC2를 켜는 것도, S3 버킷을 읽는 것도, 심지어 IAM 정책 자체를 바꾸는 것도 — 은 예외 없이 IAM을 거쳐 "이 요청을 허용할 것인가"를 판정받는다. IAM을 정확히 이해하지 못하면 AWS의 다른 모든 서비스를 아무리 잘 알아도 보안 사고 한 번에 무너질 수 있다 — 실제 클라우드 침해 사고의 상당수가 기술 취약점이 아니라 잘못 설정된 IAM 권한에서 시작된다.

02 · Motivation

왜 필요한가

IAM이 없다면 계정에 접근하는 모든 사람·서비스가 루트 계정 수준의 무제한 권한을 갖거나, 반대로 권한을 아예 나눌 방법이 없다. IAM은 이 극단 사이에서 최소 권한 원칙(Principle of Least Privilege) — 딱 필요한 만큼만, 필요한 기간만 권한을 부여하는 것을 실현하는 도구다.

사람에 대한 통제

개발자는 개발 환경만, 재무팀은 결제 정보만, 운영팀은 프로덕션 인프라만 — 조직 내 역할에 맞게 권한을 세분화한다.

서비스에 대한 통제

EC2가 S3를 읽어야 한다면, 그 EC2에게 딱 그 권한만 부여한다. 자격증명을 코드에 하드코딩할 필요가 없어진다.

03 · Core Components

핵심 구성요소 4가지

User Group Role Policy (JSON 문서) 소속 맡음(Assume) 연결(Attach)
User·Group은 사람/조직 단위, Role은 "빌려 쓰는" 임시 신원, Policy가 실제 권한의 내용
User

고정된 자격증명(비밀번호, Access Key)을 갖는 영구적인 신원. 사람이나 애플리케이션이 직접 로그인·API 호출에 사용한다.

Group

User들을 묶는 컨테이너. Group에 Policy를 붙이면 소속된 모든 User가 그 권한을 상속받는다. Group 자체는 로그인할 수 없다.

Role

고정 자격증명이 없는 "임시로 맡아 쓰는" 신원. 사람, 서비스, 다른 계정 누구나 조건을 만족하면 이 Role을 맡아(Assume) 그 권한을 임시로 빌려 쓸 수 있다.

Policy

"무엇을 허용/거부할지"를 정의한 JSON 문서. User·Group·Role 어디에도 붙일 수 있는 권한의 실제 내용물이다.

실무 원칙 AWS는 User에 Policy를 직접 붙이지 말고 Group을 통해서, 그리고 가능하면 사람도 User보다 Role(Federation)을 쓰라고 권장한다. 장기 고정 자격증명(Access Key)은 유출 시 만료가 없어 가장 큰 리스크이기 때문이다. 뒤에서 다룰 Role 중심 설계가 사실상 현대 AWS 보안의 기본값이다.
Part 2
정책과 평가 로직
JSON 구조 · 정책 유형 · 아무도 제대로 안 알려주는 평가 순서
04 · Policy Structure

Policy 구조 완전 분해

모든 IAM Policy는 JSON 문서이며, 구조는 항상 같은 골격을 따른다.

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

Allow 또는 Deny 딱 둘뿐이다. 이 값이 없는 "허용도 거부도 아닌" 상태는 존재하지 않는다.

Action

대상 API 동작. s3:GetObject처럼 서비스:동작 형식이며, 와일드카드(s3:Get*)도 가능하다.

Resource

대상 리소스의 ARN. Identity-based Policy에서는 생략 불가하며, 어떤 리소스에 적용될지 명시해야 한다.

Condition

추가 조건. IP 대역, MFA 사용 여부, 시간대 등으로 권한을 더 세밀하게 제한한다. 실무 보안 강화의 핵심 도구다.

Principal

"누구에게"를 명시하는 필드. Identity-based Policy에는 없고(붙는 대상 자체가 Principal이므로), Resource-based Policy와 Trust Policy에서만 등장한다.

05 · Policy Types

Policy 유형

구분AWS ManagedCustomer ManagedInline
관리 주체AWS내 계정내 계정
재사용여러 신원에 재사용여러 신원에 재사용단 하나의 신원 전용
버전 관리AWS가 업데이트직접 버전 관리(최대 5개)없음(즉시 반영)
권장 상황빠른 시작, 표준 권한조직 특화 재사용 정책이 신원에만 필요한 예외적 권한

또한 정책이 어디에 붙느냐로도 나뉜다 — User·Group·Role에 붙는 Identity-based Policy와, S3 버킷·SQS 큐 등 리소스 자체에 붙는 Resource-based Policy(대표적으로 S3 Bucket Policy)다. Resource-based Policy는 유일하게 다른 계정의 Principal을 직접 지정할 수 있어, 크로스 계정 접근의 또 다른 축이 된다.

06 · Evaluation Logic

정책 평가 로직 — 가장 중요한데 아무도 제대로 안 알려주는 것

한 사람에게 여러 정책이 동시에 적용되는 건 흔한 일이다. 여러 정책이 서로 다른 결론을 내릴 때 AWS는 정확히 다음 순서로 판정한다.

요청 발생 적용 가능한 정책 중 명시적 Deny가 하나라도 있는가? YES 최종 DENY NO 적용 가능한 정책 중 명시적 Allow가 하나라도 있는가? YES 최종 ALLOW NO 묵시적(Implicit) DENY — 기본값은 항상 거부
명시적 Deny 최우선 → 명시적 Allow → 아무 매칭도 없으면 기본은 항상 거부(묵시적 Deny)
① 명시적 Deny 최우선

어떤 정책이든 하나라도 명시적으로 Deny하면, 다른 모든 정책이 Allow여도 최종 결과는 무조건 거부다. Deny는 항상 이긴다.

② 명시적 Allow

Deny가 하나도 없다면, 적용되는 모든 정책 중 하나라도 Allow하면 허용된다. 여러 정책의 Allow는 합집합으로 누적된다.

③ 묵시적 Deny (기본값)

어떤 정책도 명시적으로 언급하지 않은 Action은 기본적으로 항상 거부다. AWS IAM은 "화이트리스트" 모델이다 — 허용을 명시해야만 열린다.

실전에서 가장 헷갈리는 지점 Permission Policy가 Allow여도, Permission Boundary나 SCP에서 Deny하면 최종 결과는 거부다. 즉 평가는 "붙어있는 모든 정책 종류(Identity-based + Resource-based + Boundary + SCP)를 통틀어" 이뤄지며, 그 안에서 Deny 최우선 원칙이 관통한다. 이 부분은 뒤(10~11장)에서 Boundary·SCP를 다룬 뒤 다시 정리한다.
07 · Role & AssumeRole
ROLE

Role과 AssumeRole 동작 방식

Role은 두 개의 서로 다른 정책을 동시에 갖는다는 점이 User와 결정적으로 다르다.

Trust Policy (신뢰 정책)

"누가 이 Role을 맡을 수 있는가"를 정의. Role 자체에 붙는 Resource-based Policy의 일종이며, Principal 필드로 허용할 대상(계정, 서비스, 사용자 등)을 명시한다.

Permission Policy (권한 정책)

"이 Role을 맡으면 무엇을 할 수 있는가"를 정의. User·Group에 붙이는 것과 동일한 형태의 Identity-based Policy다.

호출자 (User/서비스/타계정) STS Trust Policy 검증 후 임시 자격증명 발급 임시 자격증명 AccessKey+Secret +SessionToken sts:AssumeRole 이후 모든 API 호출은 이 임시 자격증명 + Role의 Permission Policy로 평가됨 기본 유효기간 1시간(최대 12시간), 만료되면 다시 발급받아야 함
AssumeRole = STS가 Trust Policy를 검증하고 임시 자격증명을 발급하는 과정
// Trust Policy 예시: 특정 계정의 특정 Role만 이 Role을 맡을 수 있음
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::111122223333:role/CI-Deployer" },
    "Action": "sts:AssumeRole",
    "Condition": { "StringEquals": { "sts:ExternalId": "unique-shared-secret" } }
  }]
}
TERM STS (Security Token Service)

임시 자격증명을 발급하는 AWS 서비스. AssumeRole, Federation 로그인, EC2 Instance Profile 모두 내부적으로 STS가 임시 자격증명을 찍어낸다.

08 · Cross-Account Access

크로스 계정 접근 패턴

여러 AWS 계정을 운영하는 조직(대부분의 엔터프라이즈)에서 A 계정 사용자가 B 계정 리소스에 접근하는 대표 패턴이다.

Role Assumption 방식

B 계정에 Role을 만들고 Trust Policy에 A 계정을 Principal로 등록. A 계정 사용자가 sts:AssumeRole로 B 계정 Role을 맡아 임시 자격증명으로 작업한다. 가장 표준적인 방식이다.

Resource-based Policy 방식

S3 Bucket Policy처럼 리소스 자체의 정책에 A 계정 Principal을 직접 허용. Role을 거치지 않고 바로 접근 가능하지만, 지원하는 리소스 타입이 제한적이다.

TERM External ID

제3자(다른 회사 등)에게 Role을 내줄 때, Trust Policy 조건에 추가하는 공유 비밀값. "혼동된 대리인(Confused Deputy)" 공격 — 제3자가 의도치 않게 다른 고객의 리소스에 접근하게 되는 상황 — 을 막기 위한 표준 대응책이다.

09 · Instance Profile

EC2가 Role을 쓰는 방식 — Instance Profile

EC2에 Access Key를 박아 넣지 않고도 AWS API를 호출할 수 있는 이유가 Instance Profile이다. EC2에 Role을 연결하면, 인스턴스 내부에서 메타데이터 서비스(IMDS)를 통해 임시 자격증명을 자동으로 받아 쓴다.

// EC2 내부에서 실행하면 자동 발급된 임시 자격증명 확인 가능
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME

이 자격증명은 자동으로 주기적으로 회전(Rotate)되며, SDK·CLI가 별도 설정 없이 이를 자동으로 사용한다 — 코드에 자격증명을 하드코딩할 이유가 없어지는 근본적인 이유다.

보안 참고 IMDSv1은 SSRF(서버 측 요청 위조) 공격으로 메타데이터 자격증명이 탈취된 사례가 있어, IMDSv2(세션 토큰 기반)를 강제하는 것이 현재 표준 권장사항이다.
10 · Permission Boundary

Permission Boundary — 권한의 상한선

Permission Boundary는 "이 신원이 최대로 가질 수 있는 권한의 천장"을 정의하는 특수한 정책이다. 일반 Permission Policy와 절대 혼동하면 안 된다 — 이 둘은 AND 연산으로 결합된다.

Permission Policy

"이 신원에게 무엇을 허용할지"를 직접 부여하는 정책.

Permission Boundary

"Permission Policy가 아무리 관대해도, 절대 이 선을 넘을 수 없다"는 상한선.

실제 유효 권한은 Permission Policy ∩ Permission Boundary(교집합)다. 예를 들어 Boundary가 S3만 허용한다면, Permission Policy에 EC2 전체 권한이 있어도 EC2 호출은 여전히 거부된다.

TERM 위임 권한 관리(Delegated Administration)

Permission Boundary의 대표 활용 사례. 팀 리더에게 "팀원의 IAM Role을 만들 권한"을 주되, Boundary로 "관리자 권한까지 부여하는 Role은 못 만들게" 제한해 권한 상승(Privilege Escalation)을 원천 차단한다.

11 · Service Control Policy

SCP (Service Control Policy) — 조직 전체 가드레일

SCP는 AWS Organizations 레벨에서 계정 전체(또는 OU 단위)에 적용되는 최상위 가드레일이다. Permission Boundary가 "신원 하나"의 상한선이라면, SCP는 "계정 전체"의 상한선이다.

구분Permission BoundarySCP
적용 범위개별 User/Role계정 전체 / OU
관리 주체계정 내에서 설정Organizations 관리 계정에서 설정
루트 계정에도 적용?아니오예 (루트 계정도 못 벗어남)
Allow 자체를 부여?아니오(상한선만)아니오(상한선만)
// SCP 예시: 특정 리전 외 모든 리전 사용 차단
{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": { "aws:RequestedRegion": ["ap-northeast-2"] }
  }
}
평가 로직 최종 정리 결국 최종 권한은 SCP ∩ Permission Boundary ∩ (Identity-based Policy ∪ Resource-based Policy 중 명시적 Allow, 단 어디든 명시적 Deny가 있으면 즉시 거부)다. 이 전체 그림을 한 번에 이해하면 IAM 트러블슈팅의 8할은 끝난 것이다.
12 · Federation

Identity Federation

모든 사람에게 IAM User를 만들어주는 대신, 이미 있는 신원 체계(사내 AD, 구글, 소셜 로그인 등)를 그대로 활용해 AWS 권한을 위임하는 방식이다. 내부적으로는 전부 STS의 AssumeRoleWithSAML / AssumeRoleWithWebIdentity를 거친다.

SAML 2.0 Federation

사내 Active Directory, Okta 같은 기업용 IdP와 연동. 임직원이 사내 계정 그대로 로그인해 매핑된 Role로 AWS 콘솔에 접근한다.

OIDC / Web Identity

구글, Amazon 같은 OIDC 제공자로 로그인한 사용자에게 Role을 매핑. 모바일·웹 앱에서 최종 사용자에게 임시 AWS 권한을 주는 Amazon Cognito Identity Pool이 대표적 구현체다.

IAM Identity Center

구 AWS SSO. 여러 AWS 계정과 외부 SaaS 앱까지 하나의 로그인으로 통합 관리하는 AWS의 사내 SSO 서비스. Organizations와 결합해 조직 전체 접근을 중앙화한다.

13 · MFA & Credential Hygiene

MFA, Access Key, 루트 계정 보안

권장 관행
  • 루트 계정은 MFA를 반드시 활성화하고, 일상 작업에는 절대 사용하지 않음
  • 사람의 콘솔 접근은 Federation/IAM Identity Center로, User+비밀번호 최소화
  • 불가피하게 Access Key를 쓴다면 정기적으로 교체(Rotate)
  • 민감한 작업(삭제, 정책 변경 등)에는 Condition으로 MFA 필수화
흔한 실수
  • Access Key를 코드/저장소에 하드코딩
  • 모든 사람에게 AdministratorAccess 관리형 정책을 붙임
  • 루트 계정으로 일상 업무 수행
  • 오래된 미사용 자격증명을 방치
Part 3
실전 적용
최소 권한 실천 · 실습 가이드 · 안티패턴
14 · Least Privilege in Practice

최소 권한을 실제로 실천하는 법

원칙은 쉽지만 "정확히 필요한 권한"을 처음부터 알기는 어렵다. AWS는 이를 돕는 도구를 제공한다.

IAM Access Analyzer

실제 CloudTrail 활동 로그를 분석해 "이 Role이 지난 N일간 실제로 쓴 Action"만으로 최소 권한 정책 초안을 자동 생성해준다.

Policy Simulator

정책을 실제로 적용하기 전에 "이 요청이 허용될지 거부될지"를 시뮬레이션해서 미리 검증할 수 있다.

실무 순서: 처음엔 넓은 권한으로 시작 → Access Analyzer로 실제 사용 패턴 수집 → 사용된 Action만으로 정책을 좁혀 재배포 → 반복. "처음부터 완벽한 최소 권한"을 손으로 짜려 하기보다, 이렇게 점진적으로 좁혀가는 방식이 실무에서 훨씬 현실적이다.

15 · Hands-on Guide

실습 가이드 — EC2용 Role 생성부터 검증까지

"EC2가 특정 S3 버킷만 읽을 수 있게" 만드는 가장 흔한 시나리오로 처음부터 끝까지 따라가 본다.

1

Customer Managed Policy 생성

IAM 콘솔 → Policies → Create policy → JSON 탭에서 04장 구조를 참고해 s3:GetObject, s3:ListBucket만 특정 버킷 ARN으로 한정한 정책을 작성하고 저장(예: S3ReadOnly-MyBucket).

2

Role 생성 & 신뢰 대상 지정

IAM 콘솔 → Roles → Create role → Trusted entity type은 AWS service → Use case는 EC2 선택. 이 과정에서 AWS가 ec2.amazonaws.com을 Principal로 하는 Trust Policy를 자동 생성해준다.

3

Permission Policy 연결

1단계에서 만든 S3ReadOnly-MyBucket 정책을 검색해 체크 → Role 이름 지정(예: EC2-S3Reader-Role) → Create role.

4

EC2에 Role 연결

EC2 콘솔에서 인스턴스 선택 → Actions → Security → Modify IAM role → 3단계 Role 선택. 기존 실행 중인 인스턴스에도 재부팅 없이 즉시 적용된다.

5

검증

해당 EC2에 접속해 aws s3 ls s3://my-bucket/ 실행 — 성공해야 한다. 이어서 aws s3 rm s3://my-bucket/some-file 시도 — AccessDenied가 떠야 정상이다(쓰기 권한을 주지 않았으므로, 06장의 묵시적 Deny가 여기서 실제로 작동하는 것을 확인하는 것).

트러블슈팅 예상과 다르게 거부된다면 확인 순서는 이렇다 — ① Permission Policy에 해당 Action이 있는가 ② Resource ARN이 정확히 일치하는가 ③ Condition이 현재 상황과 맞는가 ④ Permission Boundary·SCP에 상충되는 Deny가 없는가. 06장·11장의 평가 순서를 그대로 거꾸로 따라가면 대부분 원인이 잡힌다.
16 · Anti-patterns

자주 하는 실수

피해야 할 패턴
  • "Action": "*", "Resource": "*"를 습관적으로 붙이는 것
  • User에 정책을 직접 붙이고 Group을 아예 안 쓰는 것
  • Trust Policy의 Principal을 "*"(모든 계정)로 열어두는 것
  • Permission Boundary·SCP 존재를 모른 채 Identity-based Policy만 붙였다 왜 안 되는지 못 찾는 것
  • 장기 Access Key를 발급받아 로컬 PC나 코드에 계속 방치
대신 이렇게
  • 필요한 Action·Resource를 구체적으로 명시
  • Group 또는 Role 기반으로 권한을 부여
  • Trust Policy는 항상 구체적인 Principal + Condition으로 좁히기
  • Boundary·SCP까지 포함한 전체 평가 그림을 항상 염두에 두기
  • 가능하면 항상 Role(임시 자격증명)로 대체
17 · Wrap-up

정리

IAM은 결국 하나의 질문으로 요약된다 — "이 요청, 정말 허용해도 되는가?" User·Group·Role·Policy로 신원과 권한을 구성하고, 명시적 Deny 최우선 → 명시적 Allow → 기본 거부라는 평가 순서 위에서, Permission Boundary와 SCP라는 상한선까지 겹겹이 얹은 것이 AWS IAM의 전체 그림이다. 이 흐름 하나만 정확히 그릴 수 있으면, 어떤 복잡한 권한 문제도 "지금 어느 단계에서 막히고 있는가"로 항상 분해해서 풀 수 있다.

CLOUD COMPUTING BLOG IAM · ROLE · POLICY · STS · SCP