GCP IAM 기초 — 서비스 계정과 권한, 최소 권한 원칙
이 글은 「GCP 기초」 연재의 네 번째 글이자 1단계 마지막 글이다. IAM은 팀이 커진 다음에 배우는 것이라고 미루기 쉬운데, 혼자 쓸 때야말로 잘못 잡아 두기 쉬운 영역이다. 혼자니까 전부 소유자 권한으로 쓰고, 편하니까 키 파일을 받아서 코드 옆에 둔다. 앞 편에서 본 요금 사고의 셋째 갈래가 정확히 여기서 나온다. 이 글을 다 읽으면 IAM을 문장 하나로 읽을 수 있고, 키 파일을 받지 않고 인증하는 방법을 알게 된다.
IAM은 문장 하나로 끝난다
IAM 화면. 역할별로 접으면 어떤 역할에 누가 붙어 있는지 한눈에 보인다
IAM(Identity and Access Management)은 세 가지의 조합이다. 주 구성원에게 리소스에 대한 역할을 부여한다. 이 한 문장이 전부다.
- 주 구성원(principal) — 누가. 구글 계정, 그룹, 그리고 서비스 계정이 여기 들어간다.
- 역할(role) — 무엇을 할 수 있게. 권한들을 묶어 놓은 꾸러미다.
- 리소스(resource) — 어디에서. 프로젝트, 버킷, 특정 서비스 등이다.
여기서 자주 하는 착각이 하나 있다. 권한을 개별로 붙이는 게 아니라 역할 단위로만 붙는다는 점이다. 그래서 "이 권한 하나만 주고 싶다"는 요구는 그 권한이 들어 있는 역할을 찾거나, 맞춤 역할을 만들어서 해결한다.
또 하나, 앞서 본 리소스 계층 때문에 상위에 준 역할은 하위로 상속된다. 프로젝트에 편집자를 주면 그 안의 모든 리소스에 편집 권한이 간다는 뜻이다.
역할 세 종류, 무엇을 골라야 하나
액세스 권한 부여 화면. 역할 선택을 열면 기본·직무 기반과 서비스별 사전 정의 역할을 검색해 고를 수 있다
기본 역할은 소유자·편집자·뷰어 세 개다. IAM이 생기기 전부터 있던 것으로, 하나에 수천 개의 권한이 묶여 있다. 공식 문서도 이 역할은 최후의 수단으로 쓰라고 안내한다.
사전 정의 역할은 구글이 서비스별로 만들어 둔 것이다. 이름이 roles/run.invoker처럼 서비스와 동작을 담고 있어서 무엇을 허용하는지 눈으로 읽힌다. 대부분의 경우 여기서 답이 나온다.
맞춤 역할은 권한을 직접 골라 조합한 것이다. 딱 맞는 게 없을 때 쓰지만, 새 권한이 생길 때 직접 갱신해야 하므로 관리 부담이 늘어난다.
고르는 순서는 정해져 있다. 사전 정의에서 찾고, 없으면 맞춤을 만들고, 기본 역할은 마지막이다.
서비스 계정은 사람이 아닌 계정이다
서비스 계정 목록. 키 ID 열이 "키 없음"이면 키 파일을 만든 적이 없다는 뜻이고, 그 상태가 권장 상태다
서비스 계정(service account)은 사람이 아니라 코드가 쓰는 신원이다. 배포된 앱이나 CI 파이프라인이 GCP 리소스를 건드릴 때, 개발자 개인 계정 대신 이 계정으로 접근한다. 주소가 your-sa@your-project-id.iam.gserviceaccount.com 형태의 이메일이라 처음에는 사람 계정처럼 보인다.
헷갈리기 쉬운 성질이 하나 있다. 서비스 계정은 주 구성원이면서 동시에 리소스다. 다른 리소스에 접근하는 주체이기도 하고, "누가 이 서비스 계정을 쓸 수 있는가"라는 권한이 따로 붙는 대상이기도 하다.
gcloud iam service-accounts create your-sa \
--display-name="배포용 계정"
gcloud projects add-iam-policy-binding your-project-id \
--member="serviceAccount:your-sa@your-project-id.iam.gserviceaccount.com" \
--role="roles/run.invoker"
만드는 기준은 용도 하나에 계정 하나다. 하나를 만들어 여기저기 돌려 쓰면, 권한이 계속 쌓이면서 결국 소유자와 다를 게 없어진다.
키 파일은 마지막 선택지다
키 탭 상단의 두 안내가 핵심이다. 키를 내려받지 말라는 경고와, 공개 저장소에서 감지된 키를 자동 중지한다는 안내
서비스 계정을 만들면 콘솔에서 JSON 키를 내려받을 수 있다. 편하지만 위험하다. 이 파일은 만료가 없는 자격 증명이고, 파일이라서 복사되고 커밋되고 채팅으로 전달된다. 한번 유출되면 회수하기 전까지 계속 유효하다.
구글 공식 문서의 권고는 명확하다. 가능하면 키를 아예 만들지 말라는 것이다. 대안은 상황별로 다르다.
- GCP 안에서 실행할 때 — Compute Engine이나 Cloud Run에 서비스 계정을 연결(attach)하면 키 없이 인증된다. 가장 안전하고 가장 간단하다.
- 외부 CI나 다른 클라우드에서 접근할 때 — 워크로드 아이덴티티 제휴를 쓴다. 외부에서 발급된 토큰을 GCP의 단기 토큰으로 교환하는 방식이라 저장할 키가 없다.
- 내 노트북에서 개발할 때 — 아래의 ADC를 쓴다.
조직 계정을 쓴다면 조직 정책으로 키 생성과 업로드 자체를 막을 수도 있다. 실제로 조직이 붙은 계정에서 키를 만들어 보면, 키 유형을 고르고 만들기를 눌러도 정책에 걸려 생성이 거부되는 경우가 있다. 막혔다는 것은 설정이 잘못된 게 아니라 권장 상태가 이미 걸려 있다는 뜻이다. 이럴 때는 정책을 풀 궁리를 하지 말고 위의 세 가지 대안 중 상황에 맞는 것을 고르면 된다.
키 탭에는 눈여겨볼 안내가 두 줄 더 있다. 하나는 키를 내려받지 말고 워크로드 아이덴티티 제휴를 쓰라는 경고이고, 다른 하나는 공개 저장소에서 감지된 키를 구글이 자동으로 사용 중지한다는 안내다. 깃허브에 실수로 올린 키가 곧바로 무력화된다는 뜻인데, 안전장치가 있다는 얘기이지 올려도 된다는 얘기는 아니다. 감지되기 전까지의 시간과 이미 복제된 사본은 그대로 남는다.
ADC — 코드에서 인증을 지우는 방법
ADC(Application Default Credentials, 애플리케이션 기본 사용자 인증 정보)는 라이브러리가 자격 증명을 알아서 찾아 쓰는 방식이다. 코드에 키 경로를 적지 않고, 실행 환경에 있는 자격 증명을 순서대로 탐색한다.
# 로컬 개발용 자격 증명 만들기
gcloud auth application-default login
# 남아 있는 키 목록 확인
gcloud iam service-accounts keys list \
--iam-account=your-sa@your-project-id.iam.gserviceaccount.com
탐색 순서는 대략 이렇다. GOOGLE_APPLICATION_CREDENTIALS 환경 변수에 지정된 파일 → gcloud로 만들어 둔 로컬 자격 증명 → 실행 중인 환경에 연결된 서비스 계정. 덕분에 같은 코드가 노트북에서도 Cloud Run에서도 그대로 돈다. 이 블로그의 Vertex AI에서 Claude 호출하기나 Cloud Run에 LLM 앱 배포하기에서 인증 코드가 짧은 이유도 이 방식을 쓰기 때문이다.
최소 권한, 혼자서도 지키는 법
- 소유자 역할은 사람에게만 두고, 서비스 계정에는 절대 주지 않는다.
- 필요한 역할부터 준다. 안 되면 하나씩 더하는 방향이지, 넓게 주고 빼는 방향이 아니다.
- 기간이 정해진 접근은 임시로 준다. 다른 계정을 잠시 흉내 내는 가장(impersonation) 방식이면 키를 만들 필요가 없다.
- 분기마다 IAM 화면을 훑는다. 실습하다 붙여 둔 역할과 안 쓰는 서비스 계정이 반드시 남아 있다.
- 콘솔이 띄우는 권한 축소 제안을 무시하지 않는다.
마무리
1단계 네 편은 결국 하나의 이야기였다. 프로젝트라는 경계를 긋고, 무료 한도 안에서 움직이고, 새는 곳을 미리 막고, 권한을 좁게 유지하는 것. 여기까지 해 두면 GCP에서 사고가 나도 범위가 프로젝트 하나 안에서 끝난다.
당장 할 일 하나만 고르라면 이것이다. 지금 프로젝트에 남아 있는 서비스 계정 키 목록을 확인하고, 안 쓰는 것을 그 자리에서 지우는 것. 다음 단계에서는 이 기반 위에 실제 서비스를 올리는 이야기로 넘어간다.
· · · 연재 순서 · · ·
(이전) GCP 요금 폭탄 막는 법 — 예산 알림·할당량·비용 통제
※ 이 글의 설명과 권장사항은 2026년 8월 기준이며 요금·메뉴 구성은 자주 변경됩니다.
댓글
댓글 쓰기