Delegate authorization with Service Extensions

Use this page to learn how to delegate authorization for Agent Gateway to Identity-Aware Proxy, Model Armor, and other custom authorization engines by using Service Extensions.

Authorization policies and extensions

Authorization policies let you enforce centralized access control and governance policies on traffic passing through endpoints published by Agent Gateway. To handle complex access control, content safety, and governance decisions, Agent Gateway lets you configure authorization policies with authorization extensions that let you delegate authorization and content safety decisions to designated authorization engines of your choice.

An authorization extension intercepts requests passing through an Agent Gateway deployment and makes a real-time gRPC call to the designated authorization service. This allows the service to inspect, modify, or block traffic before it continues to its destination. You can delegate authorization to Google Cloud services such as Identity-Aware Proxy, Model Armor, and semantic governance policies, or to any custom authorization engine of your choice.

Authorization policies use policy profiles to determine the type of traffic data sent to the authorization extension:

  • Request-based authorization (REQUEST_AUTHZ): Evaluates HTTP request headers before any application payload is processed. This profile is used for identity verification and access control, such as delegating authorization to Identity-Aware Proxy.
  • Content-based authorization (CONTENT_AUTHZ): Evaluates complete HTTP request and response payloads. This profile is used for deep content inspection and AI safety, such as delegating to Model Armor for prompt and response safety or to semantic governance policies for natural-language constraint enforcement.

Custom authorization engines can use either REQUEST_AUTHZ or CONTENT_AUTHZ extensions depending on whether they inspect headers or full application payloads.

You can configure authorization extensions separately for request-based and content-based policies, or combine both on a gateway for comprehensive security. For recommended configurations, see Recommended ingress and egress configuration.

To learn more about authorization policies, policy profiles, and their use cases, see Authorization policies overview.

For comprehensive security across the entire agent lifecycle, we recommend the following multi-gateway architecture pattern:

  • Client-to-agent gateways: Client-to-agent (ingress) gateways only support a single CONTENT_AUTHZ policy. This means you cannot use Model Armor and semantic governance policies together on ingress. We strongly recommend using a Model Armor CONTENT_AUTHZ policy to protect against prompt injection attacks. However, if you want to use a semantic governance policy extension instead, you must ensure that Model Armor is not configured on the gateway. Other types of service extensions are not supported for ingress gateways.

  • Agent-to-Anywhere gateways: Agent-to-Anywhere (egress) gateways support up to four authorization policies. Egress gateways support both REQUEST_AUTHZ and CONTENT_AUTHZ policy profiles, and you can configure multiple policies of each type within this limit.

    We recommend the following configuration:

    • A REQUEST_AUTHZ policy delegating to Identity-Aware Proxy (IAP) to authorize the agent identity.
    • One or more CONTENT_AUTHZ policies delegating further decisions to Model Armor or semantic governance policies to protect against sensitive data exposure and enforce natural-language constraints on outgoing tool calls and responses.

    See Policy evaluation on egress for more information on how policies are evaluated.

This multi-gateway topology ensures that Model Armor screens incoming prompts while IAP, Model Armor, and semantic governance policies screen outgoing responses.

Policy evaluation on egress

When multiple authorization policies are configured on an egress gateway, they are evaluated sequentially according to their policy profile type:

  1. REQUEST_AUTHZ (header-based) policies: These policy types are evaluated first. For example, an IAP extension checks the mTLS identity of the calling agent and validates its IAM allow policies before any content is processed. If the request fails this check, it is immediately rejected.
  2. CONTENT_AUTHZ (content-based) policies: These policy types are evaluated next. If the request passes the header-based check, the payload is streamed to the content-based authorization extension (such as the semantic governance policy engine) for deep content inspection and compliance evaluation.

Before you begin

Before you begin, ensure that you meet the following requirements:

  • The Agent Gateway is deployed. See Configure Agent Gateway.

  • You must have the networkservices.agentGateways.use IAM permission on the deployed Agent Gateway resource to be able to attach authorization policies to the gateway.

Configure authorization policies with extensions

This section shows you how to configure authorization policies that delegate authorization and content safety decisions to Identity-Aware Proxy, Model Armor, and other custom services.

Delegate authorization to IAP

You can configure a request authorization extension to delegate access decisions for authorization policies to IAP.

The following steps show you how to configure an authorization extension with an authorization policy for an Agent Gateway instance.

  1. Before you begin: Turn off enforcement for the Disable binding access policy to resource (constraints/iam.managed.disableAccessPolicyBindings) managed organization policy constraint. By default, this boolean constraint is enabled for new organizations and will prevent you from binding an IAM Unified Access Policy to a resource. For more information, see Updating policies with boolean rules.

  2. Create the required IAM egress policies for your agents and tools. For more information, see Create IAM agent policies.

  3. See Configure Agent Gateway in Agent-to-Anywhere (Egress) mode to enable IAP while creating the Agent Gateway (by using the Access authorization parameter).

  4. Configure an authorization extension to point to IAP.

    1. Define the extension in a YAML file. Use the sample values provided. If you want to deploy the extension in a dry run audit-only mode, to test the authorization policy without enforcing it, you can specify the iamEnforcementMode field inside the metadata block.

      cat >iap-request-authz-extension.yaml <<EOF
      name: my-iap-request-authz-ext
      service: iap.googleapis.com
      failOpen: false
      timeout: 1s
      metadata:
        iapPolicyVersion: "V2"
      EOF
      

      If you want to deploy the extension in a dry run audit-only mode, to test the authorization policy without enforcing it, you can specify the iamEnforcementMode field inside the metadata block. This lets you verify your policy and minimize the risk of disrupting traffic due to configuration errors:

      cat >iap-request-authz-extension.yaml <<EOF
      name: my-iap-request-authz-ext
      service: iap.googleapis.com
      failOpen: false
      timeout: 1s
      metadata:
        iapPolicyVersion: "V2"
        iamEnforcementMode: "DRY_RUN"
      EOF
      

      Remove the iamEnforcementMode: "DRY_RUN" field from the metadata block when you're ready to start enforcing policies.

    2. Import the authorization extension. Use the gcloud service-extensions authz-extensions import command with the following sample values.

      gcloud service-extensions authz-extensions import my-iap-request-authz-ext \
          --source=iap-request-authz-extension.yaml \
          --location=LOCATION
      
  5. In the same project, configure an authorization policy that delegates the decision to the extension.

    1. Define an authorization policy that associates the my-iap-request-authz-ext extension with your gateway. Use the sample values provided.

      cat >iap-request-authz-policy.yaml <<EOF
      name: my-iap-request-authz-policy
      target:
        resources:
          - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
      policyProfile: REQUEST_AUTHZ
      action: CUSTOM
      customProvider:
        authzExtension:
          resources:
            - "projects/PROJECT_ID/locations/LOCATION/authzExtensions/my-iap-request-authz-ext"
      EOF
      

      Replace PROJECT_ID with your project ID.

    2. Import the authorization policy to the project. Use the gcloud network-security authz-policies import command with the following sample values.

      gcloud network-security authz-policies import my-iap-request-authz-policy \
          --source=iap-request-authz-policy.yaml \
          --location=LOCATION
      

Delegate authorization to Model Armor

You can configure an authorization extension to delegate content security decisions for authorization policies to Model Armor.

The following example shows how to configure such an authorization extension with an authorization policy for Agent Gateway.

Console

To use the Google Cloud console to enable Model Armor for Agent Gateway, perform the following steps:

  1. Create the required Model Armor templates.

  2. See Configure Agent Gateway to enable Model Armor while creating the Agent Gateway (by using the Enable Model Armor checkbox). Model Armor templates are supported in both Client-to-Agent and Agent-to-Anywhere modes.

  3. When you're using Model Armor, you must grant the Agent Gateway service account the permissions required to be able to use the Model Armor templates. The service account is of the format: service-PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com, where PROJECT_NUMBER is the project number of the project where you created the gateway.

    You must complete this step even if both the gateway and the templates are in the same project. Grant the following roles:

    • The roles/modelarmor.calloutUser and roles/serviceusage.serviceUsageConsumer roles in the project that contains the gateway.
    • The roles/modelarmor.user role in the project that contains the Model Armor templates.

    You will need to use the gcloud CLI to complete this step.

    gcloud projects add-iam-policy-binding GATEWAY_PROJECT_ID \
        --member=serviceAccount:service-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com \
        --role=roles/modelarmor.calloutUser
    gcloud projects add-iam-policy-binding GATEWAY_PROJECT_ID \
        --member=serviceAccount:service-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com \
        --role=roles/serviceusage.serviceUsageConsumer
    gcloud projects add-iam-policy-binding MODEL_ARMOR_PROJECT_ID \
        --member=serviceAccount:service-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com \
        --role=roles/modelarmor.user
    

    Replace the following:

    • GATEWAY_PROJECT_ID: The project ID of the project where you created the gateway.
    • GATEWAY_PROJECT_NUMBER: The project number of the project where you created the gateway.
    • MODEL_ARMOR_PROJECT_ID: The project ID of the project that contains the Model Armor template.

    If you're using the gateway for Agent Runtime, the Agent Runtime service agent also requires these permissions as documented in Route Agent Runtime traffic through Agent Gateway.

gcloud

  1. Create the required Model Armor templates.

  2. When you're using Model Armor, you must grant the Agent Gateway service account the permissions required to be able to use the Model Armor templates. The service account is of the format: service-PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com, where PROJECT_NUMBER is the project number of the project where you created the gateway.

    You must complete this step even if both the gateway and the templates are in the same project. Grant the following roles:

    • The roles/modelarmor.calloutUser and roles/serviceusage.serviceUsageConsumer roles in the project that contains the gateway.
    • The roles/modelarmor.user role in the project that contains the Model Armor template.
    gcloud projects add-iam-policy-binding GATEWAY_PROJECT_ID \
        --member=serviceAccount:service-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com \
        --role=roles/modelarmor.calloutUser
    gcloud projects add-iam-policy-binding GATEWAY_PROJECT_ID \
        --member=serviceAccount:service-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com \
        --role=roles/serviceusage.serviceUsageConsumer
    gcloud projects add-iam-policy-binding MODEL_ARMOR_PROJECT_ID \
        --member=serviceAccount:service-GATEWAY_PROJECT_NUMBER@gcp-sa-dep.iam.gserviceaccount.com \
        --role=roles/modelarmor.user
    

    Replace the following:

    • GATEWAY_PROJECT_ID: The project ID of the project where you created the gateway.
    • GATEWAY_PROJECT_NUMBER: The project number of the project where you created the gateway.
    • MODEL_ARMOR_PROJECT_ID: The project ID of the project that contains the Model Armor template.
  3. Configure the authorization extension to point to Model Armor.

    1. Define the extension in a YAML file. Use the sample values provided.

      cat >ma-content-authz-extension.yaml <<EOF
      name: my-ma-content-authz-ext
      service: modelarmor.LOCATION.rep.googleapis.com
      metadata:
        model_armor_settings: '[
          {
          "response_template_id": "projects/MODEL_ARMOR_PROJECT_ID/locations/LOCATION/templates/TEMPLATE_ID",
          "request_template_id": "projects/MODEL_ARMOR_PROJECT_ID/locations/LOCATION/templates/TEMPLATE_ID"
          }
        ]'
      failOpen: false
      timeout: 1s
      EOF
      
    2. Import the authorization extension. Use the gcloud service-extensions authz-extensions import command with the following sample values.

      gcloud service-extensions authz-extensions import my-ma-content-authz-ext \
         --source=ma-content-authz-extension.yaml \
         --location=LOCATION
      
  4. Configure an authorization policy with the extension.

    1. Define an authorization policy that associates the extension my-ma-content-authz-ext with an Agent Gateway.

      Agent-to-Anywhere

      cat >ma-content-authz-policy.yaml <<EOF
      name: my-ma-content-authz-policy
      target:
        resources:
          - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
      policyProfile: CONTENT_AUTHZ
      action: CUSTOM
      customProvider:
        authzExtension:
          resources:
            - "projects/PROJECT_ID/locations/LOCATION/authzExtensions/my-ma-content-authz-ext"
      httpRules:
        - to:
            operations: [ { "paths": [ { "prefix": "/" } ] } ]
          when: >
            request.headers['content-type'] == 'application/json' ||
            request.headers['content-type'].startsWith('text/')
      EOF
      

      Note the following:

      • The value of policyProfile is set to CONTENT_AUTHZ. This indicates that the custom policy provider processes request and response traffic including the request body.

      • The httpRules parameter demonstrates how to use CEL attributes to create conditions that match the specific traffic you want to forward to Model Armor for evaluation. In this example, the rules match all traffic with application/json or text/ content types. We recommend using such rules to limit Model Armor evaluation to relevant traffic. This lets you route supported LLM API, MCP, and A2A traffic to Model Armor while excluding internal traffic such as agent gRPC calls.

      Client-to-Agent

      cat >ma-content-authz-policy.yaml <<EOF
      name: my-ma-content-authz-policy
      target:
        resources:
          - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
      policyProfile: CONTENT_AUTHZ
      action: CUSTOM
      customProvider:
        authzExtension:
          resources:
            - "projects/PROJECT_ID/locations/LOCATION/authzExtensions/my-ma-content-authz-ext"
      EOF
      

      The value of policyProfile is set to CONTENT_AUTHZ. This indicates that the custom policy provider processes request and response traffic including the request body.

    2. Import the authorization policy to the project. Use the gcloud network-security authz-policies import command with the following sample values.

      gcloud network-security authz-policies import my-ma-content-authz-policy \
        --source=ma-content-authz-policy.yaml \
        --location=LOCATION
      

Delegate authorization to custom authorization extensions

You can configure custom authorization extensions to delegate decisions to custom services. These custom extensions can target only fully qualified domain names (FQDNs).

When you use FQDN targets, the extension uses the HTTP2 protocol with TLS encryption to communicate with endpoints on port 443. However, the extension doesn't validate the server certificate. Therefore, for better security, you must ensure that the resolved endpoints are within the VPC network. Also ensure that you have DNS peering set up between the Agent Gateway project and your VPC network.

  1. To configure an authorization extension with an authorization policy for a specific FQDN, such as mycustomauthz.internal.net, specify it as the value for service in the extension YAML file as the following example shows. This example assumes that you have deployed a server in your VPC network implementing the ext_proc protocol in FULL_DUPLEX_STREAMED body processing mode.

    cat >custom-authz-extension.yaml <<EOF
    name: my-custom-authz-ext
    service: mycustomauthz.internal.net
    failOpen: false
    timeout: 1s
    EOF
    
  2. Create the authorization extension to point to the custom service.

    gcloud beta service-extensions authz-extensions import custom-authz-extension \
      --source=custom-authz-extension.yaml \
      --location=LOCATION
    
  3. After you create the extension, configure a CUSTOM authorization policy that delegates decisions to the authorization extension.

      cat >authz-policy.yaml <<EOF
      name: authz-with-extension
      target:
        resources:
          - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
      policyProfile: CONTENT_AUTHZ
      action: CUSTOM
      customProvider:
        authzExtension:
          resources:
            - "projects/PROJECT_ID/locations/LOCATION/authzExtensions/custom-authz-extension"
      EOF
    
  4. Create the authorization policy.

    gcloud network-security authz-policies import authz-policy-with-extension \
    --source=authz-policy.yaml \
    --location=LOCATION
    

Note that when an authorization extension is associated with an authorization policy using the CONTENT_AUTHZ profile as demonstrated in this example, the gateway invokes the extension for request and response payloads (headers and bodies), allowing deep content inspection, prompt guardrails, and data sanitization for your agent traffic. By default, CONTENT_AUTHZ policies use the Envoy ext_proc protocol in FULL_DUPLEX_STREAMED mode to process body events.

Combine IAP authorization with Model Armor guardrails

For comprehensive security, we recommend that you set up a CUSTOM authorization policy with a REQUEST_AUTHZ policy profile and another CUSTOM authorization policy with a CONTENT_AUTHZ policy profile.

The following example uses IAP as a centralized request authorization system and Model Armor for AI guardrails. As shown in previous examples, you can swap each of these with service extensions to use your own custom solutions.

  1. Configure a REQUEST_AUTHZ authorization extension that delegates to IAP and an authorization policy that points to the extension.

    1. Define the authorization extension. The iapPolicyVersion field under metadata is mandatory.

      cat >iap-extension.yaml <<EOF
      name: iap-extension
      service: iap.googleapis.com
      failOpen: false
      timeout: 1s
      metadata:
        iapPolicyVersion: "V2"
      EOF
      
    2. Create the authorization extension.

      gcloud service-extensions authz-extensions import iap-extension \
      --source=iap-extension.yaml \
      --location=LOCATION
      

      Replace LOCATION with the region of the extension.

    3. Configure the REQUEST_AUTHZ authorization policy that delegates to the extension.

      cat >authz-policy-request-authz.yaml <<EOF
      name: authz-iap
      target:
        resources:
        - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
      policyProfile: REQUEST_AUTHZ
      action: CUSTOM
      customProvider:
        authzExtension:
          resources:
          - "projects/PROJECT_ID/locations/LOCATION/authzExtensions/iap-extension"
      EOF
      

      Replace the following:

      • PROJECT_ID: Your project ID.
      • LOCATION: The location of the resources.
      • AGENT_GATEWAY_NAME: The name of the Agent Gateway.
    4. Create the authorization policy.

      gcloud network-security authz-policies import authz-iap \
      --source=authz-policy-request-authz.yaml \
      --location=LOCATION
      
  2. Configure a CONTENT_AUTHZ authorization extension that delegates to Model Armor and an authorization policy that points to the extension.

    1. Define the extension.

      cat >ma-extension-file.yaml <<EOF
      name: ma-extension
      service: modelarmor.LOCATION.rep.googleapis.com
      metadata:
        model_armor_settings: '[
          {
          "response_template_id": "projects/MODEL_ARMOR_PROJECT_ID/locations/LOCATION/templates/RESPONSE_TEMPLATE_ID",
          "request_template_id": "projects/MODEL_ARMOR_PROJECT_ID/locations/LOCATION/templates/REQUEST_TEMPLATE_ID"
          }
        ]'
      failOpen: false
      timeout: 1s
      EOF
      

      Replace the following:

      • LOCATION: The region where your Model Armor templates reside.
      • MODEL_ARMOR_PROJECT_ID: The Project ID containing the Model Armor templates.
      • RESPONSE_TEMPLATE_ID: The ID of the response template.
      • REQUEST_TEMPLATE_ID: The ID of the request template.
    2. Create the authorization extension.

      gcloud service-extensions authz-extensions import ma-extension \
      --source=ma-extension-file.yaml \
      --location=LOCATION
      
    3. Configure the CONTENT_AUTHZ authorization policy that delegates to the extension.

      cat >authz-policy-content-authz.yaml <<EOF
      name: authz-ma
      target:
        resources:
        - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
      policyProfile: CONTENT_AUTHZ
      action: CUSTOM
      customProvider:
        authzExtension:
          resources:
          - "projects/PROJECT_ID/locations/LOCATION/authzExtensions/ma-extension"
      EOF
      
    4. Create the authorization policy.

      gcloud network-security authz-policies import ma-authz-policy \
      --source=authz-policy-content-authz.yaml \
      --location=LOCATION
      

When an authorization extension is associated with a CONTENT_AUTHZ profile, it receives all ext_proc events, including request and response headers, body, and trailers. If your ext_proc-based authorization extension is capable of handling both request-time authorization and content-based authorization, we recommend configuring a single CUSTOM authorization policy with the CONTENT_AUTHZ policy profile. This policy should point to your versatile authorization extension. This approach enables both types of authorization through a single extension and ext_proc connection, which can improve latency profiles.

Delegate authorization to Semantic governance policies

You can configure an authorization extension to delegate intent-gating and natural-language constraint decisions for authorization policies to the Semantic governance policy engine (semanticGovernancePolicyEngine).

To learn how to provision the policy engine and create the required CONTENT_AUTHZ authorization policy and authorization extension binding on your gateway, see Connect the policy engine to Agent Gateway.

Authorization based on MCP protocol attributes

Agent Gateway parses the MCP protocol payload in a request and makes the extracted attributes available for authorization policies.

You can restrict access based on MCP method parameters such as the names of specific tools. This section shows you two examples, one for an ALLOW policy and one for DENY.

  1. Configure the authorization policy.

    ALLOW policy example

    This example allows access to a specific set of tools on the MCP server and the base protocol features but disallows access to prompts and resources.

    When writing an ALLOW policy, make sure you specify baseProtocolMethodsOption: MATCH_BASE_PROTOCOL_METHODS so that non-access specific MCP RPCs like initialize, logging, completion, notifications, and ping continue to work. Failing to do so results in the inability to establish an MCP session.

    cat >authz-policy-restrict-tools.yaml <<EOF
    name: my-authz-policy-restrict-tools
    target:
      resources:
      - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
    policyProfile: REQUEST_AUTHZ
    httpRules:
    - to:
        operations:
        - mcp:
            baseProtocolMethodsOption: MATCH_BASE_PROTOCOL_METHODS
            methods:
            - name: "tools/list"
            - name: "tools/call"
              params:
              - exact: "get_weather"
              - exact: "get_location"
    action: ALLOW
    EOF
    

    DENY policy example

    This example disallows all prompts/ method access to an MCP server behind an Agent Gateway.

    cat >authz-policy-disallow-prompts.yaml <<EOF
    name: my-authz-policy-disallow-prompts
    target:
      resources:
      - "projects/PROJECT_ID/locations/LOCATION/agentGateways/AGENT_GATEWAY_NAME"
    policyProfile: REQUEST_AUTHZ
    httpRules:
    - to:
        operations:
        - mcp:
            methods:
            - name: "prompts"
    action: DENY
    EOF
    
  2. Create the authorization policy.

    gcloud network-security authz-policies import AUTHZ_POLICY_NAME \
    --source=AUTH_POLICY_YAML_FILE_PATH \
    --location=LOCATION
    

    Replace the following:

    • AUTHZ_POLICY_NAME: The name of the authorization policy.
    • AUTH_POLICY_YAML_FILE_PATH: The path to the authorization policy YAML file.
    • LOCATION: The location of the resources.

Limitations

The following limitations apply when you use authorization policies:

  • The maximum number of authorization policies per gateway depends on the gateway mode:

    • For Agent-to-Anywhere (egress) gateways, you can configure a maximum of four authorization policies per gateway, regardless of policy profile (REQUEST_AUTHZ or CONTENT_AUTHZ).
    • For Client-to-Agent (ingress) gateways, you can configure a maximum of one CONTENT_AUTHZ policy.

    For more information, see Recommended ingress and egress configuration.

  • If you use custom authorization extensions with the CONTENT_AUTHZ profile, they must support the ext_proc protocol and FULL_DUPLEX_STREAMED mode for body events.

  • If you configure multiple custom authorization policies that use the same profile, their execution order is not guaranteed.

Additionally, see the following sections for more information about the limitations of authorization extensions:

What's next

Codelab

Learn how to govern agentic workloads with Agent Gateway on Gemini Enterprise Agent Platform.

Guide

Learn how to monitor Agent Gateway.

Troubleshooting

Learn how to troubleshoot Agent Gateway connectivity.