클라우드 권한 설계 · 역할과 임시 자격증명 · 이론
액세스 키가 유출되는 이유는 존재하기 때문이다
한 줄 요약
장기 액세스 키는 만들지 않는 것이 최선입니다. 역할을 맡아 받은 임시
자격증명은 몇 시간 뒤 스스로 만료되므로, 유출돼도 피해가 시간으로 잘립니다.
왜 이게 필요했나
깃허브 공개 저장소에 AWS 키가 커밋되는 사고는 지금도 매일 일어납니다.
봇이 몇 분 안에 찾아내 암호화폐 채굴 인스턴스를 띄웁니다. 청구서는
수천만 원 단위로 옵니다.
여기서 진짜 문제는 커밋 실수가 아니라 그 키가 존재했다는 것입니다.
장기 키는 다음 성질을 가집니다.
- 스스로 만료되지 않는다 — 사람이 회수하기 전까지 영원히 유효
- 어디서 쓰이는지 추적하기 어렵다 — 그래서 폐기가 무섭다
- 복사가 쉽다 — 문서, 채팅, 환경 변수, CI 설정에 퍼진다
어떻게 동작하나
역할을 맡는다는 것
역할은 권한 묶음이고, 신뢰 정책(trust policy) 이 "누가 이 역할을 맡을 수
있는가" 를 정합니다.
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" }]}이 역할은 EC2 인스턴스가 맡을 수 있습니다. 인스턴스에 붙여 두면 그 안에서
도는 프로그램이 키 없이 자격증명을 얻습니다. 메타데이터 서비스에서
자동으로 받아 오고, 만료 전에 자동으로 갱신됩니다.
정리하면 이렇습니다.
| | 장기 액세스 키 | 역할(임시 자격증명) |
| --- | --- | --- |
| 만료 | 없음 | 보통 1~12시간 |
| 배포 | 파일·환경변수로 복사 | 자동 주입 |
| 회수 | 수동으로 찾아 폐기 | 만료를 기다리면 됨 |
| 추적 | 누가 쓰는지 불명확 | 역할 단위로 감사 로그 |
서비스 계정 키도 같은 문제다
쿠버네티스에서도 똑같습니다. 파드에 클라우드 키를 시크릿으로 넣는 방식은
같은 위험을 그대로 가집니다. 대신 OIDC 연합을 씁니다 — 클러스터가 발급한
서비스 계정 토큰으로 클라우드 역할을 맡습니다(AWS 의 IRSA, GCP 의 Workload
Identity, Azure 의 Workload Identity). 키가 아예 존재하지 않게 되는 것이 핵심입니다.
CI 도 마찬가지입니다. 깃허브 액션이나 Gitea 러너에 장기 키를 넣는 대신
OIDC 로 역할을 맡게 하면, 저장소 시크릿에서 클라우드 키가 사라집니다.
그래도 장기 키가 필요할 때
완전히 없앨 수 없는 경우가 있습니다(외부 SaaS 연동 등). 그때는 최소한 이렇게
합니다.
1. 전용 주체를 만든다 — 사람 계정의 키를 공유하지 않는다.
2. 권한을 그 용도로만 좁힌다 — Condition 으로 IP·시간까지.
3. 정기 교체(rotation) 를 절차로 만든다. 캘린더에 넣는다.
4. 사용 흔적을 본다 — 마지막 사용 시각이 오래됐으면 지운다.
4번이 가장 값싸고 효과가 큽니다. 안 쓰는 키를 지우는 것만으로 공격면이
크게 줄어듭니다.
세션과 만료 시간
역할을 맡을 때 세션 시간을 정합니다. 짧을수록 안전하지만 너무 짧으면
긴 작업 중에 만료됩니다. 실무 기준은 이렇습니다.
- 사람의 콘솔 작업: 1시간 정도
- CI 잡: 잡의 최대 실행 시간보다 조금 길게
- 긴 배치: 자격증명 갱신을 코드가 처리하게 만든다(SDK 가 대개 해 준다)
현장에서 만나는 모습
- 저장소에서 키가 발견됨 → 즉시 폐기. 그런데 어디서 쓰는지 몰라 폐기를 미룸.
- 인스턴스에 키 파일을 놓고 씀 → 역할을 붙이면 그 파일이 필요 없다.
- 키 하나를 팀 전체가 공유 → 감사 로그에서 누가 했는지 알 수 없다.
다음에 볼 것
권한을 실제로 좁혀 가는 순서. 처음부터 최소권한을 맞히는 건 불가능합니다.