広く開けて狭める vs 狭く開けて広げる
한국어 원문으로 표시합니다.
한 줄 요약
최소권한은 한 번에 설계하는 것이 아니라 측정해서 좁혀 가는 과정입니다. 어떤 API 를 호출하는지 미리 다 아는 사람은 없습니다.
왜 이게 필요했나
새 서비스를 배포합니다. 어떤 권한이 필요한지 문서에도 정확히 안 나옵니다. 그래서 두 가지 방식 중 하나를 택하게 됩니다.
A. 넓게 열고 좁히기 — s3:* 로 시작해 되게 만든 뒤 나중에 줄인다.
B. 좁게 열고 넓히기 — 필요한 것만 넣고, 막힐 때마다 하나씩 추가한다.
현실에서 A 는 좁히는 커밋이 오지 않습니다. 되기 시작하면 아무도 다시 건드리지 않습니다. 그래서 원칙은 B 인데, B 는 개발 중에 느립니다.
어떻게 동작하나
실무에서 쓰는 절충
1. 개발 환경에서만 넓게 연다 (운영 계정에는 절대 넣지 않는다)
2. 실제로 호출된 API 를 기록한다 (감사 로그·액세스 어드바이저)
3. 그 목록으로 정책을 생성한다
4. 스테이징에서 좁힌 정책으로 검증한다
5. 운영에는 좁힌 정책만 배포한다
핵심은 1번의 환경 분리입니다. 넓은 권한이 존재해도 되는 곳을 정해 두면, "일단 열고 나중에" 가 사고로 이어지지 않습니다.
2번의 재료는 클라우드가 제공합니다 — 어떤 주체가 어떤 서비스를 마지막으로 언제 호출했는지 알려 주는 기능이 있습니다. 90일간 한 번도 안 쓴 권한은 없애도 되는 후보입니다.
권한 경계(permission boundary)
개발자에게 역할을 만들 권한을 주면, 그 개발자는 자기보다 강한 역할을 만들 수 있습니다. 이걸 막는 장치가 권한 경계입니다.
실효 권한 = (붙은 정책) ∩ (권한 경계)
교집합이라서, 경계 밖의 권한은 정책에 적어도 생기지 않습니다. "역할은 마음대로 만들되 이 범위를 넘을 수는 없다" 를 표현하는 방법입니다.
조직 차원에서는 이보다 위에 서비스 제어 정책(SCP) 같은 가드레일이 또 있습니다. 계정 전체에 걸리는 Deny 라서 관리자도 뚫지 못합니다.
자주 쓰는 가드레일 몇 가지
| 가드레일 | 막는 것 |
|---|---|
| 승인된 리전 외 사용 금지 | 엉뚱한 리전에 자원이 생기는 것 |
| 루트 계정 사용 금지 | 최상위 계정의 일상 사용 |
| 감사 로그 비활성화 금지 | 흔적을 지우는 행위 |
| 암호화 없는 스토리지 생성 금지 | 기본값 실수 |
| 공개 접근 설정 금지 | 버킷 공개 사고 |
이 다섯 개만 걸어 두어도 흔한 사고 대부분이 사라집니다. 그리고 이건 사람의 주의력이 아니라 시스템이 지키는 규칙이라 시간이 지나도 유지됩니다.
좁힐 때 흔히 놓치는 것
- 읽기처럼 보이는 쓰기 —
s3:GetObject는 읽기지만s3:PutObjectAcl은 권한을 바꿉니다. 이름만 보고 분류하면 틀립니다. - 권한 상승 경로 —
iam:PassRole,iam:CreatePolicyVersion같은 동작은 자신에게 더 큰 권한을 주는 데 쓰일 수 있습니다. - 삭제 — 목록에서 빠뜨리기 쉬운데 피해가 가장 큽니다.
현장에서 만나는 모습
- 개발 때
*로 열고 그대로 운영에 배포 → 가장 흔한 사고 경로. - 90일간 안 쓴 권한이 절반 → 액세스 어드바이저를 한 번도 안 봤다.
- 개발자가 만든 역할이 관리자급 → 권한 경계가 없었다.
사람과 기계의 권한은 다르게 다룬다
최소권한을 좁혀 갈 때, 사람이 쓰는 권한과 프로그램이 쓰는 권한은 성격이 달라서 같은 방식으로 다루면 둘 다 어긋난다.
기계의 권한은 좁히기 쉽다. 프로그램이 하는 일은 정해져 있고 바뀌면 배포가 일어나므로, 실제 호출을 기록해 정확히 그만큼만 주는 방식이 잘 통한다. 그리고 기계에는 장기 자격 증명을 주지 않는 것이 원칙이다. 인스턴스나 워크로드에 역할을 붙여 짧은 수명의 자격 증명을 자동으로 받게 하면, 키가 저장소에 커밋되거나 로그에 찍히는 사고 자체가 사라진다. 외부 CI 처럼 클라우드 밖에서 도는 것도 요즘은 신원 연합으로 같은 구조를 만들 수 있다.
사람의 권한은 좁히기 어렵다. 하는 일이 매번 다르고, 장애가 났을 때는 평소에 안 쓰던 권한이 갑자기 필요해진다. 그래서 사람에게는 상시 권한을 낮게 두고, 필요할 때 잠시 올리는 경로를 만든다. 승인을 거쳐 몇 시간짜리 권한을 받고, 그 사실이 기록으로 남는 방식이다. 이것이 없으면 결국 "장애 때 곤란하니까" 라는 이유로 모두가 높은 권한을 상시로 들고 있게 된다.
두 경우 모두 자격 증명의 수명이 짧을수록 유출의 값이 떨어진다. 그래서 좁히기만큼 중요한 것이 수명을 줄이는 일이고, 실은 이쪽이 더 쉽다. 정책을 한 줄씩 다듬는 데는 몇 주가 걸리지만, 장기 키를 역할로 바꾸는 작업은 한 번에 끝나고 효과가 즉시 나타난다.
마지막으로 떠나는 사람과 사라지는 서비스를 정리하는 절차를 짚어 둔다. 권한을 주는 절차는 어느 조직에나 있지만 회수하는 절차는 없는 경우가 많다. 쓰이지 않는 계정과 역할이 쌓이면 그것 자체가 공격면이 되고, 무엇이 살아 있는 것인지 알 수 없어 정리도 못 하게 된다. 90일간 쓰이지 않은 주체를 주기적으로 뽑아 보는 것이 이 문제를 막는 가장 값싼 방법이다.
다음에 볼 것
이 모든 게 무너졌을 때 실제로 어떤 사고가 나는지, 사례로 봅니다.