[AWS] IAM: User, Role, Policy, STS
IAM, AWS IAM, IAM Role, IAM Policy, STS, AssumeRole, Identity Center, SSO
정의
IAM (Identity and Access Management) = AWS 의 권한 관리 전부. User, Group, Role, Policy 로 구성. “누가 어떤 리소스에 어떤 행동을 할 수 있는가” 를 정의.
사용 상황
| 상황 | IAM 사용 패턴 |
|---|---|
| 팀원 AWS 접근 권한 | Identity Center + Permission Set (SSO 권장) |
| EC2/Lambda 가 AWS 서비스 호출 | Instance Role / Execution Role |
| 다른 계정 리소스 접근 | Cross-account Role + AssumeRole |
| 외부 ID Provider | Federated Identity (OIDC, SAML) |
| 최소 권한 강제 | Permission Boundary |
| 조직 전체 정책 | Service Control Policy (SCP) |
| EKS Pod 의 AWS 접근 | IRSA (IAM Roles for Service Accounts) |
객체
flowchart LR
User["User<br/>(사람)"] -->|attach| Policy
Group[Group] -->|attach| Policy
Role["Role<br/>(임시 권한, EC2/Lambda/외부 등)"] -->|attach| Policy
Policy --> Statement[Effect: Allow/Deny<br/>Action: s3:GetObject<br/>Resource: arn:...]
| 객체 | 의미 |
|---|---|
| User | 사람 (long-term credentials, 가급적 최소화) |
| Group | User 묶음 (Policy 를 그룹에 부착) |
| Role | 임시 권한 받는 entity (EC2, Lambda, 외부 계정, EKS Pod 등) |
| Policy | 권한 표현 (JSON Statement 배열) |
Policy 구조
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListBucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "AllowReadObjects",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"IpAddress": { "aws:SourceIp": "10.0.0.0/8" }
}
}
]
}
Effect:Allow또는Deny. Explicit Deny 가 Allow 를 이김.Action:s3:GetObject,ec2:*형식.*와일드카드 가능.Resource: ARN.*로 전체 허용 (최소 권한 원칙 위반).Condition: 추가 조건 (IP, MFA 여부, 태그 등).
Policy 종류
| 종류 | 의미 |
|---|---|
| AWS Managed | AWS 가 관리 (AmazonS3ReadOnlyAccess) |
| Customer Managed | 사용자 정의, 재사용 가능 |
| Inline | User/Group/Role 에 직접 임베드 (재사용 불가) |
| Permission Boundary | 최대 권한 상한 (Role 이 가질 수 있는 최대) |
| Service Control Policy | Organization 수준 전체 상한 |
| Resource-based Policy | 자원에 붙음 (S3 Bucket Policy, Lambda Permission 등) |
| Session Policy | AssumeRole 시 임시로 줄이는 정책 |
권한 평가 알고리즘
flowchart TD
Q1{Explicit Deny?}
Q1 -->|예| Deny[DENY]
Q1 -->|아니오| Q2{Explicit Allow?}
Q2 -->|아니오| Deny
Q2 -->|예| Q3{SCP 차단?}
Q3 -->|예| Deny
Q3 -->|아니오| Q4{Permission Boundary 안?}
Q4 -->|아니오| Deny
Q4 -->|예| Allow[ALLOW]
Explicit Deny 가 모든 것을 이김. Organization SCP → Permission Boundary → Identity Policy 순으로 모두 통과해야 Allow.
Role 과 AssumeRole
sequenceDiagram
User->>STS: AssumeRole(arn:role/admin)
STS-->>User: temporary credentials (1h-12h)
User->>S3: API 호출 (임시 credentials)
aws sts assume-role \
--role-arn arn:aws:iam::123:role/admin \
--role-session-name my-session
| 사용 | 의미 |
|---|---|
| EC2 Role | EC2 가 metadata 로 자동 취득 |
| Lambda Role | 함수 실행 권한 |
| Cross-account | 다른 계정의 Role assume |
| 외부 ID + 신뢰 관계 | 3rd party (SaaS) 가 우리 계정 접근 |
| Federated (OIDC, SAML) | 외부 ID Provider 연동 |
임시 credentials = AccessKeyId + SecretAccessKey + SessionToken. 기본 1시간, 최대 12시간.
ABAC: Attribute-Based Access Control
태그 기반 동적 권한 부여. Role 을 늘리지 않고 태그로 접근 제어.
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Environment": "${aws:PrincipalTag/Environment}"
}
}
}
aws:PrincipalTag/Environment: 현재 호출자(Principal)의 태그.aws:ResourceTag/Environment: 대상 리소스의 태그.- 태그가 일치하는 리소스만 접근 허용.
장점: 새 EC2 인스턴스를 만들 때마다 Policy 수정 불필요. 태그만 맞으면 자동 허용.
Condition Keys 상세
| Key | 의미 |
|---|---|
aws:SourceIp | 요청 IP 대역 |
aws:RequestedRegion | 요청 리전 |
aws:MultiFactorAuthPresent | MFA 인증 여부 |
aws:SecureTransport | HTTPS 여부 |
aws:CurrentTime | 요청 시각 (업무 시간 외 차단) |
aws:PrincipalTag/Key | 호출자 태그 |
aws:ResourceTag/Key | 리소스 태그 |
iam:PermissionsBoundary | Permission Boundary ARN |
s3:prefix | S3 경로 prefix |
{
"Condition": {
"Bool": { "aws:MultiFactorAuthPresent": "true" },
"StringEquals": { "aws:RequestedRegion": ["ap-northeast-2"] }
}
}
IRSA / Pod Identity (EKS)
자세한 건 aws-eks.
IRSA (IAM Roles for Service Accounts): EKS Pod 가 AWS IAM Role 을 얻는 방법.
# ServiceAccount 에 annotation
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-reader
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123:role/s3-reader-role
- EKS 가 OIDC Provider 로 등록.
- Pod 의 ServiceAccount 에 IAM Role ARN annotation.
- Pod 기동 시 OIDC 토큰 주입.
- AWS SDK 가 토큰으로 AssumeRoleWithWebIdentity.
EKS Pod Identity (2023+): IRSA 보다 단순. OIDC Issuer 설정 없이 Pod 에 Role 직접 연결.
Identity Center (옛 SSO)
flowchart LR
User --> IC[AWS Identity Center]
IC --> Acct1[Account A]
IC --> Acct2[Account B]
IC --> Acct3[Account C]
IC -.SAML.-> Okta[Okta / Azure AD]
- Organization 의 통합 SSO.
- User 가 로그인 1회로 N 계정 접근.
- short-lived credentials (1시간).
- Permission Set = 각 계정에서의 권한 묶음.
- AD / Okta / Azure AD 연동 지원.
Access Analyzer
의도치 않은 외부 접근 자동 탐지.
| 분석 대상 | 탐지 예시 |
|---|---|
| S3 Bucket Policy | 퍼블릭 접근 허용 버킷 |
| IAM Role | 다른 계정 / 서비스가 assume 가능한 Role |
| KMS Key | 외부 공유 Key |
| SQS Queue | 외부 계정에서 메시지 전송 가능 |
| Lambda Permission | 외부 호출 허용 함수 |
aws accessanalyzer list-findings \
--analyzer-arn arn:aws:access-analyzer:...:analyzer/my-analyzer \
--filter '{"status": {"eq": ["ACTIVE"]}}'
IMPORTANT
Access Analyzer 는 신규 계정 생성 시 자동 활성화 권장. 설정 후 주기적 findings 리뷰.
Credential Report + Access Advisor
Credential Report (계정 전체)
aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 --decode
CSV 형식. 각 User 의 password 최근 사용, access key 최근 사용, MFA 활성화 여부 확인.
IAM Access Advisor (사용자별)
aws iam generate-service-last-accessed-details --arn arn:aws:iam::123:user/alice
aws iam get-service-last-accessed-details --job-id <id>
최근 사용 서비스 확인 → 미사용 권한 식별 → 최소 권한으로 축소.
Best Practice
✓ Root user 의 MFA + 일상 사용 금지 (Access Key 삭제)
✓ User 대신 SSO (Identity Center)
✓ Role 우선 (long-term credentials 회피)
✓ Least privilege (필요한 권한만, Access Advisor 로 미사용 제거)
✓ Permission Boundary 로 최대 권한 제한
✓ SCP 로 조직 전체 guardrail
✓ Access Analyzer 로 외부 접근 탐지
✓ MFA 강제 (Condition 으로 정책 적용)
✓ Credentials rotation 정기 (90일 이내)
✓ CloudTrail 로 모든 IAM 이벤트 감사
흔한 함정
WARNING
- Root user 의 access key = 누출 = 모든 권한 탈취. 즉시 삭제 + SSO 전환.
"Action": "*"남발 = 권한 과잉. 실제 필요한 Action 목록으로.- Long-term access key 를 git 에 = 자동 스캔으로 즉시 탐지됨. Role + STS 사용.
- Resource-based policy 의 Principal 오타 = 의도치 않은 외부 공개.
- Policy 변경 후 즉시 반영 안 됨 = IAM 은 eventually consistent. 수초 대기.
- AssumeRole 시 duration 기본값 = 1시간. 장시간 작업은
--duration-seconds조정. - SCP 와 Permission Boundary 혼동 = SCP 는 계정 전체 상한, PB 는 특정 Role 상한.
관련 위키
- OAuth2 (비교)
- k8s-rbac (대조)
- aws-secrets-manager
- aws-sts-assume-role
- aws-eks (IRSA)
- aws-cloudtrail (감사 로그)
이 글의 용어 (6개)
- [Auth] OAuth 2.0 / 2.1: Authorization Code + PKCEauth-security
- 정의 OAuth 2.0 (RFC 6749, 2012) 은 제3자 앱이 사용자 동의로 자원에 접근 하게 하는 권한 위임 프레임워크. 인증 (authentication) 이 아니라 …
- [AWS] CloudTrail (API Activity Logging)cloud
- 정의 AWS CloudTrail 은 AWS 계정의 API 호출 및 사용자 활동을 기록 하는 감사 로깅 서비스입니다. "누가, 언제, 어디서, 어떤 API 를, 어떤 리소스에 대해…
- [AWS] EKS: managed Kubernetescloud
- 정의 EKS (Elastic Kubernetes Service) = AWS 의 managed K8s control plane. worker node 는 사용자 (또는 Fargat…
- [AWS] Secrets Manager + Parameter Storecloud
- 정의 AWS Secrets Manager = 회전이 필요한 비밀 (DB 패스워드, API key) 을 안전하게 저장/관리하는 서비스. Lambda 기반 자동 회전과 암호화 내장.…
- [AWS] STS / AssumeRole: 임시 자격, cross-accountcloud
- 정의 STS (Security Token Service) = 임시 자격 증명 발급. short-lived (15분-12시간) credentials. 장기 access key 없이…
- [K8s] RBAC: Role, ClusterRole, ServiceAccount, RoleBindingkubernetes
- 정의 RBAC (Role-Based Access Control) = K8s 의 권한 부여 모델. 주체 + 권한 + 바인딩. 사용 시나리오 | 상황 | RBAC 역할 | |---|…
이 개념을 다룬 위키 페이지 (46)
- wiki[AWS] API Gateway: REST/HTTP/WebSocket API 관리
- wiki[AWS] Artifact (AWS Compliance Reports & Agreements)
- wiki[AWS] Audit Manager (Automated Compliance Auditing)
- wiki[AWS] Amazon Bedrock
- wiki[AWS] Cloud Adoption Framework (CAF)
- wiki[AWS CAF] Governance Perspective
- wiki[AWS CAF] Security Perspective
- wiki[AWS] CDK (Cloud Development Kit)
- wiki[AWS] CloudFormation
- wiki[AWS] CloudTrail (API Activity Logging)
- wiki[AWS] Config (Resource Configuration Tracking)
- wiki[AWS] Direct Connect
- wiki[AWS] Amazon DocumentDB
- wiki[AWS] EC2: 인스턴스 타입, AMI, EBS
- wiki[AWS] ECR (Elastic Container Registry)
- wiki[AWS] ECS (Elastic Container Service)
- wiki[AWS] ECS + Fargate: 컨테이너 오케스트레이션
- wiki[AWS] EKS: managed Kubernetes
- wiki[AWS] Amazon GuardDuty
- wiki[AWS] Amazon Kendra
- wiki[AWS] KMS: 암호화 키 관리, envelope encryption
- wiki[AWS] Amazon Macie
- wiki[AWS] Amazon Neptune
- wiki[AWS] PrivateLink (VPC Interface Endpoints)
- wiki[AWS] Amazon RDS (Relational Database Service)
- wiki[AWS] RDS Multi-AZ + Read Replica
- wiki[AWS] Amazon Redshift
- wiki[AWS] Route 53
- wiki[AWS] S3: object storage, storage classes, lifecycle
- wiki[AWS] S3 File Access (Mountpoint, File Gateway, Express One Zone)
- wiki[AWS] S3 Vectors
- wiki[AWS] Amazon SageMaker
- wiki[AWS] Secrets Manager + Parameter Store
- wiki[AWS] Security Hub
- wiki[AWS] Security Group vs NACL: stateful vs stateless 방화벽
- wiki[AWS] Shield (DDoS Protection)
- wiki[AWS] SNS: pub-sub 알림, fan-out 패턴
- wiki[AWS] STS / AssumeRole: 임시 자격, cross-account
- wiki[AWS] Trusted Advisor
- wiki[IaC] AWS CDK: TypeScript 로 CloudFormation 생성
- wiki[IaC] Terraform: HCL, provider, state
- wiki[IaC] Terraform State: backend, locking, drift, import
- wiki[AWS] Well-Architected Framework
- wiki[DB] DynamoDB: PK + SK, single-table design, GSI / LSI
- wiki[K8s] RBAC: Role, ClusterRole, ServiceAccount, RoleBinding
- wiki[Search] Elasticsearch vs OpenSearch: 라이센스 분기와 차이
💬 댓글