IAM 최소 권한: 모두가 놓치는 점 (그리고 Terraform으로 해결하는 방법)
Source: Dev.to
우리가 압박을 받을 때 가장 빠른 해결책이 승리한다. 누군가 접근 권한이 필요하고, 무언가가 실패하고, 마감일이 다가오고 있다. 그래서 우리는 고전적인 방법을 사용한다: “임시”로 넓은 권한을 부여한다.
문제는 임시 권한이 영구적으로 변하는 습관이 있다는 점이다.
최소 권한 원칙은 편집증이 아니라 의도적인 행동이다. 우리는 필요한 것만 부여하여 실수가 작게 남고, 보안이 예측 가능하도록 유지한다.
최소 권한은 실제로 무엇을 의미할까?
최소 권한은 다음을 의미합니다:
- 필요한 작업만 (모두가 아니라)
- 필요한 리소스만 (“모든 리소스”가 아니라)
- 필요할 때만 (영구적으로가 아니라)
- 올바른 정체성(역할, 사용자, 서비스)에게만
이러한 점들을 염두에 두고, 나는 항상 다음 질문을 스스로에게 합니다:
- 이 워크로드가 해야 할 일은 무엇인가?
- 어디에서 해야 하는가?
- 절대 허용해서는 안 되는 것은 무엇인가?
이 사고방식은 IAM이 단순히 보안만을 위한 것이 아니라 신뢰성에도 영향을 미치기 때문에 중요합니다. 권한이 과도한 역할은 더 많은 것을, 더 빠르게 망가뜨릴 수 있습니다.
규모에서 최소 권한이 중요한 이유
소규모 환경에서는 광범위한 권한이 즉각적인 문제를 일으키지 않을 수 있습니다.
대규모에서는 보통 문제가 됩니다.
최소 권한이 보호해 주는 것:
- 더 큰 블라스트 반경: 하나의 손상된 키가 모든 것에 영향을 미칠 수 있음
- 우발적인 삭제: 누군가가 프로덕션에서 잘못된 명령을 실행함
- 그림자 접근: 오래된 역할이 누가 부여했는지 기억하지 못하는 권한을 유지함
- 감사 골칫거리: “왜 이 역할이 이 접근 권한을 가지고 있나요?” 같은 어려운 질문
권한을 엄격히 하면 디버깅도 쉬워집니다. 무언가 실패했을 때, 접근 경계가 실제이고 의미가 있음을 알 수 있습니다.
팀이 흔히 저지르는 실수
실제 AWS 환경에서 흔히 보이는 패턴:
*와 같은 와일드카드- 인터넷에서 복사해 온 정책을 그대로 두고 정리하지 않음
- 여러 시스템에서 재사용되는 단일 역할
- 조용히 영구화되는 “임시” 권한
- 배포 권한과 런타임 권한을 구분하지 않음
이러한 문제는 빠르게 진행하려는 압박감에서 자주 발생합니다. 해결책은 비난이 아니라 올바른 패턴을 채택하는 것입니다.
나쁜 정책 vs 좋은 정책 예시
예시 1: S3 접근
❌ 나쁜 정책 (너무 광범위)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
왜 위험한가
- 모든 버킷을 삭제할 수 있음
- 비공개여야 할 데이터를 읽을 수 있음
- 특정 경로나 환경에 대한 제한이 없음
✅ 좋은 정책 (제한적이고 실용적)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucketInPrefix",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::my-app-data",
"Condition": {
"StringLike": {
"s3:prefix": ["public/*"]
}
}
},
{
"Sid": "ReadObjectsInPrefix",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-app-data/public/*"
}
]
}
왜 더 좋은가
- 단일 버킷에만 제한
- 특정 경로에만 제한
- 삭제 권한이 없음
예시 2: Lambda 로깅
❌ 나쁜 정책
{
"Effect": "Allow",
"Action": "logs:*",
"Resource": "*"
}
왜 위험한가
- 어디든 로그를 기록하도록 허용하는데, 이는 불필요하고 민감한 정보를 노출시킬 수 있음.
✅ 좋은 정책
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/my-function:*"
}
IAM을 올바르게 설계하기 위한 간단한 시스템
실제 프로젝트에서 작동하는 패턴
역할 분리
- 배포 전용 역할
- 런타임 전용 역할
- 모니터링 전용 역할
좁게 시작하고 필요할 때만 확장
- 작업이 실패하면, 문제를 해결하는 데 필요한 최소 권한만 추가합니다.
가드레일 사용
- “이것은 절대 일어나서는 안 된다”는 규칙을 강제하기 위해 Service Control Policies (SCPs)와 permission boundaries를 적용합니다.
정기적인 검토
- 몇 달 동안 사용되지 않은 권한은 제거합니다.
- 최소 권한 원칙은 일회성 설정이 아니라 지속적인 유지 관리 습관입니다.
Mini Project: Least‑Privilege IAM Role for Lambda + S3
Goal
Create:
- One S3 bucket
- One Lambda execution role
- One least‑privilege IAM policy attached to the role
The Lambda will be able to:
- Read only from
s3://bucket/public/* - Write only to
s3://bucket/results/* - Write logs to CloudWatch
미니 프로젝트: Lambda + S3용 최소 권한 IAM 역할
목표
다음 항목을 생성합니다:
- S3 버킷 하나
- Lambda 실행 역할 하나
- 역할에 연결된 최소 권한 IAM 정책 하나
Lambda는 다음 작업을 수행할 수 있습니다:
s3://bucket/public/*에서만 읽기s3://bucket/results/*에만 쓰기- CloudWatch에 로그 쓰기