AWS EC2에서 Google Agent Platform 안전하게 호출하기 – Workload Identity Federation 실전 가이드
안녕하세요. GS Neotek 김준용 입니다.
2026년 10월, Google이 공개한 Agent Platform(Gemini API)을 AWS EC2에서 호출하는 프로젝트를 진행하면서, 키 파일 없이 안전하게 인증하는 방법을 찾게 되었습니다.
보통은 Google 서비스 계정 JSON 키 파일을 EC2에 저장하지만, 이 방식은 키 유출 시 전체 권한 노출, 주기적 키 순환의 번거로움, “누가 언제 어디서” 호출했는지 추적의 어려움이 있습니다.
Google의 Workload Identity Federation(WIF)을 쓰면 AWS Instance Profile의 임시 자격 증명만으로 Google Cloud API를 호출할 수 있어, EC2에 장기 키 파일을 두지 않아도 됩니다.
이번 글에서는 테스트 환경에서 WIF를 직접 구성하고 Agent Platform을 호출한 과정을 단계별로 정리했습니다.
한눈에 보기
| 항목 | 내용 |
| 서비스 | Google Cloud Workload Identity Federation (AWS 외부 클라우드용) |
| 호출 대상 | Google Agent Platform API (Gemini 3.5 Flash, Enterprise 모드) |
| 지원 환경 | 1. AWS EC2, EKS 2. Azure VM, AKS 3. On-Premise (OIDC 제공자) |
| 보안 수준 | 1. JSON 키 파일 불필요 2. 임시 자격 증명만 사용 3. 양쪽 클라우드 감사 로그 기록 |
| 구성 소요 시간 | 이번 테스트 약 25분 (콘솔 15분 + CLI 10분) |
| 필수 설정 | EC2 IMDSv2 필수 활성화 |
| 프로덕션 권장 | 권장 |
참고: Workload Identity Federation 개요, AWS용 WIF 구성 가이드
Workload Identity Federation이란?
기존 방식의 문제점
AWS에서 Google Cloud API를 호출하려면 전통적으로 이렇게 했습니다.
- Google Cloud에서 서비스 계정 생성
- JSON 키 파일 다운로드
- EC2에 키 파일 복사 (
scp, user-data 등) - 애플리케이션이 키 파일 읽어서 호출
문제는:
- 키 파일이 EC2 디스크에 평문으로 저장
- 키가 유출되면 해당 서비스 계정의 모든 권한 노출
- 키 순환(rotation) 관리의 어려움
- “누가, 언제, 어디서” 호출했는지 추적 곤란
WIF 방식의 동작 원리
Workload Identity Federation은 연합 인증(Federated Identity) 개념을 클라우드 간에 적용합니다.
AWS EC2 Instance Profile
↓ (임시 credential 요청)
AWS STS (임시 자격 증명 발급)
↓ (GetCallerIdentity 요청에 서명)
Google Security Token Service
↓ (AWS 서명 검증 → 토큰 교환)
Google 서비스 계정 가장(Impersonation)
↓
Agent Platform API 호출 성공
핵심은 AWS의 임시 자격 증명이 Google의 신뢰할 수 있는 외부 신원(External Identity)으로 인정받는다는 것입니다.
EC2에는 WIF 설정 파일(aws-wif-credential.json)만 있으면 되고, 이 파일에는 프로젝트 정보와 매핑 규칙만 들어있습니다.
기존 방식 vs WIF 비교
| 구분 | 서비스 계정 키 방식 | WIF 방식 |
| EC2에 저장되는 것 | JSON 키 파일 (장기 자격 증명) | WIF 설정 파일 (키 없음) |
| 유출 시 위험도 | 높음 (키 자체가 유효) | 낮음 (설정만으로는 무용) |
| 키 순환 필요 | 있음 (주기적 재발급) | 없음 (임시 credential만 사용) |
| IAM 통합 | 어려움 | AWS IAM Role로 제어 가능 |
| Zero Trust 부합 | 불가 | 가능 |
직접 구성해보기
다음 단계는 Google Cloud와 AWS 콘솔을 오가며 진행합니다.<...> 형식의 플레이스홀더는 실제 환경 값으로 바꾸고, 꺾쇠괄호는 제거하세요.
준비 사항
Google Cloud:
- Workload Identity Pool 관리 권한 (
roles/iam.workloadIdentityPoolAdmin) - 서비스 계정 생성 및 IAM 변경 권한
- 프로젝트 ID와 프로젝트 번호 확인
AWS:
- IAM Role 및 Instance Profile 생성 권한
- EC2 실행 권한
- 12자리 AWS 계정 ID
네트워크:
- EC2에서 Google API endpoint로 HTTPS(443) 아웃바운드 허용
1단계 — Google Cloud Workload Identity Pool 생성
Google Cloud 콘솔 → IAM 및 관리자 → 워크로드 아이덴티티 제휴
풀 만들기:
- 이름:
aws-wif-pool(예시) - 설명: “AWS EC2용 Workload Identity Pool”
AWS 공급업체 추가:
- 공급업체 유형:
AWS - 공급업체 이름:
aws(ID로 사용됨) - AWS 계정 ID:
123456789012(실제 12자리 계정 ID)
속성 매핑:
google.subject → assertion.arn
attribute.account → assertion.account
attribute.aws_role → assertion.arn.extract('assumed-role/{role_name}/')
속성 조건 (중요!):
assertion.account=='123456789012'
이 조건으로 해당 AWS 계정에서만 진입할 수 있도록 제한합니다.


2단계 — Google Cloud 서비스 계정 생성 및 권한 부여
IAM 및 관리자 → 서비스 계정 → 서비스 계정 만들기

- 서비스 계정 이름:
service-account-for-aws(예시) - 서비스 계정 ID: 자동 생성 →
service-account-for-aws@my-project.iam.gserviceaccount.com
역할 부여:
Agent Platform 사용자(roles/aiplatform.user)

3단계 — Google Cloud AWS Role에 가장 권한 부여
워크로드 아이덴티티 제휴 → aws-wif-pool → 액세스 권한 부여

- 서비스 계정:
service-account-for-aws@my-project.iam.gserviceaccount.com - 속성 이름:
aws_role - 속성 값:
agent-platform-ec2-role← 이 이름을 AWS IAM Role 이름과 정확히 일치시켜야 함
이 설정은 “aws_role 속성이 agent-platform-ec2-role인 AWS 주체만 이 서비스 계정을 가장할 수 있다”는 의미입니다.
4단계 — Google Cloud Shell WIF 설정 파일 생성
Cloud Shell에서 아래 명령 실행 (플레이스홀더를 실제 값으로 변경):
# WIF 설정 파일 생성 (IMDSv2 활성화)
gcloud iam workload-identity-pools create-cred-config \
"projects/123456789012/locations/global/workloadIdentityPools/aws-wif-pool/providers/aws" \
--service-account="service-account-for-aws@my-project.iam.gserviceaccount.com" \
--aws \
--enable-imdsv2 \
--output-file="aws-wif-credential.json"


--enable-imdsv2가 중요합니다!
EC2 메타데이터 버전 2(IMDSv2)를 사용하도록 설정 파일을 구성합니다. IMDSv2는 SSRF 공격 방어를 위한 AWS 권장 설정입니다.
생성된 aws-wif-credential.json을 다운로드합니다. 이 파일은 키가 아니라 설정 파일입니다.
5단계 — AWS IAM Role 생성
AWS 콘솔 → IAM → 역할 → 역할 생성



- 신뢰할 수 있는 엔터티:
AWS 서비스 - 사용 사례:
EC2 - 역할 이름:
agent-platform-ec2-role← 3단계에서 지정한 이름과 정확히 일치
권한 정책:
- Agent Platform 호출 자체에는 AWS 권한 불필요
- (선택) Session Manager 접속용:
AmazonSSMManagedInstanceCore
AWS 콘솔에서 역할 생성 시 같은 이름의 Instance Profile이 자동으로 생성됩니다.
6단계 — AWS EC2 인스턴스 생성 및 설정
EC2 → 인스턴스 시작
주요 설정:
- AMI: Amazon Linux 2023 (또는 Ubuntu 22.04)
- 인스턴스 유형: t3.micro (테스트용)
- 네트워크: 아웃바운드 HTTPS(443) 허용
- 고급 세부 정보:
- IAM 인스턴스 프로파일:
agent-platform-ec2-role - 메타데이터 버전:
V2만 (토큰 필요)← 필수!
- IAM 인스턴스 프로파일:

인스턴스 생성 후 SSH 또는 Session Manager로 접속합니다.
7단계 — EC2 WIF 설정 파일 업로드 및 환경 구성
4단계에서 다운로드한 aws-wif-credential.json을 EC2에 복사합니다.
# 로컬 → EC2 (scp 또는 Session Manager로 내용 복사)
# EC2 내부에서:
nano ~/aws-wif-credential.json
# (JSON 내용 붙여넣고 저장)
Python 가상 환경 및 SDK 설치:
# Python 가상 환경 생성
python3 -m venv .venv
source .venv/bin/activate
# Google Gen AI SDK 설치 (Python 3.10 이상 필요)
pip install "google-genai==2.13.0"
# 환경 변수 설정
export GOOGLE_APPLICATION_CREDENTIALS="$HOME/aws-wif-credential.json"
export GOOGLE_CLOUD_PROJECT="my-project"
export GOOGLE_CLOUD_LOCATION="global"
8단계 — 호출 테스트
app.py 작성:
# 필요한 라이브러리를 불러옵니다.
import os
from google import genai
from google.genai import types
# AWS WIF ADC를 자동으로 사용하는 Agent Platform 클라이언트를 생성합니다.
client = genai.Client(
enterprise=True,
project=os.environ["GOOGLE_CLOUD_PROJECT"],
location=os.getenv("GOOGLE_CLOUD_LOCATION", "global"),
http_options=types.HttpOptions(api_version="v1"),
)
# Gemini 3.5 Flash와 Google Search Grounding으로 질문을 전송합니다.
response = client.models.generate_content(
model=os.getenv("MODEL_ID", "gemini-3.5-flash"),
contents="대한민국의 수도는 어디인가요?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())],
max_output_tokens=2048,
temperature=0,
),
)
# 응답 본문이 비어 있으면 오류로 처리합니다.
if not response.text:
raise RuntimeError("Gemini 응답 본문이 없습니다.")
# 응답을 출력합니다.
print(response.text)
# 사용한 클라이언트 연결을 종료합니다.
client.close()
실행:
python3 app.py

성공! 키 파일 없이 Gemini가 응답했습니다.
SDK가 자동으로 다음 과정을 수행했습니다:
EC2 Instance Profile → AWS 임시 credential 획득
→ GetCallerIdentity 요청에 서명
→ Google STS 토큰 교환
→ 서비스 계정 가장
→ Agent Platform 호출
동작 원리 깊이 보기
WIF 설정 파일 내부
aws-wif-credential.json의 구조 (민감정보 제외):
{
"type": "external_account",
"audience": "//iam.googleapis.com/projects/123456789012/locations/global/workloadIdentityPools/aws-wif-pool/providers/aws",
"subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-for-aws@my-project.iam.gserviceaccount.com:generateAccessToken",
"credential_source": {
"environment_id": "aws1",
"regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
"imdsv2_session_token_url": "http://169.254.169.254/latest/api/token"
}
}
핵심 필드:
subject_token_type: AWS 서명된 요청을 Subject Token으로 사용credential_source.imdsv2_session_token_url: IMDSv2 토큰 먼저 획득service_account_impersonation_url: 최종적으로 가장할 서비스 계정
ADC(Application Default Credentials) 체인
Google SDK는 다음 순서로 자격 증명을 찾습니다:
GOOGLE_APPLICATION_CREDENTIALS환경 변수가 가리키는 파일gcloud auth application-default login으로 생성한 사용자 credential- GCE/GKE 메타데이터 서버
- 찾지 못하면 오류
WIF를 사용할 때는 1번에서 aws-wif-credential.json을 제공하므로, SDK가 자동으로 AWS → Google 연계를 처리합니다.
보안 고려사항
WIF Pool의 속성 조건이 중요한 이유
assertion.account=='123456789012'
이 조건이 없으면 모든 AWS 계정의 해당 Role 이름을 가진 주체가 진입 시도할 수 있습니다.
속성 조건으로 특정 AWS 계정만 허용해야 합니다.
더 세밀한 제어도 가능합니다:
assertion.arn.contains(':instance-profile/agent-platform-')
Instance Profile 이름에 패턴을 넣어 특정 EC2만 허용할 수 있습니다.
IMDSv2 필수 설정
IMDSv2는 세션 토큰 기반 메타데이터 요청을 강제합니다.
IMDSv1 (취약):
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
→ SSRF 공격에 노출 가능
IMDSv2 (안전):
# 1. 토큰 획득 (TTL 지정)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# 2. 토큰과 함께 요청
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
WIF 설정 파일의 imdsv2_session_token_url이 이 과정을 자동화합니다.
감사 추적(Audit Trail)
WIF 호출은 양쪽 클라우드 모두에 로그가 남습니다.
AWS CloudTrail:
- EC2가
sts:GetCallerIdentity호출 기록 - Instance Profile assumption 기록
Google Cloud Audit Logs:
- Workload Identity Pool 토큰 교환 기록 (
sts.googleapis.com) - 서비스 계정 가장 기록 (
iamcredentials.googleapis.com) - Agent Platform API 호출 기록 (
aiplatform.googleapis.com)
“AWS의 어떤 EC2가, 언제, Google의 어떤 API를 호출했는지” 추적할 수 있습니다.
직접 써 보고 느낀 점
좋았던 점
- 키 파일이 완전히 사라졌습니다.
EC2를 탈취당해도 장기 자격 증명이 없어 피해 범위가 제한됩니다. WIF 설정 파일만으로는 아무것도 할 수 없습니다. - AWS IAM으로 통합 관리할 수 있습니다.
기존 AWS IAM 정책과 Role을 그대로 활용해 “어떤 EC2가 Google API를 호출할 수 있는가”를 제어합니다. 별도 키 관리 시스템이 불필요합니다. - Zero Trust 아키텍처에 부합합니다.
“네트워크가 아닌 신원으로 인증”하고, 임시 credential만 사용하며, 최소 권한 원칙(Least Privilege)을 양쪽 클라우드 모두에서 적용할 수 있습니다. - 키 순환 관리 부담이 사라졌습니다.
서비스 계정 키는 주기적으로 재발급하고 배포해야 했지만, WIF는 매번 새로운 임시 토큰을 사용하므로 순환 자체가 필요 없습니다.
아쉬웠던 점
- 초기 설정이 복잡했습니다.
양쪽 클라우드의 콘솔과 CLI를 오가며 여러 단계를 거쳐야 했습니다. 특히 Pool, Provider, 속성 매핑, 조건의 개념이 처음에는 혼란스러웠습니다. Terraform 같은 IaC로 자동화하면 나아질 수 있습니다. - 오류 메시지가 불친절한 경우가 있었습니다.
Role 이름 불일치나 권한 부족 시 “Unauthorized” 정도만 나와서 어느 단계에서 막혔는지 파악이 어려웠습니다. Cloud Logging을 세밀하게 보면서 디버깅해야 했습니다. - IMDSv2 필수 설정을 빼먹기 쉬웠습니다.
EC2 생성 시 메타데이터 설정이 “고급 세부 정보” 안쪽에 숨어 있어, 처음엔 IMDSv1으로 생성했다가 credential 획득 오류를 겪었습니다. 명시적으로 “V2만”을 선택해야 합니다. - 다른 리전으로 확장 시 설정이 추가될 수 있습니다.
이 테스트는globallocation을 사용했지만, 리전별 endpoint를 쓰거나 여러 리전의 EC2에서 호출한다면 WIF Provider 설정을 조정해야 할 수 있습니다.
정리
| 항목 | 정리 |
| 설정 난이도 | 보통. Pool·Provider·서비스 계정·IAM Role 순서대로 구성, CloudFormation으로 반복 작업 자동화 가능 |
| 구성 소요 시간 | 이번 테스트 약 25분 (콘솔 15분 + CLI 10분) |
| 호출 테스트 | WIF 설정 파일 생성 후 EC2에 복사, SDK가 자동으로 AWS → Google 연계 |
| 정확도 | 설정이 정확하면 100% 동작. Role 이름 불일치 시 Unauthorized |
| 활용법 | 1차 구축 후 EC2 Auto Scaling Group에 설정 파일 배포, 추가 키 관리 불필요 |
| 보안 체크 포인트 | 1. 속성 조건으로 AWS 계정 제한 2. IMDSv2 필수 활성화 3. 서비스 계정 최소 권한 |
Workload Identity Federation은 멀티 클라우드 시대에 “각 클라우드의 네이티브 보안 메커니즘을 활용”해 키 관리 부담을 덜어주는 필수 패턴이었습니다.
AWS EC2에서 Google의 Agent Platform(Gemini)을 호출하는 과정을 직접 구성하며, 장기 자격 증명 없이도 안전하게 연계할 수 있다는 것을 확인했습니다.
초기 설정은 다소 복잡하지만, 한 번 구축하면 키 순환·유출 리스크·감사 추적 모두가 개선됩니다. Azure, GCP Kubernetes, On-Premise 환경에서도 비슷한 WIF 패턴을 적용할 수 있으니, Zero Trust 아키텍처를 고민 중이라면 꼭 살펴보시길 권합니다.
최신 댓글