Gemini Enterprise Agent Platform의 에이전트 게이트웨이를 사용한 에이전트 워크로드 관리

1. 소개

Gemini Enterprise 에이전트 플랫폼은 데이터를 기반으로 그라운딩된 엔터프라이즈급 AI 에이전트를 빌드, 확장, 제어, 최적화할 수 있는 개방형 플랫폼입니다.

에이전트 런타임은 Google Cloud 내에서 안전하게 오픈소스 에이전트 개발 키트 (ADK)로 빌드된 에이전트와 같은 에이전트를 실행하기 위한 관리형 실행 환경을 제공합니다.

이 Codelab에서는 이러한 핵심 빌딩 블록을 사용하여 Gemini Enterprise에서 사용자가 시작한 에이전트가 내부 도구에 안전하게 연결될 때 이를 관리하는 방법을 살펴봅니다.

에이전트 게이트웨이 정보

Agent Gateway는 플랫폼의 Agent Governance 제품군의 네트워킹 구성요소입니다. 모든 에이전트 상호작용의 네트워크 진입점 및 종료점 역할을 하므로 보안 관리자는 개발자가 복잡한 네트워킹 기본 요소를 관리하지 않아도 중앙 집중식 거버넌스를 적용할 수 있습니다.

이 기능은 두 가지 주요 관리 액세스 경로를 지원합니다.

  • 클라이언트-에이전트 (인그레스): 외부 클라이언트 (예: Cursor 또는 Gemini CLI)와 에이전트 간의 통신을 보호합니다.
  • 에이전트-애니웨어 (이그레스): Google Cloud에서 실행되는 에이전트와 어디에서나 실행되는 서버, 도구 또는 API 간의 통신을 보호합니다.

이 Codelab에서는 에이전트-어디로든 (egress) 모드에 중점을 둡니다.

에이전트 게이트웨이를 사용한 액세스 제어

보안 정책을 적용하기 위해 에이전트 게이트웨이는 나머지 생태계와 긴밀하게 통합됩니다.

  • 에이전트 레지스트리: 승인된 에이전트 및 도구 (서드 파티 MCP 서버 포함)의 중앙 라이브러리입니다.
  • 상담사 ID: 모든 상담사에 대해 추적 가능한 고유한 페르소나로, 엔드 투 엔드 mTLS로 자동 보안 처리됩니다.
  • Identity-Aware Proxy (IAP) 및 IAM: 특정 도구에 대한 호출을 허용하기 전에 세분화된 IAM 권한에 대해 에이전트의 ID를 검증하는 기본 시행 레이어입니다.
  • Model Armor: 콘텐츠를 정리하고 프롬프트 인젝션 공격이나 데이터 유출을 방지하기 위해 Service Extensions를 통해 통합된 AI 보안 가이드레일입니다.

배포 모드 (Cloud Run의 공개 네트워킹과 비공개 네트워킹)

이 Codelab에 액세스하려면 Cloud Run에 배포된 내부 도구 (MCP 서버)에 대해 다음 두 가지 네트워킹 경로 중에서 선택하면 됩니다.

  1. 기본값 (공개 인그레스): MCP 서버가 공개 호스트 이름 (ingress=all)으로 Cloud Run에 배포됩니다. 트래픽은 표준 *.run.app URL을 통해 에이전트에서 도구로 라우팅됩니다. 맞춤 DNS 도메인이 필요하지 않으며 거버넌스 개념을 가장 빠르게 학습할 수 있습니다.
  2. 보안 (비공개 네트워킹): 선택사항인 완전한 비공개 아키텍처입니다. MCP 서버는 제한 (ingress=internal-and-cloud-load-balancing)되고 서버리스 NEG가 있는 내부 애플리케이션 부하 분산기를 통해 노출됩니다. 이렇게 하려면 Google 관리형 인증서를 프로비저닝할 공개 DNS 도메인을 소유해야 합니다.

Terraform을 구성할 때 원하는 경로를 선택합니다.

Cloud Run의 네트워크 엔드포인트 인그레스에 대해 자세히 알아보려면 문서를 참고하세요.

실습할 내용

  • Terraform을 사용하여 핵심 인프라 스택 프로비저닝
  • Cloud Run에서 내부 도구를 MCP 서버로 빌드 및 배포
  • PSC 인터페이스 이그레스를 사용하여 ADK 에이전트를 에이전트 런타임에 배포
  • ID 기반 액세스 (IAM) 및 콘텐츠 검열 (Model Armor)을 위한 에이전트 게이트웨이 서비스 확장 프로그램 구성
  • 에이전트의 안전한 엔드 투 엔드 실행 추적 및 검증

필요한 항목

  • 웹브라우저(예: Chrome)
  • 결제가 사용 설정되고 소유자 액세스 권한이 있는 Google Cloud 프로젝트
  • 조직 수준 IAM 권한 (코드랩에서 조직 범위 역할 부여)
  • Cloud DNS에 위임된 관리형 공개 인증서의 도메인
  • Terraform, gcloud, 기본 Google Cloud 네트워킹에 대한 이해

Codelab 토폴로지

엔드 투 엔드 아키텍처: Gemini Enterprise에서 에이전트 런타임, 에이전트 게이트웨이, Cloud Run의 MCP 서버까지

이 Codelab에서는 세 가지 내부 도구와 안전하게 통신하는 엔드 투 엔드 모기지 심사 에이전트를 배포합니다.

먼저 에이전트 게이트웨이로 구성된 VPC와 내부 애플리케이션 부하 분산기를 비롯한 기본 네트워킹을 프로비저닝합니다. 다음으로 모델 컨텍스트 프로토콜 (MCP) 서버 3개를 Cloud Run에 배포합니다. 다음은 내부 독점 도구로 작동합니다.

  • 문서 관리 (legacy-dms)
  • 회사 이메일 (corporate-email)
  • 소득 확인 (income-verification)

도구가 준비되면 ADK로 빌드된 모기지 어시스턴트 (mortgage-agent)를 에이전트 런타임에 배포합니다. 비공개 이그레스를 위해 PSC 인터페이스를 사용하고 에이전트 레지스트리를 통해 런타임 도구 검색을 사용 설정하도록 이 에이전트를 구성합니다.

흐름을 보호하려면 서비스 확장 프로그램 두 개로 에이전트 게이트웨이를 구성합니다. 먼저 REQUEST_AUTHZ 확장 프로그램이 도구별 IAM 정책에 대해 에이전트 ID를 확인하여 에이전트가 승인된 도구에만 액세스하도록 합니다. 두 번째로 Model Armor를 사용하는 CONTENT_AUTHZ 확장 프로그램이 에이전트의 프롬프트와 응답을 검사합니다.

마지막으로 Gemini Enterprise에 에이전트를 등록하고, 최종 사용자로 모기지 심사 작업을 트리거하고, Cloud Trace를 사용하여 안전하고 관리되는 실행을 확인합니다.

이 Codelab은 모든 수준의 플랫폼 및 보안 엔지니어를 대상으로 합니다. 완료하는 데 약 100분이 소요될 것으로 예상됩니다.

2. 시작하기 전에

프로젝트 생성 및 인증

결제가 사용 설정된 새 GCP 프로젝트를 만들거나 기존 프로젝트를 재사용하고 Cloud Shell 또는 로컬 머신을 인증합니다.

gcloud auth login
gcloud auth application-default login
gcloud config set project <your-project-id>

부트스트랩 API 사용 설정

Terraform의 기본 모듈은 첫 번째 적용 시 약 30개의 API를 사용 설정하지만 terraform init 및 GCS 상태 버킷에는 작은 부트스트랩 세트가 필요합니다.

gcloud services enable \
  compute.googleapis.com \
  serviceusage.googleapis.com \
  cloudresourcemanager.googleapis.com \
  iam.googleapis.com \
  storage.googleapis.com \
  dns.googleapis.com

필수 도구 설치

도구 모음을 설치합니다. Cloud Shell에서는 이러한 항목이 대부분 이미 제공됩니다. 워크스테이션에서는 다음을 실행하세요.

# uv (Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh

# skaffold
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \
  sudo install skaffold /usr/local/bin/

# envsubst (gettext)
sudo apt-get install -y gettext-base

Terraform >= 1.12.2, Python 3.12 이상, Google Cloud SDK (gcloud)도 필요합니다.

환경 변수 설정하기

Codelab의 나머지 부분에서는 이러한 항목이 셸에 내보내진 것으로 가정합니다.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export ORG_ID=$(gcloud projects get-ancestors $PROJECT_ID | awk '$2 == "organization" {print $1}')
export REGION="us-central1"

# Only required if using the secure private networking path
export DOMAIN_NAME="agw.example.com" 

모든 변수가 올바르게 채워졌는지 확인합니다. 값이 3개 반환되어야 합니다.

echo $PROJECT_ID  
echo $PROJECT_NUMBER
echo $ORG_ID

조직 ID가 자동으로 입력되지 않으면 직접 찾아 설정할 수 있습니다.

gcloud organizations list
export ORG_ID=ID_FROM_OUTPUT

3. 저장소 복제

git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git
cd cloud-networking-solutions
cd demos/agent-gateway

데모 디렉터리의 내용을 간단히 살펴보겠습니다.

src/                MCP servers (legacy-dms, corporate-email, income-verification-api) + mortgage-agent
terraform/          Root Terraform config + modules (foundation, networking, agent-gateway, model-armor, ...)
cloudrun/           Cloud Run service definitions (rendered from .yaml.tmpl via envsubst)
scripts/            grant_agent_mcp_egress.sh — per-MCP IAP egressor binding
skaffold.yaml.tmpl  Skaffold pipeline that builds + deploys all three MCP services to Cloud Run

4. Terraform 상태 버킷 및 백엔드 구성 만들기

원격 상태를 저장할 GCS 버킷을 만든 다음 백엔드 템플릿을 복사합니다.

gcloud storage buckets create gs://${PROJECT_ID}-tfstate \
  --location=${REGION} \
  --uniform-bucket-level-access

cp terraform/example.backend.conf terraform/backend.conf

terraform/backend.conf를 사용자 값으로 수정합니다.

bucket = "<your-project-id>-tfstate"
prefix = "agent-gateway"

5. (선택사항) 공개 Cloud DNS 영역 만들기

이 실습에서 Cloud Run의 수신 구성은 기본적으로 all로 설정되어 있으며, 에이전트 레지스트리는 각 MCP 서버를 공개 *.run.app URL에 등록합니다. 추가 DNS, 인증서 또는 부하 분산기는 필요하지 않습니다. 비공개 네트워킹 (내부 애플리케이션 LB 뒤에 있는 ingress = internal-and-cloud-load-balancing를 사용하는 Cloud Run)으로 전환하려면 인증서 관리자가 LB 인증서를 검증할 수 있도록 공개 Cloud DNS 영역도 필요합니다.

비공개 네트워킹의 개략적인 흐름

비공개 네트워킹 옵션의 개략적인 흐름

비공개 네트워킹 방식을 사용하려면 다음 단계를 따르세요.

  1. 공개 Cloud DNS 영역을 만듭니다. 인증서 관리자는 여기에 CNAME을 작성하여 리전 관리형 인증서를 검증합니다.
gcloud dns managed-zones create agw-example-com \
  --dns-name="${DOMAIN_NAME}." \
  --description="Public zone for ${DOMAIN_NAME}" \
  --visibility=public

mcp.${DOMAIN_NAME}의 해당 비공개 영역 (MCP 내부 LB 및 에이전트 런타임의 DNS 피어링에서 사용)은 Terraform에 의해 자동으로 생성되므로 직접 만들 필요가 없습니다. 비공개 네트워킹이 사용 중지되면 공개 영역과 비공개 영역이 모두 프로비저닝되지 않습니다.

6. Terraform 변수 구성

예시 tfvars를 복사하여 수정합니다.

cp terraform/example.tfvars terraform/terraform.tfvars

enable_cloud_run_private_networking로 관리되는 두 가지 데모 경로가 있습니다.

기본 경로: 공개 인그레스가 있는 Cloud Run

**가장 간단한 설정.**기본 경로의 경우 terraform.tfvars에서 세 값만 수정하면 됩니다. 파일의 다른 모든 변수에는 이미 데모에 적합한 기본값이 있습니다.

# GCP project ID where all resources will be created.
project_id = "my-gcp-project-id"

# GCP organization ID (numeric).
organization_id = "123456789012"

# Members granted demo-wide roles
platform_admin_members = ["user:admin@example.com"]

# IAP Enforcement Mode ("DRY_RUN" or null)
agent_gateway_iap_iam_enforcement_mode = "DRY_RUN"

비공개 네트워킹 (선택사항)

enable_cloud_run_private_networking = true를 설정하고 아래 변수를 추가하여 완전한 보안 스택을 프로비저닝합니다.

  • 내부 애플리케이션 LB
  • Google 관리 인증서
  • ingress = internal-and-cloud-load-balancing를 사용하는 Cloud Run
  • 에이전트 게이트웨이 DNS 피어링입니다.
enable_cloud_run_private_networking = true

# DNS — must end with a trailing dot, must match a Cloud DNS zone you own
dns_zone_domain            = "agw.example.com."
enable_certificate_manager = true

# mcp_internal_dns_zone.domain MUST be a real subdomain of dns_zone_domain so
# Certificate Manager can issue a Google-managed cert.
mcp_internal_dns_zone = {
  name   = "mcp-server-internal"
  domain = "mcp.agw.example.com."
}

# Must match mcp_internal_dns_zone.domain so Agent Engine resolves MCP
# hostnames over the PSC interface peering.
psc_interface_dns_zone = {
  name   = "mcp-server-internal"
  domain = "mcp.agw.example.com."
}

mcp_lb_protocol = "HTTPS"

7. Terraform으로 인프라 배포

초기화, 검토, 적용:

cd terraform
terraform init -backend-config=backend.conf
terraform plan
terraform apply

terraform apply는 기본 경로에 약 40개의 리소스를 프로비저닝하며 새 프로젝트에서 8~10분이 걸립니다 (enable_cloud_run_private_networking = true의 경우 약 60개의 리소스 / 15~20분). 다음을 만듭니다.

  • 프로젝트 기반 (API, 서비스 ID, 할당량)
  • VPC, 서브넷 (기본, 프록시 전용, PSC, PSC 인터페이스, 에이전트 게이트웨이 공동 배치), Cloud NAT, 방화벽 규칙
  • Cloud Run 이미지용 Artifact Registry 저장소
  • Cloud Run 서비스 3개 + 서비스별 런타임 SA (인그레스 = 기본적으로 all, 비공개 네트워킹이 사용 설정된 경우 internal-and-cloud-load-balancing)
  • Model Armor 템플릿 + IAM
  • 에이전트 게이트웨이, PSC-I 네트워크 연결, IAP 및 Model Armor 확장 프로그램, 두 승인 정책, 프로젝트 수준 roles/iap.egressor 부여
  • 에이전트 레지스트리 엔드포인트 (Vertex AI, IAP, 검색 엔진 등)와 3개의 MCP 서버 (기본적으로 *.run.app/mcp에 등록됨, 비공개 네트워킹이 사용 설정된 경우 ./mcp에 등록됨)

enable_cloud_run_private_networking = true인 경우에만:

  • 서버리스 NEG (URL 마스크 라우팅) + 비공개 DNS A 레코드가 있는 내부 리전 애플리케이션 LB
  • VPC에 연결된 MCP 비공개 DNS 영역 (mcp..)
  • 공개 DNS 영역 모듈 (인증서 관리자 DNS 승인) + 리전별 Google 관리형 인증서
  • PSC 인터페이스 DNS 영역 (확인할 비공개 호스트 이름이 없으면 고아가 되므로 마스터 플래그로도 관리됨)
  • mcp..의 에이전트 게이트웨이 DNS 피어링 (자동 추가됨)

8. 에이전트 레지스트리 엔드포인트 검사

에이전트 레지스트리는 에이전트가 런타임에 검색하는 서비스 (Google API 및 자체 MCP 서버)의 프로젝트별 카탈로그입니다. 모기지 에이전트는 시작 시 이를 읽고 도구를 동적으로 바인딩합니다. MCP URL은 에이전트 코드나 배포 명령에 포함되지 않습니다.

엔드포인트

Terraform이 사용자를 대신하여 실행한 작업: agent_registry_google_apis의 각 Google API에 대해 5가지 변형 (전역, mTLS 전역, 리전, 리전 mTLS, 리전 REP)을 등록했습니다. 예를 들어 aiplatform의 경우 다음과 같습니다.

gcloud alpha agent-registry services create aiplatform \
  --project=${PROJECT_ID} --location=${REGION} \
  --display-name="Vertex AI Platform" \
  --endpoint-spec-type=no-spec \
  --interfaces="url=https://aiplatform.googleapis.com,protocolBinding=JSONRPC"

gcloud alpha agent-registry services create aiplatform-mtls \
  --project=${PROJECT_ID} --location=${REGION} \
  --display-name="Vertex AI Platform mTLS" \
  --endpoint-spec-type=no-spec \
  --interfaces="url=https://aiplatform.mtls.googleapis.com,protocolBinding=JSONRPC"

gcloud alpha agent-registry services create ${REGION}-aiplatform \
  --project=${PROJECT_ID} --location=${REGION} \
  --display-name="Vertex AI Platform Locational" \
  --endpoint-spec-type=no-spec \
  --interfaces="url=https://${REGION}-aiplatform.googleapis.com,protocolBinding=JSONRPC"

gcloud alpha agent-registry services create aiplatform-${REGION}-rep \
  --project=${PROJECT_ID} --location=${REGION} \
  --display-name="Vertex AI Platform Regional (REP)" \
  --endpoint-spec-type=no-spec \
  --interfaces="url=https://aiplatform.${REGION}.rep.googleapis.com,protocolBinding=JSONRPC"

MCP 서버

Terraform은 3개의 MCP 서버도 등록합니다. 다른 MCP 서버를 등록하려면 문서의 단계를 따르세요.

gcloud alpha agent-registry services create legacy-dms \
--project=${PROJECT_ID} \
--location=${REGION} \
--display-name="Legacy DMS" \
--mcp-server-spec-type=tool-spec \
--mcp-server-spec-content=src/legacy-dms/toolspec.json \
--interfaces=url=https://dms.${DOMAIN_NAME}/mcp,protocolBinding=JSONRPC

등록된 엔드포인트와 MCP 서버를 확인합니다.

gcloud alpha agent-registry services list \
  --project=${PROJECT_ID} --location=${REGION} \
  --format="value(displayName,name)"

gcloud alpha agent-registry mcp-servers list \
  --project=${PROJECT_ID} --location=${REGION} \
  --format="value(displayName,name)"

출처: terraform/modules/agent-registry-endpoints/scripts/register_endpoints.sh.tpl

9. 에이전트 게이트웨이 구성 검토

에이전트 게이트웨이는 에이전트 런타임과 도구 간의 Google 관리 거버넌스 영역입니다. AGENT_TO_ANYWHERE 모드에서는 프로젝트의 에이전트 레지스트리에 바인딩되고 고객 소유 PSC 인터페이스를 통해 이그레스되므로 VPC의 비공개 MCP 서버에 연결할 수 있습니다.

이 게이트웨이를 직접 가져오는 경우 YAML은 다음과 같습니다.

# agent-gateway.yaml  for reference only, Terraform already created this
name: agent-gateway
protocols: [MCP]
googleManaged:
  governedAccessPath: AGENT_TO_ANYWHERE
registries:
  - "//agentregistry.googleapis.com/projects/${PROJECT_ID}/locations/${REGION}"
networkConfig:
  egress:
    networkAttachment: projects/${PROJECT_ID}/regions/${REGION}/networkAttachments/agent-gateway-na
  dnsPeeringConfig:
    domains:
      - mcp.${DOMAIN_NAME}.
    targetProject: ${PROJECT_ID}
    targetNetwork: projects/${PROJECT_ID}/global/networks/gateway-vpc
gcloud alpha network-services agent-gateways import agent-gateway \
  --source=agent-gateway.yaml \
  --location=${REGION}

게이트웨이가 Terraform으로 생성되었는지 확인합니다.

gcloud alpha network-services agent-gateways describe agent-gateway \
  --location=${REGION}

10. IAP 및 Model Armor 승인 검토

에이전트 게이트웨이는 승인을 서비스 확장 프로그램에 위임합니다. 데모에는 두 가지 정책 프로필이 적용됩니다.

  • REQUEST_AUTHZ - 헤더 단계에서 요청당 한 번 평가됩니다. 여기서는 호출 에이전트 ID에 타겟 MCP 서버에 대한 roles/iap.egressor가 있는지 확인하는 IAP를 호출하는 데 사용됩니다.
  • CONTENT_AUTHZ - 콘텐츠 삭제를 위해 확장 프로그램에 본문 이벤트를 스트리밍합니다. 여기서는 Sensitive Data Protection (SDP)을 통해 프롬프트 인젝션, 탈옥, RAI 위반, (선택적으로) PII를 검사하는 Model Armor를 호출하는 데 사용됩니다.

IAP REQUEST_AUTHZ 확장 프로그램

cat > iap-authz-extension.yaml <<EOF
name: agent-gateway-iap-authz
service: iap.googleapis.com
failOpen: true
timeout: 1s
EOF

gcloud beta service-extensions authz-extensions import agent-gateway-iap-authz \
  --source=iap-authz-extension.yaml \
  --location=${REGION} \
  --project=${PROJECT_ID}

REQUEST_AUTHZ 정책을 사용하여 에이전트 게이트웨이에 바인딩합니다.

curl -fsS -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -X POST "https://networksecurity.googleapis.com/v1alpha1/projects/${PROJECT_ID}/locations/${REGION}/authzPolicies?authz_policy_id=agent-gateway-iap-policy" \
  -d '{
    "name": "agent-gateway-iap-policy",
    "policyProfile": "REQUEST_AUTHZ",
    "action": "CUSTOM",
    "target": {
      "resources": [
        "projects/'"${PROJECT_ID}"'/locations/'"${REGION}"'/agentGateways/agent-gateway"
      ]
    },
    "customProvider": {
      "authzExtension": {
        "resources": [
          "projects/'"${PROJECT_ID}"'/locations/'"${REGION}"'/authzExtensions/agent-gateway-iap-authz"
        ]
      }
    }
  }'

Model Armor CONTENT_AUTHZ 확장 프로그램

확장 프로그램의 metadata.model_armor_settings는 Model Armor가 각 콜아웃을 평가하는 데 사용하는 요청 및 응답 템플릿 ID를 전달합니다.

cat > ma-extension.yaml <<EOF
name: agent-gateway-ma-authz
service: modelarmor.${REGION}.rep.googleapis.com
failOpen: true
timeout: 1s
metadata:
  model_armor_settings: '[
    {
      "request_template_id":  "projects/${PROJECT_ID}/locations/${REGION}/templates/agw-request-template",
      "response_template_id": "projects/${PROJECT_ID}/locations/${REGION}/templates/agw-response-template"
    }
  ]'
EOF

gcloud beta service-extensions authz-extensions import agent-gateway-ma-authz \
  --source=ma-extension.yaml \
  --location=${REGION} \
  --project=${PROJECT_ID}
curl -fsS -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -X POST "https://networksecurity.googleapis.com/v1alpha1/projects/${PROJECT_ID}/locations/${REGION}/authzPolicies?authz_policy_id=agent-gateway-ma-policy" \
  -d '{
    "name": "agent-gateway-ma-policy",
    "policyProfile": "CONTENT_AUTHZ",
    "action": "CUSTOM",
    "target": {
      "resources": [
        "projects/'"${PROJECT_ID}"'/locations/'"${REGION}"'/agentGateways/agent-gateway"
      ]
    },
    "customProvider": {
      "authzExtension": {
        "resources": [
          "projects/'"${PROJECT_ID}"'/locations/'"${REGION}"'/authzExtensions/agent-gateway-ma-authz"
        ]
      }
    }
  }'

맞춤 DLP 템플릿

Model Armor의 sdpSettings.basicConfig는 내장된 정보 유형 목록을 사용합니다. 더 세부적인 제어 (맞춤 정보 유형, 부분 마스킹, 서로게이트 대체, 가능성에 따른 수정)를 위해 sdpSettings.advancedConfig를 통해 자체 Cloud DLP 검사익명화 템플릿을 Model Armor에 지정하세요.

POSSIBLE 가능성 이상의 미국 사회보장번호를 플래그하는 검사 템플릿을 만듭니다.

curl -fsS -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -H "x-goog-user-project: ${PROJECT_ID}" \
  "https://dlp.googleapis.com/v2/projects/${PROJECT_ID}/locations/${REGION}/inspectTemplates" \
  -d '{
    "templateId": "agw-ssn-inspect-template",
    "inspectTemplate": {
      "displayName": "SSN Inspect Template",
      "inspectConfig": {
        "infoTypes": [
          { "name": "US_SOCIAL_SECURITY_NUMBER" }
        ],
        "minLikelihood": "POSSIBLE"
      }
    }
  }'

각 발견 항목을 정보 유형 토큰 (예: [US_SOCIAL_SECURITY_NUMBER])으로 바꾸는 익명화 템플릿을 만듭니다.

curl -fsS -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -H "x-goog-user-project: ${PROJECT_ID}" \
  "https://dlp.googleapis.com/v2/projects/${PROJECT_ID}/locations/${REGION}/deidentifyTemplates" \
  -d '{
    "templateId": "agw-ssn-redaction-template",
    "deidentifyTemplate": {
      "displayName": "SSN Redaction Template",
      "deidentifyConfig": {
        "infoTypeTransformations": {
          "transformations": [{
            "primitiveTransformation": { "replaceWithInfoTypeConfig": {} }
          }]
        }
      }
    }
  }'

그런 다음 sdpSettings.advancedConfig를 통해 Model Armor 템플릿의 응답 구성을 쌍으로 지정합니다. Terraform의 model_armor 모듈이 연결된 경우 advanced_config를 설정하는 위치입니다.

{
  "filterConfig": {
    "sdpSettings": {
      "advancedConfig": {
        "inspectTemplate":    "projects/${PROJECT_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template",
        "deidentifyTemplate": "projects/${PROJECT_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template"
      }
    }
  }
}

IAP 이그레스 작업자 IAM (MCP 서버별)

Terraform은 암시적 IAP 에이전트 레지스트리에 프로젝트 전체 roles/iap.egressor 바인딩을 만들지 않습니다. 실제로 평가하는 바인딩 IAP REQUEST_AUTHZ는 MCP 서버별 및 추론 엔진별이며, 에이전트가 배포되고 에이전트 ID를 알게 된 후에 부여됩니다. 'MCP 서버별 에이전트 이그레스 권한 부여' 단계에서 이를 위해 scripts/grant_agent_mcp_egress.sh를 실행합니다.

11. MCP 서버를 빌드하고 Cloud Run에 배포

cloudrun/*.yaml.tmplskaffold.yaml.tmpl 파일은 ${PROJECT_ID}, ${REGION}, ${MCP_INGRESS} (Cloud Run 인그레스 주석)을 참조합니다. 렌더링된 매니페스트가 enable_cloud_run_private_networking와 동기화되도록 Terraform 출력에서 MCP_INGRESS를 소싱한 다음 envsubst로 렌더링합니다.

Cloud Run 인그레스 구성을 내보냅니다.

  • all
  • internal-and-cloud-load-balancing (비공개 네트워킹 접근 방식을 사용하는 경우)
export MCP_INGRESS=all
envsubst '${PROJECT_ID} ${REGION} ${MCP_INGRESS}' < skaffold.yaml.tmpl > skaffold.yaml
for f in cloudrun/*.yaml.tmpl; do
  envsubst '${PROJECT_ID} ${REGION} ${MCP_INGRESS}' < "$f" > "${f%.tmpl}"
done

각 Cloud Run 서비스는 서비스별 런타임 SA Terraform으로 실행됩니다 (예: mcp-legacy-dms@${PROJECT_ID}.iam.gserviceaccount.com). 이러한 SA로 배포하려면 사용자에게 roles/iam.serviceAccountUser 권한이 있어야 합니다.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$(gcloud config get-value account)" \
  --role="roles/iam.serviceAccountUser"

Cloud Build로 빌드하고 Skaffold로 배포합니다.

skaffold run

Skaffold는 Artifact Registry 저장소에 세 개의 이미지 (legacy-dms, corporate-email, income-verification-api)를 빌드하고 각 Cloud Run 서비스가 새 다이제스트를 가리키도록 업데이트합니다.

다음을 확인합니다.

gcloud run services list --region=${REGION}

세 서비스 모두 ACTIVE 상태로 표시됩니다.

12. 모기지 에이전트를 Agent Runtime에 배포

에이전트의 종속 항목을 설치하고 배포합니다.

cd src/mortgage-agent
uv sync

uv run python deploy_agent.py \
  --project=${PROJECT_ID} \
  --region=${REGION} \
  --enable-agent-identity \
  --agent-name=mortgage-agent \
  --agent-gateway=projects/${PROJECT_ID}/locations/${REGION}/agentGateways/agent-gateway \
  --model-endpoint-location=global

스크립트가 완료되면 출력된 reasoningEngines/를 셸에 복사합니다.

export AGENT_ID=<numeric-id-from-output>
cd ../..

13. MCP 서버별 에이전트 이그레스 권한 부여

IAP REQUEST_AUTHZ 확장 프로그램은 호출 중인 특정 MCP 서버 또는 엔드포인트에서 에이전트의 roles/iap.egressor를 확인하여 각 도구 호출을 승인합니다. 에이전트-MCP 서버 이그레스 정책 만들기를 참고하세요.

스크립트 (scripts/grant_agent_mcp_egress.sh)는 projects/${PROJECT_ID}/locations/${REGION} 아래의 에이전트 레지스트리에서 MCP 서버를 열거하고 에이전트 보안 주체의 roles/iap.egressor 바인딩을 각 서버의 IAM 정책에 병합합니다 (gcloud add-iam-policy-binding 의미론 미러링).

사용 사례 1: 특정 MCP 서버로 범위가 지정된 무조건적 부여

./scripts/grant_agent_mcp_egress.sh \
  --mcp \
  --agent-id ${AGENT_ID} \
  --mcp-filter "legacy-dms income-verification"

사용 사례 2 - 특정 MCP 서버로 범위가 지정된 조건부 부여 (CEL)

단일 MCP 서버의 일부 도구로 에이전트를 제한하려면 IAM 조건을 연결하세요. 에이전트 게이트웨이는 IAP REQUEST_AUTHZ가 CEL에 노출하는 도구별 속성을 게시합니다. 여기에는 다음이 포함됩니다.

  • iap.googleapis.com/mcp.toolName
  • iap.googleapis.com/mcp.tool.isReadOnly
  • iap.googleapis.com/request.auth.type.

corporate-email에서 상담사를 읽기 전용 도구만 사용하도록 제한합니다.

./scripts/grant_agent_mcp_egress.sh \
  --mcp \
  --agent-id ${AGENT_ID} \
  --mcp-filter "corporate-email" \
  --condition-expression "api.getAttribute('iap.googleapis.com/mcp.tool.isReadOnly', false) == true" \
  --condition-title "ReadOnlyToolsOnly" \
  --condition-description "Restrict ${AGENT_ID} to read-only tools on corporate-email"

이 작업이 실행된 후 corporate-email에 쓰기 도구는 IAP REQUEST_AUTHZ에서 403 PermissionDenied을 반환합니다. 읽기 전용 도구는 계속 작동합니다.

바인딩 확인

정책 탭으로 이동하면 엔드포인트 및 Mcp 서버에 대해 생성된 정책 목록이 표시됩니다.

추가 사용 사례:

모든 MCP 서버에서 무조건 부여, 하나의 에이전트로 범위 지정

에이전트를 재배포한 후마다 이를 실행합니다. 필터도 조건도 없으면 명명된 에이전트가 레지스트리의 모든 MCP 서버에서 roles/iap.egressor를 가져옵니다.

./scripts/grant_agent_mcp_egress.sh \
  --mcp \
  --agent-id ${AGENT_ID}

14. Agent Platform 콘솔에서 에이전트 테스트

Agent Platform 콘솔에는 배포된 에이전트와 직접 채팅할 수 있는 Playground가 함께 제공됩니다. 에이전트를 Gemini Enterprise에 연결하기 전에 도구 호출을 스모크 테스트하고 트레이스를 검사하는 가장 빠른 방법입니다.

  1. Google Cloud 콘솔에서 에이전트 플랫폼 배포 페이지를 엽니다.
  2. 런타임 목록의 범위를 좁혀야 하는 경우 필터 필드를 사용한 다음 mortgage-agent 런타임을 클릭합니다.
  3. Playground 탭을 엽니다.
  4. 프롬프트를 입력하여 에이전트와 채팅합니다.
I am reviewing the Sterling familys current application. Can you summarize their 2024 and 2025 tax returns and verify if their total household income meets our 2026 debt-to-income requirements?

그러면 문서 관리 도구와 소득 확인 도구에서 응답이 반환되어야 하며, 이 응답에서 주민등록번호도 수정되어야 합니다. 5. 후속 질문을 입력합니다.

Can you send a summary of this to my email jane@example.com

상담사는 send_email 도구에 액세스할 수 없음을 확인하고 그에 따라 응답해야 합니다.

에이전트가 OpenTelemetry 계측과 함께 배포되었으므로 Playground에는 에이전트가 응답할 때 전환할 수 있는 4개의 측면 패널 뷰가 표시됩니다.

  • Trace - 에이전트 게이트웨이, IAP REQUEST_AUTHZ, Model Armor CONTENT_AUTHZ 스팬을 포함한 대화의 전체 트레이스
  • 이벤트 - 호출된 도구와 현재 턴의 이벤트 세부정보를 보여주는 그래프
  • 상태: 에이전트의 세션 상태 및 도구 입력/출력
  • 세션: 이 런타임에 대해 시작한 모든 세션

15. IAP 승인 적용

이제 배포를 검증했으므로 정책을 시행하도록 IAP 시행 모드를 null로 업데이트할 수 있습니다. terraform.tfvars를 열고 모드를 DRY_RUN에서 null로 업데이트합니다.

# IAP Enforcement Mode ("DRY_RUN" or null)
agent_gateway_iap_iam_enforcement_mode = null

변경사항을 적용합니다.

terraform apply

Playground로 돌아가 대화를 다시 시도해 보세요.

  1. Google Cloud 콘솔에서 에이전트 플랫폼 배포 페이지를 엽니다.
  2. 런타임 목록의 범위를 좁혀야 하는 경우 필터 필드를 사용한 다음 mortgage-agent 런타임을 클릭합니다.
  3. Playground 탭을 엽니다.
  4. 프롬프트를 입력하여 에이전트와 채팅합니다.
I am reviewing the Sterling familys current application. Can you summarize their 2024 and 2025 tax returns and verify if their total household income meets our 2026 debt-to-income requirements?

그러면 문서 관리 도구와 소득 확인 도구에서 응답이 반환되어야 하며, 이 응답에서 주민등록번호도 수정되어야 합니다. 5. 후속 질문을 입력합니다.

Can you send a summary of this to my email jane@example.com

모든 것이 올바르게 설정된 경우 상담사는 승인 정책으로 인해 이메일을 보낼 수 없다고 응답해야 합니다.

16. Gemini Enterprise 설정 및 테스트

Gemini Enterprise 설정

Gemini Enterprise 시작 가이드를 따르세요.

ADK 에이전트를 Gemini Enterprise에 등록

Gemini Enterprise에 에이전트를 등록하는 단계는 여기에서 확인할 수 있습니다.

  1. Google Cloud 콘솔에서 Gemini Enterprise 페이지로 이동합니다.
  2. 에이전트가 등록된 Gemini Enterprise 앱을 선택합니다.
  3. Gemini Enterprise 웹 앱이 준비되었습니다 섹션에 표시된 URL을 엽니다.
  4. 왼쪽 메뉴에서 에이전트 탭을 선택하여 에이전트 갤러리를 엽니다.
  5. Mortgage Assistant Agent를 선택하고 채팅을 시작합니다.

Agent Runtime Playground에서 동일한 프롬프트를 사용해 보세요.

초기 프롬프트:

I am reviewing the Sterling familys current application. Can you summarize their 2024 and 2025 tax returns and verify if their total household income meets our 2026 debt-to-income requirements?

후속 질문:

Can you send a summary of this to my email jane@example.com

콘솔의 에이전트 배포 섹션으로 돌아가 에이전트 배포를 선택하고 트레이스 탭으로 이동하면 Gemini Enterprise에서 시작된 호출을 보여주는 스팬에 Gemini Assistant 에이전트가 표시됩니다.

17. 문제 해결 및 일반적인 수정사항

  • terraform apply이 에이전트 게이트웨이에서 '리소스가 생성 중이므로 업데이트할 수 없습니다'라는 메시지와 함께 실패함 — 승인 정책이 연결되기 전에 게이트웨이의 테넌트 프로젝트가 안정화되는 데 약 30초가 걸립니다. 모듈의 time_sleep.wait_for_gateway에서 이를 처리하므로 terraform apply을 다시 실행하기만 하면 됩니다.
  • 에이전트에서 'MCP 서버를 찾을 수 없음'이라고 보고하거나 유틸리티 도구로만 부팅됨terraform.tfvars에서 enable_agent_registry_endpoints = true를 확인한 후 다음 단계를 따르세요.
    gcloud alpha agent-registry mcp-servers list \
      --project=${PROJECT_ID} --location=${REGION}
    
    Cloud Run MCP 서비스별로 하나씩 세 개의 항목이 표시됩니다. 목록이 비어 있으면 VPC 내부에서 MCP 서비스에 연결할 수 있는지, 에이전트 게이트웨이가 레지스트리를 채웠는지 확인합니다 (첫 번째 프록시 도구 목록에서 지연 방식으로 실행됨).
  • 도구 호출에서 403 PermissionDenied가 반환됨 - scripts/grant_agent_mcp_egress.sh를 다시 실행합니다. 가장 일반적인 원인은 에이전트를 재배포한 후 다시 부여하는 것을 잊은 것입니다 (reasoningEngines/는 배포마다 변경됨).
  • skaffold run이 '서비스 계정에 대한 권한이 거부됨' 오류와 함께 실패합니다. roles/iam.serviceAccountUser이 누락되었습니다. 이전 단계에서 자체 부여를 다시 실행합니다.
  • 에이전트 게이트웨이에서 MCP LB로의 DNS 피어링 오류agent_gateway_dns_peering_config.target_networkprojects/${PROJECT_ID}/global/networks/${VPC_NAME}와 정확히 일치하고 모든 domains 항목이 후행 점으로 끝나는지 확인합니다.
  • terraform plan이 Cloud Run 이미지 태그를 업데이트하려고 계속 시도합니다. lifecycle { ignore_changes } 규칙으로 인해 이러한 문제가 발생해서는 안 됩니다. 그렇다면 skaffold run 이후에 terraform.tfvars에서 mcp_services[*].image를 수정하지 않았는지 확인합니다.

18. 삭제

추론 엔진은 Terraform에서 관리하지 않습니다 (ADK SDK에서 생성). 수동으로 삭제하는 방법:

gcloud beta ai reasoning-engines delete ${AGENT_ID} \
  --region=${REGION} --project=${PROJECT_ID}

Terraform에서 만든 모든 항목을 철거합니다.

cd terraform
terraform destroy
cd ..

이 Codelab을 위해서만 공개 DNS 영역을 만든 경우 다음 단계를 따르세요.

gcloud dns managed-zones delete agw-example-com

마지막으로 Terraform 상태 버킷을 삭제합니다.

gcloud storage rm -r gs://${PROJECT_ID}-tfstate

19. 축하합니다

축하합니다. 에이전트 게이트웨이를 사용하여 멀티 도구 ADK 에이전트에 대한 포괄적인 에이전트 거버넌스를 구현했습니다. 에이전트 게이트웨이는 중앙 집중식 네트워크 컨트롤 플레인 역할을 함으로써 비공개 도구에 대한 보안 이그레스 경로를 설정하고, IAP(Identity-Aware Proxy)를 통해 세부적인 ID 기반 IAM 정책을 적용하고, 통합된 Model Armor 가드레일을 사용하여 콘텐츠 상호작용을 정리할 수 있었습니다.

학습한 내용

  • 에이전트-투-애니웨어 이그레스 트래픽의 중앙 거버넌스 레이어로 에이전트 게이트웨이를 배포하고 구성하는 방법
  • 관리되는 동적 런타임 도구 검색을 위해 에이전트 레지스트리를 통합하는 방법
  • 도구별 및 조건 기반 IAM 정책을 작성하고 적용하여 에이전트 실행 경로를 엄격하게 제어하는 방법
  • Agent Gateway Service Extensions를 활용하여 Model Armor 정책을 적용하고 민감한 에이전트 트래픽을 자동으로 가로채고 수정하는 방법

참조 문서