핵심 요약
- GCP IAM은 "누가(Member) + 무엇을(Role) + 어디서(Resource)" 3요소로 작동한다. AWS IAM과 달리 정책 문서가 아닌 바인딩(binding) 단위로 관리한다.
- Role은 Basic / Predefined / Custom 3종이며, Basic Role(Owner/Editor/Viewer)은 운영 환경에서 사용 금지다.
- Service Account는 사용자가 아닌 워크로드(앱, CI, VM)의 신원이다. JSON 키 발급은 마지막 수단이며 우선순위는 Workload Identity > ADC > Key다.
- Service Account Key 노출은 GCP 최대 사고 유형이다. 키 발급이 필요하면 자동 로테이션 + Secret Manager 보관이 기본이다.
- 본 글은 Predefined Role 선택 기준, Service Account 위임 패턴, Workload Identity Federation 동작 원리를 다룬다.
사전 지식: 시리즈 #1, OAuth 2.0 기본 개념, JWT 기본 구조
작성 시점: 2026년 5월 기준
1. GCP IAM의 기본 모델
GCP IAM은 다음 3요소로 모든 권한을 표현한다.
Member (Principal): 누가
- 사용자 계정: user:alice@example.com
- 서비스 계정: serviceAccount:my-sa@project.iam.gserviceaccount.com
- 그룹: group:devs@example.com
- 도메인: domain:example.com
- 인증된 모든 사용자: allAuthenticatedUsers
- 모든 사람(공개): allUsers
Role: 무엇을
- 권한(permission)의 집합. 예: roles/storage.objectViewer는 storage.objects.get, storage.objects.list 권한을 포함한다.
Resource: 어디서
- Organization, Folder, Project, 개별 리소스(Bucket, VM 등) 중 어느 레벨에 권한을 부여할지 결정한다.
이 셋을 묶은 것이 IAM Policy Binding이다. 다음과 같은 형태로 표현된다:
"bindings": [
{
"role": "roles/storage.objectViewer",
"members": [
"user:alice@example.com",
"serviceAccount:reader-sa@my-project.iahttp://m.gserviceaccount.com"
]
}
]
}
AWS IAM과의 핵심 차이
| 정책 단위 | JSON Policy Document | Role + Binding |
| 권한 표현 | Allow/Deny + Action/Resource | Role(권한 집합) 부여 |
| Deny 정책 | Explicit Deny 가능 | Deny Policy(별도 기능, 2022~) |
| 상속 | 명시적 첨부 | 계층 자동 상속 (Org→Folder→Project→Resource) |
| 정책 평가 | Allow vs Deny 명시 | Allow만 합산(기본) |
GCP의 가장 큰 특징은 계층 자동 상속이다.

[다이어그램 자리: GCP IAM 상속 구조 - Organization → Folder → Project → Resource 계층별 권한 합산]
위 다이어그램의 핵심은: 권한은 상위에서 하위로 합산된다(Allow Union). Organization 레벨에 부여된 권한은 자동으로 모든 하위 리소스에 적용되며, 하위에서 상위 권한을 철회하려면 별도의 Deny Policy가 필요하다.
2. Role의 세 가지 종류
2.1 Basic Role (사용 금지 권장)
GCP 초창기부터 존재한 거친 단위의 Role이다:
- roles/owner: 모든 권한 + 빌링 관리 + 권한 부여
- roles/editor: 모든 리소스 수정 (수십만 개 권한 포함)
- roles/viewer: 모든 리소스 읽기
문제: 너무 광범위해서 최소 권한 원칙에 정면으로 위배된다. roles/editor 하나가 약 4,000개 이상의 개별 permission을 포함한다(2026년 5월 기준).
언제 쓰는가: 본인이 단독으로 운영하는 sandbox/test 프로젝트, 또는 신규 프로젝트 초기 설정 단계에서만 임시 사용.
언제 안 쓰는가: 운영 환경, 다인 협업 환경, 외부 시스템 연동 시.
2.2 Predefined Role (실무 표준)
서비스별로 사전 정의된 Role이다. 명명 규칙은 roles/<service>.<level> 형식이다.
대표적인 예시:
- roles/storage.objectViewer: GCS 객체 읽기만
- roles/storage.objectCreator: GCS 객체 쓰기만 (읽기 X)
- roles/storage.objectAdmin: GCS 객체 전체 관리
- roles/storage.admin: GCS 버킷 + 객체 전체 관리
같은 storage 서비스 안에서도 5~6단계로 세분화되어 있다. 이 단계 구분을 정확히 이해해야 최소 권한이 실현된다.
Predefined Role 검색법: 콘솔 → IAM & Admin → Roles에서 검색하거나, gcloud로 확인할 수 있다. 명령은 gcloud iam roles list --filter="name:storage"이다.
2.3 Custom Role (특수 케이스)
Predefined Role로 표현할 수 없는 정밀한 권한 조합이 필요할 때 사용한다.
생성 예시:
"title": "Cloud Storage Lifecycle Viewer",
"description": "버킷 lifecycle 설정만 조회 가능",
"stage": "GA",
"includedPermissions": [
"storage.buckets.get",
"storage.buckets.getIamPolicy"
]
}
주의사항:
- Custom Role은 Organization 또는 Project 레벨에만 생성 가능(Folder 불가)
- GCP가 신규 permission을 추가해도 Custom Role에 자동 반영되지 않음(수동 업데이트 필요)
- 운영 부담이 크므로 Predefined Role로 표현 가능하면 Custom Role을 만들지 않는 것이 원칙이다.
3. Predefined Role 선택 기준
실무에서 가장 자주 헷갈리는 부분이 "어떤 Role을 줘야 하는가"이다. 다음 결정 흐름을 따른다.
Step 1: 해당 사용자/SA가 수행할 구체적인 작업을 동사로 나열한다.
예시 시나리오: "이미지 업로드 서비스의 백엔드 SA가 GCS에 파일 쓰고, BigQuery에 메타데이터 적재"
작업 목록:
- GCS 버킷에 객체 쓰기
- GCS 객체 메타데이터 읽기
- BigQuery 테이블에 INSERT
- BigQuery 테이블 스키마 조회
Step 2: 각 작업에 필요한 최소 Role을 매핑한다.
- GCS 객체 쓰기 → roles/storage.objectCreator
- GCS 객체 메타데이터 읽기 → roles/storage.objectViewer (이미 Creator에 미포함)
- BigQuery INSERT → roles/bigquery.dataEditor
- BigQuery 스키마 조회 → 위 Role에 포함
Step 3: 부여할 리소스 범위(scope) 를 최소화한다.
❌ 잘못된 예: Project 전체에 roles/storage.objectCreator 부여 (모든 버킷에 쓰기 가능)
✅ 올바른 예: 특정 버킷 gs://my-app-uploads 에만 roles/storage.objectCreator 부여
버킷 단위 권한 부여 명령:
Step 4: 정기적으로 사용되지 않는 권한 감사.
gcloud asset analyze-iam-policy 또는 IAM Recommender를 활용해 90일간 사용되지 않은 권한을 식별하고 제거한다.
4. Service Account 깊이 있게
4.1 Service Account란
Service Account(SA)는 사람이 아닌 워크로드(앱, VM, CI 파이프라인 등)의 신원이다. 다음 특징을 가진다:
- 이메일 형식의 식별자: <name>@<project-id>.iam.gserviceaccount.com
- 비밀번호 없음. 인증은 키 또는 ID 토큰으로 진행
- 자체적으로도 IAM 권한의 부여 주체이자 대상이 됨
4.2 두 가지 사용 패턴
패턴 A: SA를 리소스에 직접 첨부 (권장)
VM, Cloud Run, Cloud Function 등 GCP 리소스에 SA를 첨부(attach) 하면, 해당 리소스 내부 코드는 별도 인증 정보 없이 자동으로 SA의 권한을 얻는다. 이를 Application Default Credentials (ADC) 라고 한다.
VM에 SA 첨부 명령 예시:
--service-account=app-sa@my-project.iahttp://m.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--zone=us-west1-a
이 VM 안에서 Python 코드를 실행하면:
client = storage.Client()
buckets = client.list_buckets()
별도의 인증 키 없이 자동으로 app-sa의 권한으로 동작한다. ADC가 메타데이터 서버에서 단기 토큰을 자동 발급받기 때문이다.
패턴 B: SA Key 발급해서 외부 시스템에서 사용 (마지막 수단)
GCP 외부 환경(온프레미스 서버, GitHub Actions, 로컬 PC 등)에서 GCP API를 호출할 때 사용한다. JSON 형식의 키 파일을 발급한다.
키 발급 명령:
--iam-account=ci-sa@my-project.iahttp://m.gserviceaccount.com
생성된 JSON 키 파일의 구조 예시:
"type": "service_account",
"project_id": "my-project",
"private_key_id": "abc123...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "ci-sa@my-project.iahttp://m.gserviceaccount.com",
"client_id": "1234567890",
...
}
⚠️ 이 JSON 파일이 유출되면 해당 SA의 모든 권한이 외부에 노출된다. GCP 보안 사고의 가장 흔한 유형이다.
4.3 Service Account Key 운영 원칙
Key를 발급할 수밖에 없는 상황이라면 다음을 반드시 준수한다:
- Secret Manager에 저장: 코드 저장소에 절대 커밋하지 않는다. Secret Manager 또는 동급의 시크릿 관리 시스템에 보관
- 90일 이내 로테이션: gcloud iam service-accounts keys list 명령으로 만료된 키 식별 후 교체
- Key 발급 권한 제한: iam.serviceAccountKeyAdmin Role을 최소 인원만 보유
- Organization Policy로 차단: 가능하면 iam.disableServiceAccountKeyCreation 정책으로 Key 발급 자체를 차단
- GitHub Push Protection 활성화: 실수로 키를 커밋하더라도 push 단계에서 차단
4.4 Service Account Impersonation
SA Key 없이도 사용자가 일시적으로 SA 권한을 빌릴 수 있는 기능이다. 보안 관점에서 Key 발급보다 우월하다.
사용자에게 SA를 사칭(impersonate)할 권한 부여:
--member=user:alice@example.com \
--role=roles/iam.serviceAccountTokenCreator
이후 alice는 다음 명령으로 SA 권한으로 작업 가능:
이 방식의 장점:
- Key 파일이 디스크에 존재하지 않음
- 단기 토큰(기본 1시간) 사용
- 모든 impersonation은 감사 로그(Cloud Audit Logs)에 기록됨
운영 환경에서 임시 권한이 필요할 때는 Impersonation을 표준 패턴으로 삼는다.
5. Workload Identity Federation
5.1 등장 배경
외부 환경(AWS Lambda, GitHub Actions, Azure VM 등)에서 GCP를 호출할 때, 전통적으로는 SA Key를 발급해서 사용했다. 이는 다음 문제가 있다:
- 키가 노출되면 보안 사고
- 키 로테이션 운영 부담
- 멀티 클라우드 환경에서 키 관리 복잡도 증가
Workload Identity Federation (WIF) 은 외부 시스템의 신원(OIDC/SAML)을 GCP에 직접 연동하여, 키 없이도 외부 워크로드가 GCP SA 권한을 얻을 수 있게 한다.
5.2 동작 원리
WIF는 다음 흐름으로 동작한다:
- 외부 시스템(예: GitHub Actions)이 자체 OIDC 토큰을 발급
- GCP의 Workload Identity Pool에 해당 토큰을 제출
- Pool이 토큰을 검증하고 미리 정의된 매핑 규칙에 따라 SA 토큰을 발급
- 외부 시스템은 발급받은 SA 토큰으로 GCP API 호출
[다이어그램 자리: WIF 토큰 교환 흐름 - GitHub Actions → OIDC → WIF Pool → SA Token → GCP API]
5.3 GitHub Actions 연동 예시
GitHub Actions에서 WIF로 GCP에 인증하는 설정의 핵심 구성요소:
(1) Workload Identity Pool 및 Provider 생성:
--location=global \
--display-name="GitHub Actions Pool"
gcloud iam workload-identity-pools providers create-oidc github-provider \
--location=global \
--workload-identity-pool=github-pool \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"
(2) SA에 WIF 연결:
deployer-sa@my-project.iahttp://m.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principalSet://iahttp://m.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/attribute.repository/my-org/my-repo"
(3) GitHub Actions Workflow 설정:
deploy:
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/providers/github-provider
service_account: deployer-sa@my-project.iahttp://m.gserviceaccount.com
- run: gcloud storage ls
이 구성을 갖추면 GitHub Actions에서 SA Key 없이 GCP 리소스를 조작할 수 있다.
6. 실전 트러블슈팅
6.1 권한 에러 디버깅
가장 흔한 에러 메시지:
체크 순서:
(1) Member가 올바른지 확인: 사용자 본인인지, SA인지, 어떤 SA인지
(2) 현재 활성 SA의 권한 확인:
--flatten="bindings[].members" \
--filter="bindings.members:my-sa@my-project.iahttp://m.gserviceaccount.com" \
--format="table(bindings.role)"
(3) Policy Troubleshooter 활용: 콘솔의 IAM & Admin → Policy Troubleshooter에서 "이 Member가 이 권한을 가지는가?"를 직접 시뮬레이션할 수 있다.
6.2 권한 캐시 문제
IAM 정책 변경은 전파에 최대 7분까지 소요될 수 있다. 권한을 부여했는데 즉시 안 먹히면 다음을 확인:
- 토큰 갱신: gcloud auth application-default print-access-token으로 새 토큰 발급
- 7분 대기 후 재시도
- 그래도 안 되면 캐시된 자격증명 삭제: rm ~/.config/gcloud/application_default_credentials.json 후 gcloud auth application-default login 재실행
6.3 Default Service Account 위험성
GCP는 Compute Engine, App Engine 등에 Default Service Account를 자동 생성한다(예: 123456789-compute@developer.gserviceaccount.com). 이 기본 SA에는 보통 roles/editor가 기본 부여되어 있다.
문제: 이 SA가 첨부된 VM이 침해되면 프로젝트 전체에 대한 광범위한 권한이 노출된다.
해결:
- Organization Policy로 Default SA 자동 권한 부여 차단: iam.automaticIamGrantsForDefaultServiceAccounts
- 신규 생성 VM에는 명시적으로 최소 권한 Custom SA 첨부
- Default SA에서 roles/editor 제거 후 필요한 Predefined Role만 부여
7. 보안 점검 체크리스트
운영 환경 GCP 프로젝트에서 정기적으로 확인할 항목:
- Basic Role(Owner/Editor/Viewer)이 부여된 Member가 있는지 확인 (있다면 Predefined로 교체)
- Default Service Account의 roles/editor 제거 여부
- SA Key가 90일 이상 로테이션 안 된 게 있는지 (gcloud iam service-accounts keys list)
- allUsers, allAuthenticatedUsers에 부여된 권한 점검 (의도된 공개 외 차단)
- Workload Identity Federation 적용 가능한 외부 시스템 식별
- IAM Recommender의 사용되지 않는 권한 제거 권고 검토
- Cloud Audit Logs에서 비정상 Impersonation 시도 모니터링
- iam.disableServiceAccountKeyCreation Organization Policy 적용 검토
8. 마무리 및 다음 글
핵심 정리
- GCP IAM은 Member + Role + Resource의 3요소이며, 권한은 상위에서 하위로 자동 상속된다.
- Basic Role은 운영 환경에서 사용 금지. Predefined Role을 적절한 scope에 부여하는 것이 표준이다.
- Service Account는 워크로드의 신원이며, 우선순위는 리소스 첨부(ADC) > Impersonation > WIF > SA Key 순이다.
- SA Key 발급은 마지막 수단. 발급 시 Secret Manager 보관, 90일 로테이션, Organization Policy 차단을 기본 운영 원칙으로 삼는다.
- 외부 시스템 연동은 가능한 Workload Identity Federation으로 키 없이 인증한다.
다음 글(#3 예정): Cloud Storage 깊이 있게 — 스토리지 클래스 선택 기준, 라이프사이클 정책, 서명 URL(Signed URL), Object Versioning, Storage Transfer Service.
참고 자료
- IAM Overview 공식 문서
- Predefined Role 전체 목록
- Service Account Best Practices
- Workload Identity Federation 공식 가이드
- google-github-actions/auth (GitHub Actions WIF)
- Policy Troubleshooter
카테고리: Cloud / GCP
태그: gcp google-cloud iam service-account workload-identity-federation wif security cloud-architecture devops
'개발 프로젝트 > GCP 실습 일지' 카테고리의 다른 글
| GCP 시작 가이드 #5 — 비용 최적화 패턴 (0) | 2026.06.05 |
|---|---|
| GCP 시작 가이드 #4 — Cloud Run 배포 실전 (0) | 2026.06.03 |
| GCP 시작 가이드 #3 — Cloud Storage 깊이 있게 (0) | 2026.05.30 |
| GCP 시작 가이드 #1 — 계정 구조, 빌링, Free Tier의 함정 (0) | 2026.05.22 |