Ce guide répond à : qu'est-ce qui protège les données, à chaque étage ? Comment suivre l'usage, révoquer un accès, maîtriser le coût ? Que faire quand ça bloque, et comment tout supprimer ?
1. Les protections, de l'extérieur vers les données
| Étage | Protection | Ce qu'elle empêche |
|---|---|---|
| Réseau | Cloud Run privé (--no-allow-unauthenticated) | Personne n'atteint le serveur sans run.invoker (403, vérifié par tester) |
| Appelants | run.invoker donné seulement au compte de l'app et au compte de l'agent | Un autre service, ou un utilisateur seul, ne peut pas appeler le serveur |
| Utilisateur | Jeton OAuth vérifié : audience (nos clients), portée Sheets, e-mail vérifié, domaine autorisé | Jeton d'une autre application, compte personnel ou externe (4 refus testés) |
| Consentement | Écran Interne + hd=acme.example | Seuls les comptes de l'organisation peuvent même se connecter |
| Données | Appels Sheets avec le jeton de l'utilisateur ; compte du serveur sans rôle | Le serveur ne voit que ce que l'utilisateur voit : ses droits Drive s'appliquent |
| Portées | spreadsheets + drive.metadata.readonly (noms de fichiers seulement) | Pas de lecture du contenu des autres fichiers Drive ; pas de suppression de fichier |
| Actions | Annotations lecture / destructif ; actions désactivées par défaut dans l'app ; confirmation | Une modification n'arrive pas par surprise ; vous choisissez ce qui est activé |
| Volume | 20 000 cellules maximum par lecture | Un classeur entier n'est pas envoyé au modèle |
| Traçabilité | Journal tool_call : qui, outil, classeur, plage. Jamais le contenu | Audit sans fuite |
| Configuration | Démarrage refusé sans OAUTH_CLIENT_IDS ; Terraform refuse aussi | Un serveur mal configuré ne peut pas accepter n'importe quel jeton |
| Jeton dans l'agent | État temp: : jamais enregistré, jamais journalisé | Pas de jeton qui traîne dans une base de sessions |
| Contenu des cellules | Consigne à l'agent : une cellule est une donnée, pas une consigne | Injection de consignes cachée dans un classeur |
Ce que le serveur peut détruire, et comment le limiter. write_range, clear_range, delete_sheet,
delete_dimension et batch_update modifient ou suppriment du contenu dans un classeur. Ils ne suppriment jamais
le fichier lui-même. Trois réglages :
- dans l'app, ne pas activer ces actions (10-5, étape 5) ;
- dans l'agent, la consigne demande d'annoncer et de faire confirmer ;
- l'historique des versions de Sheets permet toujours de revenir en arrière (Fichier → Historique des versions).
2. Exploiter
Journaux (Cloud Logging, ressource Cloud Run sheets-mcp) :
jsonPayload.event="tool_call" -- qui a utilisé quel outil, sur quel classeur
jsonPayload.event="auth_rejected" -- refus (domaine, e-mail non vérifié)
Révoquer un accès :
- un utilisateur, pour lui-même : myaccount.google.com → Sécurité → Applications tierces → retirer l'accès ;
- l'admin Workspace, pour tous : Console d'administration → Sécurité → Contrôles des API → Accès des applications → bloquer le client OAuth ;
- en urgence :
- désactiver le client OAuth (Google Auth Platform) ;
- ou retirer
run.invokerau compte de l'app et au compte de l'agent ; - ou mettre le service à 0 instance.
Mettre à jour le serveur :
- modifier le code ;
python tests/test_server.py;python scripts/gen_toolspec.py;./scripts/deployer.sh mcp(outerraform apply) ;- dans l'app : Reload custom actions.
Quotas : l'API Sheets a des quotas par minute, par utilisateur et par projet (celui du client OAuth). Le serveur
traduit une erreur 429 en message clair : « réessayez dans une minute ».
Coût : Cloud Run à 0 instance minimum : rien quand personne ne l'utilise, avec un démarrage de quelques secondes
à la première requête. --min-instances=1 répond tout de suite, pour un coût fixe modéré. L'API Sheets est gratuite
(dans les quotas). L'agent consomme des appels Gemini.
3. Dépannage
| Symptôme | Où regarder | Cause → solution |
|---|---|---|
deployer.sh : « Chargez la configuration » | – | source scripts/config.sh config/10-mcp.env dans ce terminal |
verifier : facturation DÉSACTIVÉE | – | Rattacher un compte de facturation au projet : sans lui, Cloud Run, Cloud Build, Vertex AI et Agent Runtime refusent |
mcp : « OAUTH_CLIENT_IDS est vide » | – | Créer le client OAuth (10-5, étape 1), mettre son ID dans le fichier, recharger |
Construction refusée (PERMISSION_DENIED, storage.objects.get) | Cloud Build → Historique | Compte de construction tout neuf (le script réessaie 3 fois) ; sinon preparer |
Le service ne démarre pas (container failed to start) | Cloud Run → Journaux | OAUTH_CLIENT_IDS vide dans le service (le serveur refuse de démarrer, c'est voulu) |
403 en appelant le serveur | – | run.invoker manquant pour l'appelant ; URL sans /mcp |
401 sur toutes les actions | Journaux : aucun tool_call | Le client OAuth qui a émis le jeton n'est pas dans OAUTH_CLIENT_IDS |
auth_rejected … reason: domain | Journaux | Domaine absent de ALLOWED_DOMAINS |
| « accès refusé : vous n'avez pas les droits sur ce fichier » | – | Le classeur n'est pas partagé avec l'utilisateur, ou la portée manque |
#ERROR! (Formula parse error.) | Le classeur | Locale fr_FR : , décimale et ; entre les arguments (10-1, partie 6) |
truncated: true | – | Plage trop grande : lire plus petit |
| L'agent dit « cliquez sur Autoriser » en boucle | – | 10-6, partie 7 |
| Connecteur : « Custom MCP Server » introuvable | – | Règle d'organisation (10-5, étape 2) |
4. Tout supprimer
Dans l'app (console de l'app) :
- Agents → l'agent → Delete ;
- Data stores →
Google Sheets→ Delete ; - l'autorisation OAuth :
DELETE …/authorizations/acces-sheets(REST), ou le scriptautorisation_oauth.sh deletedu projet 09.
Dans le projet des agents :
- script :
./scripts/deployer.sh nettoyer(inventaire, puis confirmation en tapant l'ID du projet) ; - ou Terraform :
terraform destroy.
Le client OAuth : Google Auth Platform → Clients → supprimer, s'il ne sert plus.