IAM Role은 "누가 이 권한을 사용할 수 있는가"를 정의하고, IAM Policy는 "어떤 작업을 허용하거나 거부하는가"를 정의합니다. 이 두 가지를 분리해서 설계해야 권한 관리가 확장 가능해집니다.
핵심 요약
- IAM Policy는 "무엇을 할 수 있는가"를 JSON으로 정의한 권한 규칙입니다.
- IAM Role은 "누가 이 권한을 사용할 수 있는가"를 정의한 자격 증명 컨테이너입니다.
- Policy는 Role에 연결(Attach)되어야 실제로 동작합니다. Policy 단독으로는 아무 효과가 없습니다.
- Role은 사람이 아닌 서비스(EC2, Lambda 등)에도 권한을 부여할 수 있는 유일한 방법입니다.
- 실무에서는 Policy를 재사용 가능한 단위로 설계하고, Role을 통해 필요한 주체에 조합하여 연결합니다.
1. 왜 구분이 필요한가
개발자 3명이 있는 팀에서 S3 버킷에 접근해야 하는 상황을 생각해봅니다.
방법 1: 각 개발자의 IAM User에 직접 S3 권한을 붙입니다. 개발자가 10명으로 늘어나면 10번 반복해야 합니다. 권한을 변경하려면 10명 모두 수정해야 합니다.
방법 2: "S3 읽기 권한"이라는 Policy를 하나 만들고, "개발자 Role"에 연결합니다. 개발자가 늘어나도 Role만 부여하면 됩니다. 권한 변경은 Policy 하나만 수정하면 전체에 반영됩니다.
이 차이가 Policy와 Role을 분리하는 이유입니다. Policy는 권한의 내용을, Role은 권한의 주체를 관리합니다.
2. IAM Policy란 무엇인가
2.1 한 줄 정의
IAM Policy는 "어떤 리소스에 어떤 작업을 허용하거나 거부하는가"를 JSON 형식으로 정의한 권한 규칙 문서입니다.
2.2 Policy의 구조
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-app-bucket",
"arn:aws:s3:::my-app-bucket/*"
]
}
]
}
| 필드 | 설명 |
|---|---|
| Effect | Allow 또는 Deny |
| Action | 허용/거부할 AWS API 작업 |
| Resource | 대상 리소스의 ARN |
| Condition | 조건부 적용 (선택) |
2.3 Policy의 종류
| 종류 | 설명 | 관리 주체 |
|---|---|---|
| AWS Managed Policy | AWS가 미리 만들어 제공하는 정책 | AWS |
| Customer Managed Policy | 사용자가 직접 작성하는 정책 | 사용자 |
| Inline Policy | 특정 User/Role/Group에 직접 내장된 정책 | 사용자 |
AWS Managed Policy는 빠르게 시작할 때 유용하지만, 운영 환경에서는 필요 이상의 권한이 포함된 경우가 많습니다. Customer Managed Policy로 최소 권한을 직접 정의하는 것이 보안 관점에서 적합합니다.
3. IAM Role이란 무엇인가
3.1 한 줄 정의
IAM Role은 "특정 주체가 임시로 맡을(Assume) 수 있는 자격 증명"입니다. Role 자체에는 권한이 없고, Policy를 연결해야 권한이 생깁니다.
3.2 Role의 두 가지 구성 요소
Role은 두 가지 정책으로 구성됩니다.
| 구성 요소 | 역할 | 질문 |
|---|---|---|
| Trust Policy | 누가 이 Role을 맡을 수 있는가 | "Who can assume this role?" |
| Permission Policy | 이 Role을 맡으면 무엇을 할 수 있는가 | "What can this role do?" |
Trust Policy 예시 (EC2가 이 Role을 맡을 수 있도록 허용):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
3.3 Role의 핵심 특성

- 임시 자격 증명: Role을 Assume하면 STS(Security Token Service)가 임시 토큰을 발급합니다. 만료 시간이 있어 장기 노출 위험이 줄어듭니다.
- 교차 계정 접근: 다른 AWS 계정의 리소스에 접근할 때 Role을 사용합니다.
- 서비스 간 권한 위임: EC2, Lambda, ECS 등 AWS 서비스가 다른 서비스에 접근할 때 Role이 유일한 방법입니다.
4. Role과 Policy의 관계

두 개념의 관계를 정리하면 다음과 같습니다.
| 기준 | IAM Policy | IAM Role |
|---|---|---|
| 정의 | 권한 규칙 문서 | 자격 증명 컨테이너 |
| 질문 | "무엇을 할 수 있는가?" | "누가 이 권한을 사용하는가?" |
| 단독 동작 | 불가 (연결 대상 필요) | 불가 (Policy 없으면 권한 없음) |
| 연결 대상 | User, Group, Role | User, Service, 다른 Account |
| 재사용 | 여러 Role/User에 연결 가능 | 여러 주체가 Assume 가능 |
| 비유 | 출입증에 적힌 권한 목록 | 출입증 자체 |
핵심 관계: Policy는 Role에 연결되어야 의미가 있고, Role은 Policy가 있어야 권한이 생깁니다.
5. 실무 사용 사례
사례 1: EC2에서 S3 접근
EC2 인스턴스에서 S3 버킷의 파일을 읽어야 하는 상황입니다.
잘못된 방법: EC2 안에 IAM User의 Access Key를 환경 변수로 넣습니다. 키가 유출되면 영구적으로 악용될 수 있습니다.
올바른 방법: EC2에 IAM Role을 연결합니다.
# 1. S3 읽기 Policy 생성
aws iam create-policy \
--policy-name S3ReadOnlyAppBucket \
--policy-document file://s3-read-policy.json
# 2. EC2용 Role 생성 (Trust Policy에 ec2.amazonaws.com 지정)
aws iam create-role \
--role-name EC2-S3Reader \
--assume-role-policy-document file://ec2-trust-policy.json
# 3. Policy를 Role에 연결
aws iam attach-role-policy \
--role-name EC2-S3Reader \
--policy-arn arn:aws:iam::123456789012:policy/S3ReadOnlyAppBucket
# 4. EC2 Instance Profile에 Role 연결
aws iam create-instance-profile --instance-profile-name EC2-S3Reader-Profile
aws iam add-role-to-instance-profile \
--instance-profile-name EC2-S3Reader-Profile \
--role-name EC2-S3Reader
이 구조에서 EC2는 임시 토큰으로 S3에 접근합니다. 토큰은 자동 갱신되며, 인스턴스 외부에서는 사용할 수 없습니다.
사례 2: Lambda에서 DynamoDB 접근
Lambda 함수가 DynamoDB 테이블에 데이터를 쓰는 상황입니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:ap-northeast-2:123456789012:table/Orders"
}
]
}
이 Policy를 Lambda Execution Role에 연결하면, Lambda는 Orders 테이블에만 쓰기 작업을 수행할 수 있습니다. 다른 테이블이나 읽기 작업은 거부됩니다.
사례 3: 교차 계정 접근
개발 계정(111111111111)의 개발자가 운영 계정(222222222222)의 S3 버킷을 읽어야 하는 상황입니다.
운영 계정에서 Role 생성 (Trust Policy):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "dev-team-access-2026"
}
}
}
]
}
개발 계정의 개발자가 이 Role을 Assume하면 운영 계정의 리소스에 임시로 접근할 수 있습니다. ExternalId 조건을 추가하면 의도하지 않은 계정에서의 접근을 방지할 수 있습니다.
6. 설계 패턴과 의사결정
6.1 Policy 설계 원칙
| 원칙 | 설명 |
|---|---|
| 최소 권한 | 필요한 Action과 Resource만 명시 |
| 리소스 한정 | * 대신 구체적인 ARN 사용 |
| 조건 활용 | IP, 시간, MFA 등 조건으로 범위 제한 |
| 분리 설계 | 하나의 Policy에 하나의 책임 |
6.2 Role 설계 원칙
| 원칙 | 설명 |
|---|---|
| 서비스별 분리 | EC2용, Lambda용, ECS용 Role을 각각 생성 |
| 환경별 분리 | dev, staging, prod Role을 분리 |
| Trust Policy 최소화 | Assume할 수 있는 주체를 최소한으로 제한 |
| 세션 시간 제한 | MaxSessionDuration을 업무에 맞게 설정 |
6.3 User 직접 권한 vs Role 기반 권한
| 기준 | User 직접 연결 | Role 기반 |
|---|---|---|
| 관리 편의성 | 인원 증가 시 관리 부담 증가 | Role 단위로 일괄 관리 |
| 보안 | 영구 자격 증명 (Access Key) | 임시 자격 증명 (STS Token) |
| 서비스 적용 | 불가 (User는 사람 전용) | 가능 (EC2, Lambda 등) |
| 교차 계정 | 불가 | 가능 |
| 권장 상황 | 거의 없음 | 대부분의 운영 환경 |
운영 환경에서는 IAM User에 직접 Policy를 연결하는 방식보다 Role 기반 접근을 권장합니다. AWS는 2022년 7월에 AWS SSO를 IAM Identity Center로 리브랜딩하면서, 임시 자격 증명 기반의 Role 접근을 기본 권장 방식으로 안내하고 있습니다.
7. 보안 고려사항
IAM 설계에서 가장 흔한 보안 사고는 과도한 권한 부여와 장기 자격 증명 노출입니다. 아래 원칙을 기본으로 적용하는 것이 좋습니다.
- Access Key 사용 최소화: EC2, Lambda 등 AWS 서비스에서는 Role을 사용합니다. Access Key는 외부 시스템 연동 등 불가피한 경우에만 사용하고, 주기적으로 교체합니다.
*권한 금지:"Action": "*"또는"Resource": "*"는 운영 환경에서 사용하지 않습니다. 초기 개발 시에도 범위를 좁혀가는 것이 좋습니다.- MFA 조건 추가: 민감한 작업(IAM 변경, 리소스 삭제 등)에는 MFA 조건을 Policy에 추가합니다.
- CloudTrail 감사: 누가 어떤 Role을 Assume했는지, 어떤 API를 호출했는지 CloudTrail로 기록하고 모니터링합니다.
- Permission Boundary: 위임된 관리자가 자신보다 높은 권한을 부여하지 못하도록 경계를 설정합니다.
8. 비용/운영 고려사항
IAM 자체는 무료 서비스이지만, 잘못된 IAM 설계는 간접적으로 비용 사고를 유발할 수 있습니다.
| 항목 | 설명 |
|---|---|
| IAM 서비스 비용 | 무료 (User, Role, Policy 생성에 비용 없음) |
| 비용 사고 위험 | 과도한 권한으로 의도치 않은 리소스 생성/삭제 가능 |
| 감사 비용 | CloudTrail 로그 저장 시 S3/CloudWatch 비용 발생 |
| 운영 부담 | Policy/Role이 많아지면 관리 복잡도 증가 |
운영 관점:
- IAM Access Analyzer를 활용하면 사용하지 않는 권한을 식별할 수 있습니다.
- Policy 수가 많아지면 태그 기반 관리와 명명 규칙이 중요해집니다.
- AWS 계정당 Customer Managed Policy는 기본 1,500개, Role은 기본 1,000개까지 생성할 수 있습니다. Service Quotas를 통해 상한 증가를 요청할 수 있습니다.
9. 자주 하는 실수
- EC2에 Access Key를 하드코딩하는 것: IAM Role을 사용하면 키 관리가 필요 없습니다. 키가 코드에 포함되면 Git 저장소를 통해 유출될 수 있습니다.
- AdministratorAccess를 개발용으로 사용하는 것: 개발 환경에서도 필요한 서비스만 허용하는 Policy를 사용하는 것이 좋습니다. 실수로 운영 리소스를 삭제하는 사고를 방지할 수 있습니다.
- Inline Policy를 남용하는 것: Inline Policy는 재사용이 불가능하고 관리가 어렵습니다. Customer Managed Policy를 만들어 연결하는 것이 유지보수에 유리합니다.
- Trust Policy를 너무 넓게 설정하는 것:
"Principal": {"AWS": "*"}는 모든 AWS 계정에서 Role을 Assume할 수 있게 됩니다. 반드시 특정 계정이나 서비스로 제한해야 합니다. - Policy 변경 시 영향 범위를 확인하지 않는 것: 하나의 Policy가 여러 Role에 연결되어 있을 수 있습니다. 변경 전
aws iam list-entities-for-policy명령으로 영향 범위를 확인합니다.
10. 정리
- IAM Policy는 "무엇을 할 수 있는가"를 정의하는 권한 규칙입니다.
- IAM Role은 "누가 이 권한을 사용하는가"를 정의하는 자격 증명 컨테이너입니다.
- Policy는 Role에 연결되어야 동작하고, Role은 Policy가 있어야 의미가 있습니다.
- 운영 환경에서는 User 직접 권한보다 Role 기반 접근이 보안과 관리 측면에서 적합합니다.
- 최소 권한 원칙, 임시 자격 증명, 감사 로그가 IAM 보안의 핵심입니다.
참고 문서
'Security' 카테고리의 다른 글
| DevSecOps란 무엇인가: CI/CD에 보안을 통합하는 방법 (0) | 2026.06.07 |
|---|---|
| GitHub Actions에서 Secret을 안전하게 관리하는 방법 (0) | 2026.06.06 |
| IAM과 RBAC 차이: AWS, Azure, GCP 기준으로 이해하기 (0) | 2026.06.05 |
| 클라우드 보안 기본 원칙: 최소 권한, 네트워크 격리, 감사 로그 (0) | 2026.05.28 |