Agents × Gemini Enterprise

These values fill in every command on the page. They stay in your browser. Nothing is sent anywhere.Ces valeurs remplissent toutes les commandes de la page. Elles restent dans votre navigateur. Rien n'est envoyé nulle part.

Complete path · agents project → Gemini Enterprise appParcours complet · projet des agents → app Gemini Enterprise

Your own agents, inside Gemini Enterprise

Des agents à vous, dans Gemini Enterprise

Deploy an agent (Cloud Run with A2A, or Agent Runtime) in its own project, plug it into the Gemini Enterprise app of another project, then let it use the user's data (Gmail, Calendar, Drive, Sheets…) with their consent. One or several providers. Everything that can be is scripted.

Déployer un agent (Cloud Run en A2A, ou Agent Runtime) dans son propre projet, le brancher sur l'app Gemini Enterprise d'un autre projet, puis lui faire utiliser les données de l'utilisateur (Gmail, Agenda, Drive, Sheets…) avec son accord. Un ou plusieurs fournisseurs. Tout ce qui peut l'être est scripté.

No Docker: Cloud BuildScript, Terraform or console OAuth: “Authorize” buttonModel ArmorNo deletion possible
Sans Docker : Cloud BuildScript, Terraform ou console OAuth : bouton « Autoriser »Model ArmorAucune suppression possible
0 · Overview

Who talks to whom

Gemini Enterprise is Google's enterprise assistant: a chat, connectors (Drive, Gmail…) and agents. Our agents live in a separate project. The app calls them with its own service account and, when needed, with the user's token.

User

The chat

Opens an agent, asks a question
First time with OAuth: “Authorize”
Agent User role on the agent
question
App project

{{PROJET_APP}}

App {{APP_ID}} ({{GE_LOCATION}})
App service account:
{{GE_SA}}
OAuth authorizations (client + scopes)
A2A call
or Agent Runtime
Agents project

{{PROJET_AGENTS}}

Cloud Run: {{K}}-a2a-shell (A2A)
Agent Runtime: {{K}}-shell
Model Armor, Gemini, logs
OAuth client + Gmail, Drive… APIs (recommended)
Identity 1

The user

Their Acme account. They only see an agent if they have the Agent User role. With OAuth, the agent acts with their own rights.

Identity 2

The app's account

{{GE_SA}} calls the agent. It needs ① run.invoker on each Cloud Run service, ② discoveryengine.serviceAgent on the agents project (Agent Runtime).

Identity 3

The agent's account

{{K}}-a2a-shell-sa: calls Gemini, writes its logs, goes through Model Armor. Nothing else.

Two ways to host an agent

A2A on Cloud RunAgent Runtime (Vertex AI)
What you give the appThe agent card (JSON)The path projects/…/reasoningEngines/…
App permission① roles/run.invoker on the service② roles/discoveryengine.serviceAgent on the project
OAuthOne authorization per agentSeveral (one per provider)
UpdatesNew revision, same addressNew resource: add the new path to the app
When to choose itDefault; open, reusable protocolSeveral OAuth providers; sessions managed by Google

The agent catalogue

One folder per agent in agents/trio/, described in catalogue.json (name, description, sample questions, and the oauth block). Scripts and Terraform read this file.

Good to know

The Gemini Enterprise API (streamAssist) cannot call an A2A or ADK agent added to the app (Google documentation). A custom agent is tested in the chat, or by calling the agent directly the way the app does (Troubleshooting tab).

1 · Agents project

Deploy an agent

Everything runs from a Mac or Linux terminal. No Docker: the image is built by Cloud Build, inside Google Cloud. The app doesn't need to exist yet.

Your machine

  • gcloud signed in: gcloud auth login and gcloud auth application-default login
  • Python 3.12 to 3.14
  • Mac without install rights: pip install --no-deps -r agents/trio/requirements-poste.txt

Your permissions

Read-only check, groups included:

./scripts/verifier_droits.sh

The configuration

One file, config/12-1-agents-dans-projet-exp.env. The app fields can stay empty until you publish.

Load the configuration

source scripts/config.sh config/12-1-agents-dans-projet-exp.env

Prints a summary: projects, agents, and “(pas encore : agents seuls)” if the app is empty.

Prepare (once per project)

./scripts/deployer_shell.sh preparer   # Model Armor templates, image repository, build account

Deploy the agent

./scripts/deployer_shell.sh cloudrun {{K}}   # A2A: image (Cloud Build), account, private service
./scripts/deployer_shell.sh runtime {{K}}    # and/or Agent Runtime
== {{K}} (Cloud Run)   adresse {{URL}}
-- 1/3 l'image, construite par Cloud Build (environ 1 min 20 s)   … SUCCESS
-- 2/3 son compte de service et ses 3 rôles
-- 3/3 le service Cloud Run (privé)
Service URL: {{URL}}

Test (3 to 5 minutes later)

./scripts/deployer_shell.sh tester {{K}}

“OK : les agents répondent en A2A v0.3, avec mémoire de conversation”. For an OAuth agent, the reply “cliquez sur Autoriser” is expected: the test sends no user token.

The sheet for Gemini Enterprise

./scripts/deployer_shell.sh carte {{K}}

Writes carte-{{K}}.json and prints everything to paste in the app: name, description, one-line card, Agent Runtime path, Authentication step, suggested questions, permissions.

The card comes from carte_a2a.py, in the format Google expects. Not the one from /.well-known/agent-card.json: it has extra fields, and Gemini Enterprise rejects it.

Re-running is safe: what exists is kept. cloudrun rebuilds the image: new revision, same address. To delete: python scripts/nettoyer.py --agent {{K}} --supprimer (shows the inventory first).

Pick the agents in the configuration

AGENTS="{{K}}"                  # what must EXIST (empty = the whole catalogue)
AGENTS_OAUTH="{{K}}={{AUTH}}"   # only for an OAuth agent

Apply

source scripts/config.sh config/12-1-agents-dans-projet-exp.env
cd 01-bis-cloud-run-a2a/terraform     # Agent Runtime: 02-bis-agent-runtime/terraform
terraform init && terraform plan     # 1 agent, no app: 22 to add; +7 per agent
terraform apply

for_each over the catalogue: one image per agent, and adding an agent touches no other. OAuth agents also get their Google APIs enabled.

Read what the app needs

terraform output cards    # the card of each A2A agent
terraform output oauth    # expected authorizations + scopes
terraform output agents   # (02-bis) the path of each Agent Runtime agent

With PUBLIER=oui and the app values, Terraform also adds the agents to the app, authorization included.

The image

Cloud Build is started from the terminal (no console button takes our folder): gcloud builds submit … --config=01-bis-cloud-run-a2a/cloudbuild.yaml. Guide 12-1-3 has the full command.

The Cloud Run service

🔎 Cloud Run → Deploy container → the image → name {{K}}-a2a-shell → region {{REGION}} → Require authentication → the agent's service account → variables (file env-{{K}}.yaml).

Check

The service URL must be exactly {{URL}}: it is written in the card.

Click-by-click details: docs/12-1-3-deployer-agents-console.md.

2 · Agents project + app project

Plug the agent into the app

Three things: the app account's permissions (in the agents project), adding the agent (in the app), and the users' access. Wait 2 to 3 minutes after the permissions.

Permission ① · A2A agents

Cloud Run Invoker on the service

🔎 Cloud Run → {{K}}-a2a-shell → Security → Add principal → {{GE_SA}} → role Cloud Run Invoker → Save.

gcloud run services add-iam-policy-binding {{K}}-a2a-shell \
  --region={{REGION}} --project={{PROJET_AGENTS}} \
  --role=roles/run.invoker --member=serviceAccount:{{GE_SA}}
Permission ② · Agent Runtime agents

Discovery Engine Service Agent on the project

🔎 IAM → Grant access → {{GE_SA}} → role Discovery Engine Service Agent. Once, for all agents.

gcloud projects add-iam-policy-binding {{PROJET_AGENTS}} --condition=None \
  --role=roles/discoveryengine.serviceAgent --member=serviceAccount:{{GE_SA}}

See the permissions (read-only): IAM → tick “Include Google-provided role grants” → filter gcp-sa-discoveryengine. Or ./scripts/connecter_app.sh verifier. Both permissions in one command, with confirmation: ./scripts/connecter_app.sh droits {{K}}.

The card, on one line

./scripts/deployer_shell.sh carte {{K}}     # or: cat carte-{{K}}.json

In the app

🔎 Gemini Enterprise → the app → Agents → + Add agent → Custom agent via A2A → paste the whole line, from the first { to the last } → Preview agent details → Next.

Authentication

Agent without OAuth: Skip & Finish. OAuth agent: do not click Skip, see tab 3.

The name

The agent → Edit → {{NOM}} (A2A). Or in one command, with suggested questions: tab 5.

The agent's path

./scripts/deployer_shell.sh carte {{K}}     # “[Agent Runtime] projects/{{NUM_AGENTS}}/locations/{{REGION}}/reasoningEngines/…”

In the app

+ Add agent → Custom agent via Agent Runtime → Authorizations: nothing (no OAuth) → Next → Agent name {{NOM}}, catalogue description, Agent Runtime resource path → Create.

New version?

Agent Runtime creates a new resource. Remove the old entry from the app and add the new path.

User access

The agent → User permissions → Add → a group (recommended) or an address → role Agent User → Save. Without this role, the agent doesn't show in the chat.

The test

Overview → web app link → Agents → {{NOM}} → “{{EX}}”. 20 to 40 s the first time (cold start).

What to send to teams that own their agents

Their agent lives in their project. They grant the permission, then send us the card or the path:

To plug your agent into the Gemini Enterprise app ({{PROJET_APP}}), please:
1. grant the account {{GE_SA}}
   - roles/run.invoker on your Cloud Run service (A2A agent), or
   - roles/discoveryengine.serviceAgent on your project (Agent Runtime agent);
2. send us the A2A card (JSON, one line) or the path projects/…/reasoningEngines/…;
3. if the agent acts with the user's account (OAuth): the client ID and the scopes you need (the secret through a secure channel).
Agent region: europe-* (app in {{GE_LOCATION}}).
3 · The user's account

An agent acting with the user's consent

Examples: Rapport e-mails (courriels, Gmail read-only) and Espace de travail (workspace: Gmail, Calendar, Drive read-only, Google Sheets read and edit, no deletion). The user clicks “Authorize” once. After that, the agent gets their token with every question.

The flow, step by step

Everything is scripted, except one step

Google publishes no API to create an OAuth client: 2 minutes in the console, and the script prints the link. Everything else goes through scripts and Terraform: Google APIs, deployment, sheet, authorization, adding, customization.

Agents projectScript

Enable the agent's APIs, see its scopes

source scripts/config.sh config/12-1-agents-dans-projet-exp.env
./scripts/deployer_shell.sh oauth {{K}}
== courriels
▶ gcloud services enable gmail.googleapis.com --project={{PROJET_AGENTS}}
  portées (A2A)           : https://www.googleapis.com/auth/gmail.readonly
  portées (Agent Runtime) : … + https://www.googleapis.com/auth/cloud-platform
Client OAuth (une fois, console, 2 min) : https://console.cloud.google.com/auth/clients?project={{PROJET_AGENTS}}

APIs and scopes come from the agent's "oauth" block in catalogue.json.

Agents projectConsole · 2 min

The OAuth client

  1. 🔎 Google Auth Platform → if needed Get started: app name, email, audience Internal.
  2. Clients → + Create client → Web application → name ge-{{K}}.
  3. Authorized redirect URIs, exactly these two:
https://vertexaisearch.cloud.google.com/oauth-redirect
https://vertexaisearch.cloud.google.com/static/oauth/oauth.html

→ Create → note the client ID (put it in “Your values”) and the secret. Never put them in the repository.

Agents projectScript

Deploy the agent with its authorization

AGENTS_OAUTH="{{K}}={{AUTH}}" ./scripts/deployer_shell.sh cloudrun {{K}}
./scripts/deployer_shell.sh tester {{K}}   # 3 to 5 min later: “cliquez sur Autoriser” = expected

The agent gets AUTH_ID={{AUTH}}. In A2A, the authorization name in the app may differ; on Agent Runtime it must be identical.

Agents projectScript

The sheet, with the full authorization URL

AGENTS_OAUTH="{{K}}={{AUTH}}" CLIENT_ID={{CLIENT_ID}} ./scripts/deployer_shell.sh carte {{K}}
  3. Authentication (ne PAS cliquer Skip) :
      Nom de l'autorisation  : {{AUTH}}
      Authorization URL      : {{AUTH_URL}}
      Token URL              : https://oauth2.googleapis.com/token
      Scopes                 : {{SCOPES}}
      PKCE / HTTP Basic      : décochés
Agents project

The app's permission on the service

Permission ① on {{K}}-a2a-shell, as for any A2A agent (tab 2).

App projectConsoleor script

Add the agent with the authorization

Console: Custom agent via A2A → the card → Authentication: fill in the fields from the sheet. Do not click Skip.

FieldValue
Authorization name{{AUTH}} (readable: users see it)
Client ID / secretThose of the OAuth client
Authorization URLThe one from the sheet (with access_type=offline and prompt=consent, both required)
Token URLhttps://oauth2.googleapis.com/token
Scopes{{SCOPES}}
PKCE / HTTP BasicUnchecked for Google

Or by script, with the app values passed in front of the commands (the config file is not touched):

export PROJET_APP={{PROJET_APP}} NUM_APP={{NUM_APP}} GE_LOCATION={{GE_LOCATION}}
export GE_PROJECT={{PROJET_APP}} GE_APP={{APP_ID}}
./scripts/autorisation_oauth.sh create {{AUTH}} ~/Downloads/client_secret_XXX.json "{{SCOPES}}" "{{NOM}}"
AUTH_ID={{AUTH}} ./scripts/add_agent_to_ge.sh a2a carte-{{K}}.json "{{NOM}} (A2A)"   # + run.invoker permission
./scripts/personnaliser_agent.sh "{{NOM}} (A2A)" {{K}}                              # suggested questions, language
Chat

The test

Agent User for you → open the agent → “{{EX}}” → Authorize box → Google window → Allow → the answer, with your data. After that, no more box: access is kept.

What the “Espace de travail” agent can do, and will never do

ServiceScopeCanCannot
Gmailgmail.readonlySearch, read, summarizeSend, delete (Google refuses)
Calendarcalendar.events.readonlySee meetingsCreate, edit, delete
Drivedrive.readonlySearch, read Docs and SlidesEdit, delete a file
SheetsspreadsheetsRead, write, formulas, append rows, tabs, formatting, sort, charts, create a spreadsheetDelete or clear nothing: blocked by the code, before any call to Google

Google has no “Sheets without deletion” scope. So the tools only accept a list of lossless changes, and sheets_ecrire refuses to empty a filled cell. Tested: asked to “delete the Archives tab”, the agent refuses and offers to hide it.

4 · Google + Atlassian + …

Several credential providers

One authorization = one provider. A single Google authorization covers Gmail, Calendar, Drive, Sheets and BigQuery: scopes add up in a single consent. Another provider, such as Atlassian, Airtable or Databricks, needs another authorization.

A2A (Cloud Run)

One authorization per agent

The app sends one token (agentAuthorization). Several providers? One agent per provider: “Espace Google (A2A)” and “Jira (A2A)”. The chat switches between them.

Agent Runtime

A list of authorizations

The app sends one token per authorization (toolAuthorizations). Each tool takes its own. The user clicks “Authorize” once per provider.

The naming rule (our code)

AUTH_ID="acces-google,acces-atlassian": Google tools take the token of the first authorization, Atlassian tools the one whose ID contains “atlassian”. So: Google first, and the provider's word in the ID.

The Atlassian OAuth app

  1. developer.atlassian.com/console/myapps → Create → OAuth 2.0 integration.
  2. Permissions: Jira API (read:jira-work, read:jira-user), Confluence API (search:confluence, read:confluence-content.summary).
  3. Authorization → Callback URL: https://vertexaisearch.cloud.google.com/static/oauth/oauth.html.
  4. Settings: Client ID and Secret. Distribution → Sharing: otherwise only you can authorize.

Deploy on Agent Runtime with both authorizations

AGENTS_OAUTH="workspace=acces-google,acces-atlassian" ./scripts/deployer_shell.sh runtime workspace
AGENTS_OAUTH="workspace=acces-google,acces-atlassian" CLIENT_ID={{CLIENT_ID}} ./scripts/deployer_shell.sh carte workspace

In the app: two authorizations

Custom agent via Agent Runtime → Authorizations → Add authorization twice. The names must be identical to AGENTS_OAUTH.

acces-googleacces-atlassian
Authorization URLThe one from the sheet (Google, + cloud-platform, required on Agent Runtime)https://auth.atlassian.com/authorize?audience=api.atlassian.com&client_id=…&scope=read%3Ajira-work%20read%3Ajira-user%20search%3Aconfluence%20read%3Aconfluence-content.summary%20offline_access&redirect_uri=…&response_type=code&prompt=consent
Token URLhttps://oauth2.googleapis.com/tokenhttps://auth.atlassian.com/oauth/token

By script: AUTH_ID=acces-google,acces-atlassian ./scripts/add_agent_to_ge.sh adk <path> "Espace de travail". In A2A, the script refuses: “UNE seule autorisation par agent”.

In the chat

“My open Jira tickets?” → a second Authorize button (Atlassian) → Accept → the list. “Prepare my week with meetings, emails and tickets” → all three sources in one answer.

Other providers: the fields

ProviderAuthorization URLToken URLPKCEHTTP Basic
Googleaccounts.google.com/o/oauth2/auth?…&access_type=offline&prompt=consentoauth2.googleapis.com/tokennono
Atlassianauth.atlassian.com/authorize?audience=api.atlassian.com&…auth.atlassian.com/oauth/tokennono
Airtableairtable.com/oauth2/v1/authorizeairtable.com/oauth2/v1/tokenyesyes
Databricks<workspace>/oidc/v1/authorize<workspace>/oidc/v1/tokenyesif secret

Everywhere: register Gemini Enterprise's two redirect addresses with the provider. Atlassian, Airtable and Databricks have not been tested for real yet.

5 · What the user sees

Polish the experience

The “The agent requires additional authorization for: …” box and its Authorize button are Google's interface: their look can't be changed. What is written around them, however, can be set.

ElementHow
Button color, shape, positionnoGoogle's interface, the same for everyone
Language (“Authorize” or “Autoriser”)indirectGemini Enterprise language setting; no hl=en_US in the URL
The name after “authorization for:”yesThe authorization's display name (displayName), or a readable ID (not the one the console generates)
Agent name and iconyesdisplayName, icon
Suggested questions, input placeholderyesstarterPrompts, customPlaceholderText (taken from the catalogue)
Google window: app name, logo, support emailyesGoogle Auth Platform → Branding, in the OAuth client's project
Agent message when the token is missing or refusedyesThe agent's instruction (in French, with what to do)

The Google window (no risk)

OAuth client's project → 🔎 Google Auth Platform → Branding: name (“Assistant Acme”), 120×120 PNG logo, team email. Then Data access → declare the scopes: they show in plain words.

The authorization name

export PROJET_APP={{PROJET_APP}} NUM_APP={{NUM_APP}} GE_LOCATION={{GE_LOCATION}}
./scripts/autorisation_oauth.sh list                              # ID | display name
./scripts/autorisation_oauth.sh renommer {{AUTH}} "{{NOM}}"

If the box still shows the ID after renaming, recreate the authorization with a readable ID, then reattach the agent.

The agent: name, questions, placeholder, language, icon

GE_PROJECT={{PROJET_APP}} GE_APP={{APP_ID}} GE_LOCATION={{GE_LOCATION}} \
  ./scripts/personnaliser_agent.sh "<current name in the app>" {{K}} --icone icone.png
AVANT : {"displayName": "test gmail remote agent with auth"}
APRÈS : {"displayName": "{{NOM}} (A2A)", "starterPrompts": [{"text": "{{EX}}"}, …], "languageCode": "fr"}
Modifier cet agent dans l'app {{APP_ID}} (projet {{PROJET_APP}}) ? Tapez « oui » : oui
modifié : …  (retour arrière : ./scripts/personnaliser_agent.sh --annuler avant-<ID>.json)

Only these fields change (updateMask): neither the card nor the authorization.

6 · Security and governance

What protects, at every level

Private services

Cloud Run without public access: only accounts with run.invoker can call the agent, i.e. the app and you.

Least privilege

Each agent has its own account with 3 roles: Gemini, logs, Model Armor. The app account only has ① and ②.

Model Armor

Questions and answers are filtered: prompt injection, jailbreak, malicious URLs, sensitive data, dangerous content.

The user's rights

With OAuth, the agent only sees what the user sees. The token is never stored (temp: state) nor written to logs.

Minimal scopes

Read-only everywhere except Sheets. No deletion tool. Internal consent: Acme accounts only.

Injection through content

An email may say “ignore your rules”. The agent treats that content as data. Even if fooled, it can't delete or send anything: scopes and code prevent it.

The OAuth client: which project?

Agents project (recommended)App project
Gmail, Drive… APIs to enableagents project (script, Terraform)the app's production project
Quotas, monitoringagents projectapp project
Google windowthe team's name and logoone name for everyone
Secret and rotationagents teamGemini Enterprise team
Production change for an agentnone, except adding the agentAPIs + client in production

Both work. Agents project: one client per team or per agent family. App project: only for a shared client, run by the Gemini Enterprise team. Either way, the Google Workspace admin may need to approve the client ID (Security → API controls).

In production

Read first (connecter_app.sh verifier, autorisation_oauth.sh list, nettoyer.py without --supprimer). Any change to the app asks for confirmation (type the project ID, or “oui”). personnaliser_agent.sh keeps the previous values for rollback.

7 · When it gets stuck

Troubleshooting

What you seeCauseWhat to do
The card is rejected when addingCard from /.well-known/agent-card.json, or truncated line./scripts/deployer_shell.sh carte {{K}}, then copy the whole line
KeyError: '{{K}}'catalogue.json not up to date on the machineCopy the whole file again
“The agent couldn't respond”Permissions not active yet, or missingWait 3 min; check ① and ② for {{GE_SA}}
part_metadata parameter is only supported in Gemini Developer API modeOld commun.pyUpdate commun.py, then deployer_shell.sh cloudrun {{K}}
Agent missing from the chatNo Agent User role, or no licenseThe agent → User permissions → Agent User
redirect_uri_mismatchOAuth client redirect URIsThe 2 URIs, character for character
“Access blocked: your administrator…”The Workspace admin blocks the appGet the client ID approved (API controls)
refus (403) … has not been used in projectGoogle API not enabled./scripts/deployer_shell.sh oauth {{K}} (OAuth client's project)
refus (403) … insufficient authentication scopesScope missing from the Authorization URLUse the sheet's URL; revoke access, then authorize again
refus (401)Expired tokenAsk again; otherwise revoke access at myaccount.google.com/permissions
No Authorize buttonAgent added without authorization (Skip)Remove the agent from the app, add it again with the Authentication step
Agent Runtime: always “click Authorize”Authorization name ≠ AGENTS_OAUTHSame ID on both sides
A2A : UNE seule autorisation par agentTwo providers in A2AAgent Runtime, or one agent per provider
“Pas de jeton Atlassian”ID without the word “atlassian”, or A2ATab 4: naming rule
Answer blocked by Model ArmorAgent account permissions not active yet, or sensitive dataWait 2 to 5 min; narrow the request
does not have storage.objects.get accessBuild account missing./scripts/deployer_shell.sh preparer
Service account … does not existBrand-new account, not visible yetThe script retries; otherwise run again
pip install fails (watchdog) on MacNo prebuilt package for Python 3.14pip install --no-deps -r agents/trio/requirements-poste.txt; adk run instead of adk web

Call the agent the way the app does

curl -s -X POST "{{URL}}/" \
  -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  -H "Content-Type: application/json" -H "A2A-Version: 0.3" \
  -d '{"jsonrpc":"2.0","id":"1","method":"message/send","params":{"message":{"kind":"message","role":"user","messageId":"t1","parts":[{"kind":"text","text":"{{EX}}","metadata":{"source":"curl"}}]}}}' \
  | python3 -m json.tool

“completed” and an answer: the agent works. To simulate the app end to end, with its service account: ./scripts/simuler_gemini_enterprise.sh tout (guide 12-1-5).

The path, to tick off

From zero to an OAuth agent in the chat

Each box stays ticked in your browser. The order is the one that worked on the Acme instance.

Going further: the guides (in French)

  • docs/12-1-1-deployer-agents-shell.md: deploy by script, step by step
  • docs/12-1-2-deployer-agents-terraform.md · 12-1-3 (console)
  • docs/12-1-4-connecter-agents-app-gemini-enterprise.md: permissions, messages to teams
  • docs/12-1-5-simuler-appel-gemini-enterprise.md: simulate the app, without the app
  • docs/12-1-6-ajouter-agent-console-gemini-enterprise.md: the app console, click by click
  • docs/12-1-7-agents-oauth-identite-outils.md: OAuth, identity
  • docs/12-1-8-agent-espace-de-travail-multi-oauth.md: Gmail, Calendar, Drive, Sheets; several providers; experience
  • scripts/README.md: the map of all scripts
0 · Vue d'ensemble

Qui parle à qui

Gemini Enterprise est l'assistant d'entreprise de Google : un chat, des connecteurs (Drive, Gmail…) et des agents. Nos agents vivent dans un projet à part. L'app les appelle, avec son compte de service, et, s'il le faut, avec le jeton de l'utilisateur.

Utilisateur

Le chat

Ouvre un agent, pose une question
1re fois si OAuth : « Autoriser »
Rôle Agent User sur l'agent
question
Projet de l'app

{{PROJET_APP}}

App {{APP_ID}} ({{GE_LOCATION}})
Compte de l'app :
{{GE_SA}}
Autorisations OAuth (client + portées)
appel A2A
ou Agent Runtime
Projet des agents

{{PROJET_AGENTS}}

Cloud Run : {{K}}-a2a-shell (A2A)
Agent Runtime : {{K}}-shell
Model Armor, Gemini, journaux
Client OAuth + API Gmail, Drive… (recommandé)
Identité 1

L'utilisateur

Son compte Acme. Il voit un agent seulement s'il a le rôle Agent User. Avec OAuth, l'agent agit avec ses droits à lui.

Identité 2

Le compte de l'app

{{GE_SA}} appelle l'agent. Il lui faut ① run.invoker sur chaque service Cloud Run, ② discoveryengine.serviceAgent sur le projet des agents (Agent Runtime).

Identité 3

Le compte de l'agent

{{K}}-a2a-shell-sa : appelle Gemini, écrit ses journaux, passe par Model Armor. Rien d'autre.

Deux façons d'héberger un agent

A2A sur Cloud RunAgent Runtime (Vertex AI)
Ce qu'on donne à l'appLa carte de l'agent (JSON)Le chemin projects/…/reasoningEngines/…
Droit de l'app① roles/run.invoker sur le service② roles/discoveryengine.serviceAgent sur le projet
OAuthUne autorisation par agentPlusieurs (une par fournisseur)
Mise à jourNouvelle révision, même adresseNouvelle ressource : nouveau chemin à rajouter dans l'app
Quand le choisirPar défaut ; protocole ouvert, réutilisablePlusieurs fournisseurs OAuth ; sessions gérées par Google

Le catalogue des agents

Un dossier par agent dans agents/trio/, décrit dans catalogue.json (nom, description, questions d'exemple, et le bloc oauth). Scripts et Terraform lisent ce fichier.

À savoir

L'API de Gemini Enterprise (streamAssist) ne sait pas appeler un agent A2A ou ADK ajouté à l'app (documentation Google). Un agent personnalisé se teste dans le chat, ou en appelant l'agent directement comme le fait l'app (onglet Dépannage).

1 · Projet des agents

Déployer un agent

Tout se fait depuis un terminal Mac ou Linux. Il n'y a pas de Docker : l'image est construite par Cloud Build, dans Google Cloud. L'app n'a pas besoin d'exister à cette étape.

Le poste

  • gcloud connecté : gcloud auth login et gcloud auth application-default login
  • Python 3.12 à 3.14
  • Mac sans droits d'installation : pip install --no-deps -r agents/trio/requirements-poste.txt

Vos droits

Vérification en lecture seule, groupes compris :

./scripts/verifier_droits.sh

La configuration

Un fichier config/12-1-agents-dans-projet-exp.env. Les champs de l'app peuvent rester vides tant qu'on ne publie pas.

Charger la configuration

source scripts/config.sh config/12-1-agents-dans-projet-exp.env

Affiche un résumé : projets, agents, et « (pas encore : agents seuls) » si l'app est vide.

Préparer (une fois par projet)

./scripts/deployer_shell.sh preparer   # filtres Model Armor, dépôt d'images, compte de construction

Déployer l'agent

./scripts/deployer_shell.sh cloudrun {{K}}   # A2A : image (Cloud Build), compte, service privé
./scripts/deployer_shell.sh runtime {{K}}    # et/ou Agent Runtime
== {{K}} (Cloud Run)   adresse {{URL}}
-- 1/3 l'image, construite par Cloud Build (environ 1 min 20 s)   … SUCCESS
-- 2/3 son compte de service et ses 3 rôles
-- 3/3 le service Cloud Run (privé)
Service URL: {{URL}}

Tester (3 à 5 minutes après)

./scripts/deployer_shell.sh tester {{K}}

« OK : les agents répondent en A2A v0.3, avec mémoire de conversation ». Pour un agent OAuth, la réponse « cliquez sur Autoriser » est normale : le test n'envoie pas de jeton utilisateur.

La fiche pour Gemini Enterprise

./scripts/deployer_shell.sh carte {{K}}

Écrit carte-{{K}}.json et affiche tout ce qu'il faut coller dans l'app : nom, description, carte sur une ligne, chemin Agent Runtime, étape Authentification, questions proposées, droits.

La carte vient de carte_a2a.py, au format attendu par Google. Pas celle de /.well-known/agent-card.json : elle a des champs en plus, et Gemini Enterprise la refuse.

Relancer est sans danger : ce qui existe est gardé. cloudrun reconstruit l'image : nouvelle révision, même adresse. Supprimer : python scripts/nettoyer.py --agent {{K}} --supprimer (affiche d'abord l'inventaire).

Choisir les agents dans la configuration

AGENTS="{{K}}"                  # ce qui doit EXISTER (vide = tout le catalogue)
AGENTS_OAUTH="{{K}}={{AUTH}}"   # seulement pour un agent OAuth

Appliquer

source scripts/config.sh config/12-1-agents-dans-projet-exp.env
cd 01-bis-cloud-run-a2a/terraform     # Agent Runtime : 02-bis-agent-runtime/terraform
terraform init && terraform plan     # 1 agent sans app : 22 to add ; +7 par agent
terraform apply

for_each sur le catalogue : une image par agent, et ajouter un agent n'en touche aucun autre. Les agents OAuth ont aussi leurs API Google activées.

Lire ce qu'il faut pour l'app

terraform output cards    # la carte de chaque agent A2A
terraform output oauth    # autorisations attendues + portées
terraform output agents   # (02-bis) le chemin de chaque agent Agent Runtime

Avec PUBLIER=oui et les valeurs de l'app, Terraform ajoute aussi les agents à l'app, autorisation comprise.

L'image

Cloud Build se lance depuis le terminal (aucun bouton console ne prend notre dossier) : gcloud builds submit … --config=01-bis-cloud-run-a2a/cloudbuild.yaml. Le guide 12-1-3 donne la commande complète.

Le service Cloud Run

🔎 Cloud Run → Déployer un conteneur → l'image → nom {{K}}-a2a-shell → région {{REGION}} → Exiger l'authentification → compte de service de l'agent → variables (fichier env-{{K}}.yaml).

Vérifier

L'URL du service doit être exactement {{URL}} : elle est écrite dans la carte.

Détail clic par clic : docs/12-1-3-deployer-agents-console.md.

2 · Projet des agents + projet de l'app

Brancher l'agent sur l'app

Trois choses : les droits du compte de l'app (dans le projet des agents), l'ajout de l'agent (dans l'app), l'accès des utilisateurs. Attendez 2 à 3 minutes après les droits.

Droit ① · agents A2A

Cloud Run Invoker sur le service

🔎 Cloud Run → {{K}}-a2a-shell → Sécurité → Ajouter un compte principal → {{GE_SA}} → rôle Cloud Run Invoker (Demandeur Cloud Run) → Enregistrer.

gcloud run services add-iam-policy-binding {{K}}-a2a-shell \
  --region={{REGION}} --project={{PROJET_AGENTS}} \
  --role=roles/run.invoker --member=serviceAccount:{{GE_SA}}
Droit ② · agents Agent Runtime

Discovery Engine Service Agent sur le projet

🔎 IAM → Accorder l'accès → {{GE_SA}} → rôle Discovery Engine Service Agent. Une fois pour tous les agents.

gcloud projects add-iam-policy-binding {{PROJET_AGENTS}} --condition=None \
  --role=roles/discoveryengine.serviceAgent --member=serviceAccount:{{GE_SA}}

Voir les droits (lecture seule) : IAM → cocher « Include Google-provided role grants » → filtre gcp-sa-discoveryengine. Ou ./scripts/connecter_app.sh verifier. Les deux droits en une commande, avec confirmation : ./scripts/connecter_app.sh droits {{K}}.

La carte, sur une ligne

./scripts/deployer_shell.sh carte {{K}}     # ou : cat carte-{{K}}.json

Dans l'app

🔎 Gemini Enterprise → l'app → Agents → + Add agent → Custom agent via A2A → collez toute la ligne, du premier { au dernier } → Preview agent details → Next.

Authentication

Agent sans OAuth : Skip & Finish. Agent OAuth : ne pas cliquer Skip, voir l'onglet 3.

Le nom

L'agent → Edit → {{NOM}} (A2A). Ou en une commande, avec les questions proposées : onglet 5.

Le chemin de l'agent

./scripts/deployer_shell.sh carte {{K}}     # « [Agent Runtime] projects/{{NUM_AGENTS}}/locations/{{REGION}}/reasoningEngines/… »

Dans l'app

+ Add agent → Custom agent via Agent Runtime → Authorizations : rien (sans OAuth) → Next → Agent name {{NOM}}, description du catalogue, Agent Runtime resource path → Create.

Nouvelle version ?

Agent Runtime crée une nouvelle ressource. Retirez l'ancienne entrée de l'app et ajoutez le nouveau chemin.

L'accès des utilisateurs

L'agent → User permissions → Add → un groupe (recommandé) ou une adresse → rôle Agent User → Save. Sans ce rôle, l'agent n'apparaît pas dans le chat.

Le test

Overview → lien de l'app web → Agents → {{NOM}} → « {{EX}} ». 20 à 40 s la 1re fois (démarrage).

Ce qu'on envoie aux équipes qui ont leurs propres agents

Leur agent est dans leur projet. Elles donnent le droit, puis nous envoient la carte ou le chemin :

Pour brancher votre agent sur l'app Gemini Enterprise ({{PROJET_APP}}), merci de :
1. donner au compte {{GE_SA}}
   - roles/run.invoker sur votre service Cloud Run (agent A2A), ou
   - roles/discoveryengine.serviceAgent sur votre projet (agent Agent Runtime) ;
2. nous envoyer la carte A2A (JSON, une ligne) ou le chemin projects/…/reasoningEngines/… ;
3. si l'agent agit avec le compte de l'utilisateur (OAuth) : l'ID client, et les portées voulues (le secret par un canal sûr).
Région de l'agent : europe-* (app en {{GE_LOCATION}}).
3 · Le compte de l'utilisateur

Un agent qui agit avec l'accord de l'utilisateur

Exemples : Rapport e-mails (courriels, Gmail en lecture) et Espace de travail (workspace : Gmail, Agenda, Drive en lecture, Google Sheets en lecture et modification, sans suppression). L'utilisateur clique une fois sur « Autoriser ». Ensuite, l'agent reçoit son jeton à chaque question.

Le flux, étape par étape

Tout est scripté, sauf un geste

Google ne publie pas d'API pour créer un client OAuth : 2 minutes dans la console, et le script affiche le lien. Tout le reste passe par les scripts et Terraform : API Google, déploiement, fiche, autorisation, ajout, personnalisation.

Projet des agentsScript

Activer les API de l'agent, voir ses portées

source scripts/config.sh config/12-1-agents-dans-projet-exp.env
./scripts/deployer_shell.sh oauth {{K}}
== courriels
▶ gcloud services enable gmail.googleapis.com --project={{PROJET_AGENTS}}
  portées (A2A)           : https://www.googleapis.com/auth/gmail.readonly
  portées (Agent Runtime) : … + https://www.googleapis.com/auth/cloud-platform
Client OAuth (une fois, console, 2 min) : https://console.cloud.google.com/auth/clients?project={{PROJET_AGENTS}}

Les API et les portées viennent du bloc "oauth" de l'agent dans catalogue.json.

Projet des agentsConsole · 2 min

Le client OAuth

  1. 🔎 Google Auth Platform → si besoin Commencer : nom de l'application, e-mail, audience Interne.
  2. Clients → + Créer un client → Application Web → nom ge-{{K}}.
  3. URI de redirection autorisés, ces deux-là exactement :
https://vertexaisearch.cloud.google.com/oauth-redirect
https://vertexaisearch.cloud.google.com/static/oauth/oauth.html

→ Créer → notez l'ID client (à mettre dans « Vos valeurs ») et le secret. Ne les mettez jamais dans le dépôt.

Projet des agentsScript

Déployer l'agent avec son autorisation

AGENTS_OAUTH="{{K}}={{AUTH}}" ./scripts/deployer_shell.sh cloudrun {{K}}
./scripts/deployer_shell.sh tester {{K}}   # 3 à 5 min après : « cliquez sur Autoriser » = normal

L'agent reçoit AUTH_ID={{AUTH}}. En A2A, le nom de l'autorisation dans l'app peut être différent ; sur Agent Runtime, il doit être identique.

Projet des agentsScript

La fiche, avec l'URL d'autorisation complète

AGENTS_OAUTH="{{K}}={{AUTH}}" CLIENT_ID={{CLIENT_ID}} ./scripts/deployer_shell.sh carte {{K}}
  3. Authentication (ne PAS cliquer Skip) :
      Nom de l'autorisation  : {{AUTH}}
      Authorization URL      : {{AUTH_URL}}
      Token URL              : https://oauth2.googleapis.com/token
      Scopes                 : {{SCOPES}}
      PKCE / HTTP Basic      : décochés
Projet des agents

Le droit de l'app sur le service

Droit ① sur {{K}}-a2a-shell, comme pour tout agent A2A (onglet 2).

Projet de l'appConsoleou script

Ajouter l'agent avec l'autorisation

Console : Custom agent via A2A → la carte → Authentication : remplissez les champs de la fiche. Ne cliquez pas sur Skip.

ChampValeur
Nom de l'autorisation{{AUTH}} (lisible : il s'affiche à l'utilisateur)
Client ID / secretCeux du client OAuth
Authorization URLCelle de la fiche (avec access_type=offline et prompt=consent, obligatoires)
Token URLhttps://oauth2.googleapis.com/token
Scopes{{SCOPES}}
PKCE / HTTP BasicDécochés pour Google

Ou par script, avec les valeurs de l'app données devant les commandes (le fichier de config n'est pas touché) :

export PROJET_APP={{PROJET_APP}} NUM_APP={{NUM_APP}} GE_LOCATION={{GE_LOCATION}}
export GE_PROJECT={{PROJET_APP}} GE_APP={{APP_ID}}
./scripts/autorisation_oauth.sh create {{AUTH}} ~/Downloads/client_secret_XXX.json "{{SCOPES}}" "{{NOM}}"
AUTH_ID={{AUTH}} ./scripts/add_agent_to_ge.sh a2a carte-{{K}}.json "{{NOM}} (A2A)"   # + droit run.invoker
./scripts/personnaliser_agent.sh "{{NOM}} (A2A)" {{K}}                              # questions proposées, langue
Chat

Le test

Agent User pour vous → ouvrez l'agent → « {{EX}} » → encadré Authorize → fenêtre Google → Autoriser → la réponse, avec vos données. Ensuite, plus d'encadré : l'accès est gardé.

Ce que l'agent « Espace de travail » peut faire, et ne fera jamais

ServicePortéePeutNe peut pas
Gmailgmail.readonlyChercher, lire, résumerEnvoyer, supprimer (Google refuse)
Agendacalendar.events.readonlyVoir les réunionsCréer, modifier, supprimer
Drivedrive.readonlyChercher, lire Docs et SlidesModifier, supprimer un fichier
SheetsspreadsheetsLire, écrire, formules, ajouter des lignes, onglets, mise en forme, tri, graphiques, créer un classeurRien supprimer ni vider : bloqué par le code, avant tout appel à Google

Google n'a pas de portée « Sheets sans suppression ». Les outils n'acceptent donc qu'une liste de modifications sans perte, et sheets_ecrire refuse de vider une cellule remplie. Testé : à « Supprime l'onglet Archives », l'agent refuse et propose de le masquer.

4 · Google + Atlassian + …

Plusieurs fournisseurs d'identifiants

Une autorisation = un fournisseur. Une seule autorisation Google couvre Gmail, Agenda, Drive, Sheets et BigQuery : les portées s'additionnent dans un seul consentement. Un autre fournisseur, comme Atlassian, Airtable ou Databricks, demande une autre autorisation.

A2A (Cloud Run)

Une seule autorisation par agent

L'app envoie un jeton (agentAuthorization). Plusieurs fournisseurs ? Un agent par fournisseur : « Espace Google (A2A) » et « Jira (A2A) ». Le chat passe de l'un à l'autre.

Agent Runtime

Une liste d'autorisations

L'app envoie un jeton par autorisation (toolAuthorizations). Chaque outil prend le sien. L'utilisateur clique « Autoriser » une fois par fournisseur.

La règle de nommage (notre code)

AUTH_ID="acces-google,acces-atlassian" : les outils Google prennent le jeton de la 1re autorisation, les outils Atlassian celle dont l'ID contient « atlassian ». Donc : Google en premier, et le mot du fournisseur dans l'ID.

L'application OAuth Atlassian

  1. developer.atlassian.com/console/myapps → Create → OAuth 2.0 integration.
  2. Permissions : Jira API (read:jira-work, read:jira-user), Confluence API (search:confluence, read:confluence-content.summary).
  3. Authorization → Callback URL : https://vertexaisearch.cloud.google.com/static/oauth/oauth.html.
  4. Settings : Client ID et Secret. Distribution → Sharing : sinon, vous seul pouvez autoriser.

Déployer sur Agent Runtime avec les deux autorisations

AGENTS_OAUTH="workspace=acces-google,acces-atlassian" ./scripts/deployer_shell.sh runtime workspace
AGENTS_OAUTH="workspace=acces-google,acces-atlassian" CLIENT_ID={{CLIENT_ID}} ./scripts/deployer_shell.sh carte workspace

Dans l'app : deux autorisations

Custom agent via Agent Runtime → Authorizations → Add authorization deux fois. Les noms doivent être identiques à AGENTS_OAUTH.

acces-googleacces-atlassian
Authorization URLCelle de la fiche (Google, + cloud-platform, exigé sur Agent Runtime)https://auth.atlassian.com/authorize?audience=api.atlassian.com&client_id=…&scope=read%3Ajira-work%20read%3Ajira-user%20search%3Aconfluence%20read%3Aconfluence-content.summary%20offline_access&redirect_uri=…&response_type=code&prompt=consent
Token URLhttps://oauth2.googleapis.com/tokenhttps://auth.atlassian.com/oauth/token

Par script : AUTH_ID=acces-google,acces-atlassian ./scripts/add_agent_to_ge.sh adk <chemin> "Espace de travail". En A2A, le script refuse : « UNE seule autorisation par agent ».

Dans le chat

« Mes tickets Jira en cours ? » → un 2e bouton Authorize (Atlassian) → Accept → la liste. « Prépare ma semaine avec réunions, e-mails et tickets » → les trois sources dans une seule réponse.

Autres fournisseurs : les champs

FournisseurAuthorization URLToken URLPKCEHTTP Basic
Googleaccounts.google.com/o/oauth2/auth?…&access_type=offline&prompt=consentoauth2.googleapis.com/tokennonnon
Atlassianauth.atlassian.com/authorize?audience=api.atlassian.com&…auth.atlassian.com/oauth/tokennonnon
Airtableairtable.com/oauth2/v1/authorizeairtable.com/oauth2/v1/tokenouioui
Databricks<espace>/oidc/v1/authorize<espace>/oidc/v1/tokenouisi secret

Partout : déclarer chez le fournisseur les deux adresses de redirection de Gemini Enterprise. Atlassian, Airtable et Databricks n'ont pas encore été testés en vrai.

5 · Ce que voit l'utilisateur

Soigner l'expérience

L'encadré « The agent requires additional authorization for: … » et son bouton Authorize sont l'interface de Google : leur forme ne se change pas. En revanche, ce qui est écrit autour se règle.

ÉlémentComment
Couleur, forme, place du boutonnonInterface Google, la même pour tous
Langue (« Authorize » ou « Autoriser »)indirectGemini Enterprise en français ; pas de hl=en_US dans l'URL
Le nom après « authorization for: »ouiNom affiché de l'autorisation (displayName), ou un ID lisible (pas l'ID généré par la console)
Nom et icône de l'agentouidisplayName, icon
Questions proposées, texte de la zone de saisieouistarterPrompts, customPlaceholderText (pris dans le catalogue)
Fenêtre Google : nom de l'app, logo, e-mail d'assistanceouiGoogle Auth Platform → Branding, dans le projet du client OAuth
Message de l'agent si le jeton manque ou est refuséouiL'instruction de l'agent (déjà en français, avec la marche à suivre)

La fenêtre Google (sans risque)

Projet du client OAuth → 🔎 Google Auth Platform → Branding : nom (« Assistant Acme »), logo PNG 120×120, e-mail d'équipe. Puis Accès aux données → déclarer les portées : elles s'affichent en clair.

Le nom de l'autorisation

export PROJET_APP={{PROJET_APP}} NUM_APP={{NUM_APP}} GE_LOCATION={{GE_LOCATION}}
./scripts/autorisation_oauth.sh list                              # ID | nom affiché
./scripts/autorisation_oauth.sh renommer {{AUTH}} "{{NOM}}"

Si l'encadré montre encore l'ID après renommage, recréez l'autorisation avec un ID lisible, puis rattachez l'agent.

L'agent : nom, questions, texte de saisie, langue, icône

GE_PROJECT={{PROJET_APP}} GE_APP={{APP_ID}} GE_LOCATION={{GE_LOCATION}} \
  ./scripts/personnaliser_agent.sh "<nom actuel dans l'app>" {{K}} --icone icone.png
AVANT : {"displayName": "test gmail remote agent with auth"}
APRÈS : {"displayName": "{{NOM}} (A2A)", "starterPrompts": [{"text": "{{EX}}"}, …], "languageCode": "fr"}
Modifier cet agent dans l'app {{APP_ID}} (projet {{PROJET_APP}}) ? Tapez « oui » : oui
modifié : …  (retour arrière : ./scripts/personnaliser_agent.sh --annuler avant-<ID>.json)

Seuls ces champs changent (updateMask) : ni la carte, ni l'autorisation.

6 · Sécurité et gouvernance

Ce qui protège, à chaque étage

Services privés

Cloud Run sans accès public : seuls les comptes qui ont run.invoker appellent l'agent, c'est-à-dire l'app et vous.

Droits minimaux

Chaque agent a son compte, avec 3 rôles : Gemini, journaux, Model Armor. Le compte de l'app n'a que ① et ②.

Model Armor

Questions et réponses filtrées : injection de consignes, jailbreak, URL malveillantes, données sensibles, contenus dangereux.

Les droits de l'utilisateur

Avec OAuth, l'agent ne voit que ce que l'utilisateur voit. Le jeton n'est jamais enregistré (état temp:) ni écrit dans les journaux.

Portées minimales

Lecture seule partout, sauf Sheets. Aucun outil de suppression. Consentement Interne : comptes Acme uniquement.

Injection par le contenu

Un e-mail peut contenir « ignore tes règles ». L'agent traite ce contenu comme une donnée. Même trompé, il ne peut rien supprimer ni envoyer : les portées et le code l'en empêchent.

Le client OAuth : dans quel projet ?

Projet des agents (recommandé)Projet de l'app
API Gmail, Drive… à activerprojet des agents (script, Terraform)projet de prod de l'app
Quotas, suiviprojet des agentsprojet de l'app
Fenêtre Googlenom et logo de l'équipeun seul nom pour tous
Secret et rotationéquipe agentséquipe Gemini Enterprise
Changement en prod pour un agentaucun, à part l'ajout de l'agentAPI + client dans la prod

Les deux marchent. Projet des agents : un client par équipe ou par famille d'agents. Projet de l'app : seulement pour un client commun, géré par l'équipe Gemini Enterprise. Dans les deux cas, l'admin Google Workspace peut devoir approuver l'ID client (Sécurité → Contrôles des API).

En production

Lecture d'abord (connecter_app.sh verifier, autorisation_oauth.sh list, nettoyer.py sans --supprimer). Toute modification de l'app demande une confirmation (taper l'ID du projet, ou « oui »). personnaliser_agent.sh garde l'avant pour revenir en arrière.

7 · Si ça bloque

Dépannage

Ce que vous voyezCauseQue faire
La carte est refusée à l'ajoutCarte de /.well-known/agent-card.json, ou ligne coupée./scripts/deployer_shell.sh carte {{K}}, puis copier toute la ligne
KeyError: '{{K}}'catalogue.json pas à jour sur le posteRecopier tout le fichier
« The agent couldn't respond »Droits pas encore actifs, ou manquantsAttendre 3 min ; vérifier ① et ② avec {{GE_SA}}
part_metadata parameter is only supported in Gemini Developer API modeAncien commun.pyMettre à jour commun.py, puis deployer_shell.sh cloudrun {{K}}
Agent absent du chatPas de rôle Agent User, ou pas de licenceL'agent → User permissions → Agent User
redirect_uri_mismatchURI de redirection du client OAuthLes 2 URI, au caractère près
« Accès bloqué : votre administrateur… »L'admin Workspace bloque l'appFaire approuver l'ID client (Contrôles des API)
refus (403) … has not been used in projectAPI Google non activée./scripts/deployer_shell.sh oauth {{K}} (projet du client OAuth)
refus (403) … insufficient authentication scopesPortée absente de l'Authorization URLReprendre l'URL de la fiche ; retirer l'accès, puis réautoriser
refus (401)Jeton expiréRedemander ; sinon retirer l'accès sur myaccount.google.com/permissions
Pas de bouton AuthorizeAgent ajouté sans autorisation (Skip)Retirer l'agent de l'app, le rajouter avec l'étape Authentication
Agent Runtime : toujours « cliquez sur Autoriser »Nom de l'autorisation ≠ AGENTS_OAUTHMême ID des deux côtés
A2A : UNE seule autorisation par agentDeux fournisseurs en A2AAgent Runtime, ou un agent par fournisseur
« Pas de jeton Atlassian »ID sans le mot « atlassian », ou A2AOnglet 4 : règle de nommage
Réponse bloquée par Model ArmorDroits du compte de l'agent pas encore actifs, ou données sensiblesAttendre 2 à 5 min ; restreindre la demande
does not have storage.objects.get accessCompte de construction absent./scripts/deployer_shell.sh preparer
Service account … does not existCompte tout neuf, pas encore visibleLe script réessaie ; sinon relancer
Échec de pip install (watchdog) sur MacPas de paquet compilé pour Python 3.14pip install --no-deps -r agents/trio/requirements-poste.txt ; adk run au lieu de adk web

Appeler l'agent comme le fait l'app

curl -s -X POST "{{URL}}/" \
  -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  -H "Content-Type: application/json" -H "A2A-Version: 0.3" \
  -d '{"jsonrpc":"2.0","id":"1","method":"message/send","params":{"message":{"kind":"message","role":"user","messageId":"t1","parts":[{"kind":"text","text":"{{EX}}","metadata":{"source":"curl"}}]}}}' \
  | python3 -m json.tool

« completed » et une réponse : l'agent marche. Pour simuler l'app de bout en bout, avec son compte de service : ./scripts/simuler_gemini_enterprise.sh tout (guide 12-1-5).

Le parcours, à cocher

De zéro à un agent OAuth dans le chat

Chaque case reste cochée dans votre navigateur. L'ordre est celui qui a marché sur l'instance Acme.

Pour aller plus loin : les guides

  • docs/12-1-1-deployer-agents-shell.md : déployer par script, pas à pas
  • docs/12-1-2-deployer-agents-terraform.md · 12-1-3 (console)
  • docs/12-1-4-connecter-agents-app-gemini-enterprise.md : les droits, les messages aux équipes
  • docs/12-1-5-simuler-appel-gemini-enterprise.md : simuler l'app, sans l'app
  • docs/12-1-6-ajouter-agent-console-gemini-enterprise.md : la console de l'app, clic par clic
  • docs/12-1-7-agents-oauth-identite-outils.md : OAuth, identité
  • docs/12-1-8-agent-espace-de-travail-multi-oauth.md : Gmail, Agenda, Drive, Sheets ; plusieurs fournisseurs ; expérience
  • scripts/README.md : la carte de tous les scripts