Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Agent Platform demo — Model Armor + Agent Gateway + ADK agent

A minimal working example on Google Cloud's Gemini Enterprise Agent Platform (ex–Vertex AI): a dummy ADK agent deployed to Agent Runtime behind an ingress Agent Gateway, with a Model Armor template attached and enforcing on that gateway.

Everything described below is in this repository and was applied against a live GCP project. Nothing is aspirational — features that are not implemented are listed explicitly under Not included and Private Preview dependencies.

Contents

terraform/main.tf               Model Armor template, both gateways, VPC + PSC attachment, APIs
terraform/iam_model_armor.tf    Service-agent IAM, Model Armor authz extension + authz policy
terraform/terraform.tfvars.example   Copy to terraform.tfvars and fill in
terraform/.terraform.lock.hcl   Provider pins (google + google-beta 7.41.0)
agent/dummy_agent/agent.py      The ADK agent: one Gemini LlmAgent + one echo tool
agent/deploy.py                 Deploys the agent to Agent Runtime, bound to the ingress gateway
agent/showcase.py               Sends a benign prompt and a jailbreak prompt to the deployed agent
agent/requirements.txt          google-cloud-aiplatform[adk,agent_engines]>=1.112

No Terraform state, provider cache, or virtualenv is shipped.

What the stack creates

Terraform (terraform/)

Resource Detail
google_model_armor_template.demo RAI filters (hate speech, harassment, sexually explicit, dangerous — all MEDIUM_AND_ABOVE), prompt-injection/jailbreak filter, malicious-URI filter, basic Sensitive Data Protection
google_network_services_agent_gateway.ingress CLIENT_TO_AGENT, governs client → agent traffic
google_network_services_agent_gateway.egress AGENT_TO_ANYWHERE, provisioned but not bound to the agent
google_compute_network / _subnetwork / _network_attachment VPC 10.10.0.0/24 + PSC-Interface attachment, required only by the egress gateway
google_network_services_authz_extension.model_armor Model Armor as a Google-API callout, EXT_PROC_GRPC, fail_open = false
google_network_security_authz_policy.model_armor_binding CUSTOM / CONTENT_AUTHZ, binds the extension to the ingress gateway
google_project_iam_member.* Service-agent grants (see IAM below)
google_project_service.apis Enables aiplatform, networkservices, networksecurity, agentregistry, modelarmor, compute, iam

Agent (agent/) — an ADK LlmAgent on gemini-2.5-flash with a single echo_tool. The agent code contains no gateway references: gateway routing is a deployment-time binding on the Agent Runtime instance (agent_gateway_config in deploy.py), not application code. The deployment sets identity_type = AGENT_IDENTITY, which is required for gateway-governed agents.

What was verified

Applied and run end-to-end on a disposable GCP project in us-central1 with provider 7.41.0:

  • terraform apply creates all resources listed above.
  • deploy.py deploys the agent and the ingress binding succeeds.
  • showcase.py: the benign prompt returns a normal answer; the jailbreak/prompt-injection prompt is rejected at the gateway with 403 "Model Armor: Prompt violates content security configurations".

Only prompt-side screening was exercised. The template is attached as both request and response template, but response-side blocking was not triggered during testing.

Not included

  • No egress binding. The egress gateway is created but the agent is not bound to it. The agent_to_anywhere_config line in deploy.py is commented out — see Private Preview dependencies.
  • No Agent Registry destination registration. No Terraform resource exists for it in provider 7.x.
  • No client authorization policy (IAP) on the ingress gateway. Access to the agent is plain project IAM; the gateway does content screening only.
  • No staging bucket. deploy.py expects STAGING_BUCKET to already exist.
  • No remote state backend. The Terraform uses local state.
  • No CI, tests, or teardown automation.
  • No least-privilege custom IAM role. A commented-out alternative is in terraform/iam_model_armor.tf; it requires roles/iam.roleAdmin on the deploying identity, so the stack uses predefined roles instead.

Private Preview dependencies

These require allowlisting by Google; the repo cannot work around them.

  • Binding an Agent Runtime instance to an Agent Gateway. The gateway resources themselves apply on a normal project, but deploy.py will fail without the allowlist.
  • Registering egress destinations in Agent Registry. Binding the agent to the egress gateway forces all outbound traffic through it, and every destination not registered is blocked — including the Gemini endpoint, so the container fails to start (503 UNAVAILABLE ... Handshake read failed). Registration is a separate Private Preview capability with no Terraform resource, which is why the egress binding is left commented out.

Constraints

  • One ingress and one egress gateway per project + region.
  • An agent cannot be unbound from a gateway once deployed. Use a disposable project.
  • No cross-region. The Model Armor template, the gateways and the agent must all be in the same region. Validated on us-central1.

Running it

1. Infrastructure

cd terraform
cp terraform.tfvars.example terraform.tfvars   # set project_id
terraform init
terraform apply

On a brand-new project, enable two bootstrap APIs once first (Terraform enables the rest):

gcloud services enable cloudresourcemanager.googleapis.com serviceusage.googleapis.com --project=<PROJECT_ID>

2. Agent

cd agent
python -m venv .venv && .venv/bin/pip install -r requirements.txt
export GOOGLE_CLOUD_PROJECT=<PROJECT_ID>
export GOOGLE_CLOUD_LOCATION=us-central1
export STAGING_BUCKET=gs://<PROJECT_ID>-agent-staging   # must exist; create it first
.venv/bin/python deploy.py

3. Showcase

.venv/bin/python showcase.py

Expected output: the benign prompt returns a normal answer; the jailbreak prompt is rejected with 403 PERMISSION_DENIED.

Implementation notes

  • Auth. Both scripts use Application Default Credentials (gcloud auth application-default login). The Python SDK does not honour GOOGLE_IMPERSONATE_SERVICE_ACCOUNT; to run as a service account, create an impersonated_service_account ADC file and point GOOGLE_APPLICATION_CREDENTIALS at it.
  • IAM. iam_model_armor.tf grants roles/networkservices.admin to both the Reasoning Engine service agent (gcp-sa-aiplatform-re) and the Vertex AI service agent (gcp-sa-aiplatform). The second one is not optional: the deploy fails with "Permission denied to get Agent Gateway ... ensure Vertex AI Service Agent has networkservices.agentGateways.get" without it. The Service Extensions service agent (gcp-sa-dep) gets the Model Armor callout roles.
  • Model Armor attachment is two resources, not a gateway field: the authz extension plus the CONTENT_AUTHZ authz policy that binds it. Without the policy the extension is never invoked. load_balancing_scheme must be left unset on both — an Agent Gateway is not a load balancer, and INTERNAL_MANAGED is rejected by the authz policy. authority must not be set on extensions that call Google APIs.
  • Extension metadata keys are request_template_id / response_template_id. Other key names are accepted by the API but silently ignored, which leaves the extension attached and screening nothing.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages