Limit agent permissions with scoped credentials

When your orchestrator agent calls a remote Agent2Agent (A2A) agent, scoping credentials helps ensure that the remote agent receives only the permissions needed for that request. After discovering an agent in Agent Registry, you can include your user's credentials or generate scoped tokens using the Agent Identity auth manager with restricted OAuth scopes or Credential Access Boundaries for Cloud Storage.

Before you begin

Before you limit agent permissions with scoped credentials for A2A calls, complete the following steps:

  1. Set up Agent Registry.
  2. For a single-project setup, get the project ID of the governance project where Agent Registry is enabled. If you configured a management boundary for multiple projects, use the ID of your management project for boundary-wide discovery and registration, or specify a member project ID for single-project operations.

  3. If you want to restrict Cloud Storage tokens, enable the Security Token Service API (sts.googleapis.com) in your project.

  4. Install the google-auth and requests Python libraries:

    pip install --upgrade google-auth requests
    
  5. Configure Application Default Credentials (ADC) for local development. Otherwise, attach a service account or Workload Identity Federation credential configuration:

    gcloud auth application-default login
    

Required roles

You can use your user account for local development, or you can use a service account or agent principal for your orchestrator agent to discover registered agents and call target A2A agents. The user account, service account, or agent principal must have appropriate roles to complete these tasks.

To ensure that your user account, service account, or agent principal has the necessary permissions to discover A2A agents in Agent Registry and call target A2A agents , ask your administrator to grant the following IAM roles to your user account, service account, or agent principal:

  • To discover agents in Agent Registry: Agent Registry API Viewer (roles/agentregistry.viewer) on the governance project where Agent Registry is enabled
  • To call a target A2A agent at runtime: The runtime or gateway role for the service that hosts the target agent, required to call that agent. For example, if the target agent runs on Cloud Run, the account or principal must have the Cloud Run Invoker role (roles/run.invoker).

For more information about granting roles, see Manage access to projects, folders, and organizations.

Your administrator might also be able to give your user account, service account, or agent principal the required permissions through custom roles or other predefined roles.

How credentials pass between agents

When an A2A client or orchestrator agent sends a message to a remote agent, downstream services check permissions based on how the request is authenticated:

  • On behalf of a user: a user signs in to your orchestrator agent, which passes a user-authorized OAuth 2.0 token, or a token managed by the auth manager, to the remote A2A agent. Google Cloud APIs verify the token and check the user's Identity and Access Management (IAM) permissions so the remote agent can't access resources that the user isn't allowed to access.
  • Using the agent's own identity: when an orchestrator agent runs without a signed-in user, it authenticates with its own agent identity or service account. Downstream services check the roles granted to that agent's principal (principal://), a matching principal set (principalSet://), or its service account.
  • From external or cross-cloud workloads: agents running outside Google Cloud exchange tokens from an external identity provider through Workload Identity Federation to get federated Google Cloud access tokens before calling target A2A agent endpoints.

To limit the permissions that a token grants to a remote agent, you can limit the scope of OAuth tokens with bindings for third-party or SaaS A2A agents.

You can also restrict Cloud Storage tokens using a Credential Access Boundary to limit a Google Cloud access token to specific Cloud Storage buckets or objects. Credential Access Boundaries support only Cloud Storage (storage.googleapis.com) permissions. For other Google Cloud APIs and A2A agent calls, scope access through auth manager bindings, least-privilege agent identities with IAM allow and deny policies, or Agent Gateway.

If those options don't fit your use case and your orchestrator agent authenticates with a service account, you can also use service account impersonation to request a short-lived token for a dedicated service account that has only the roles needed for a specific task.

Scope OAuth tokens with bindings

When calling a third-party or SaaS A2A agent that uses 2-legged or 3-legged OAuth 2.0, create an auth provider in the auth manager and attach a Binding resource in Agent Registry that lists only the OAuth scopes the remote agent needs. When Agent Development Kit (ADK) retrieves the remote agent using get_remote_a2a_agent(), it requests tokens limited to the scopes on that binding. For setup steps, see Authenticate to tools and resources and Manage bindings.

Restrict Cloud Storage tokens

If your orchestrator agent passes an OAuth 2.0 access token to an agent or tool that reads or writes Cloud Storage data, you can reduce the permissions of the token to only allow access to specific buckets or object prefixes. Use Security Token Service to apply a Credential Access Boundary before sending the request:

import google.auth
from google.auth import downscoped
from google.auth.transport.requests import Request

source_creds, _ = google.auth.default(
    scopes=["https://www.googleapis.com/auth/cloud-platform"]
)

access_boundary_rule = downscoped.AccessBoundaryRule(
    available_resource=(
        "//storage.googleapis.com/projects/_/buckets/BUCKET_NAME"
    ),
    available_permissions=["inRole:roles/storage.objectViewer"],
)
cab = downscoped.CredentialAccessBoundary(rules=[access_boundary_rule])

downscoped_creds = downscoped.Credentials(
    source_credentials=source_creds,
    credential_access_boundary=cab,
)
downscoped_creds.refresh(Request())

Replace BUCKET_NAME with the Cloud Storage bucket name that the remote agent can read.

Additional security controls

You can combine credential scoping with network policies and prompt inspection:

What's next