Passer au contenu principal
Cette page vous guide à travers une façon d’exécuter la passerelle Claude apps sur Google Cloud. La configuration est un exemple fonctionnel pour une infrastructure gérée par le client plutôt qu’un déploiement de production pris en charge ; utilisez-la pour voir comment les éléments s’assemblent avant de l’adapter à votre propre environnement. Pour les exigences indépendantes de la plateforme, consultez le guide de déploiement.
Cet exemple provisionne la passerelle Claude apps sur Google Cloud avec Agent Platform de Google Cloud comme upstream de modèle, en utilisant soit Cloud Run soit GKE pour le calcul. Google Workspace est le fournisseur d’identité (IdP) d’exemple, mais tout fournisseur d’identité conforme à OpenID Connect (OIDC) fonctionne ; seul le bloc oidc change. Consultez Configuration du fournisseur d’identité pour les détails spécifiques à chaque IdP.

Ce que vous allez construire

Diagramme de la passerelle Claude apps sur Google Cloud : les clients Claude Code se connectent via HTTPS à la passerelle (Cloud Run ou GKE), qui s'exécute à l'intérieur d'un VPC aux côtés d'une base de données Cloud SQL avec IP privée pour l'état de session. La passerelle connecte les utilisateurs via OIDC contre Google Workspace, lit la configuration et les secrets de Secret Manager, transfère les demandes de modèle à Agent Platform et récupère son image d'Artifact Registry au déploiement.
La configuration de référence provisionne :
  • Un service Cloud Run ou un déploiement GKE exécutant le conteneur de la passerelle
  • Un référentiel Artifact Registry pour l’image de la passerelle
  • Une instance Cloud SQL pour PostgreSQL, IP privée uniquement, pour le store de la passerelle
  • Des secrets Secret Manager pour gateway.yaml, la clé de signature JWT, le secret client OIDC et l’URL Postgres
  • Un compte de service avec roles/aiplatform.user, attaché directement sur Cloud Run ou lié via Workload Identity sur GKE
  • Un équilibreur de charge d’application interne sur Cloud Run, ou un GKE Ingress interne de classe gce-internal sur GKE, pour HTTPS

Prérequis

  • Un projet GCP avec facturation activée et permission de créer les ressources ci-dessus
  • L’interface de ligne de commande gcloud, authentifiée avec gcloud auth login, et Docker installé localement
  • Pour la piste GKE : kubectl et un cluster GKE sur le VPC créé dans la procédure pas à pas ci-dessous
  • Accès aux modèles Claude dont vous avez besoin dans Model Garden, dans une région qui les publie
  • Un client d’application web OAuth 2.0 Google Workspace avec URI de redirection https://<gateway-host>/oauth/callback ; consultez Configuration du fournisseur d’identité
  • Un nom d’hôte TLS pour la passerelle, généralement un nom DNS interne pointant vers l’équilibreur de charge
Définissez le projet et la région une fois :
export PROJECT_ID=<your-project>
export REGION=us-east5   # a region where the Claude models you need are published in Model Garden
gcloud config set project "$PROJECT_ID"

Déployer la passerelle

Les étapes ci-dessous provisionnent le déploiement complet avec des commandes gcloud.
1

Activer les API

Activez les API de service que la procédure pas à pas utilise :
gcloud services enable \
  aiplatform.googleapis.com \
  artifactregistry.googleapis.com \
  sqladmin.googleapis.com \
  secretmanager.googleapis.com \
  iamcredentials.googleapis.com \
  iam.googleapis.com \
  compute.googleapis.com \
  servicenetworking.googleapis.com \
  run.googleapis.com \
  container.googleapis.com
Les API dont vous avez besoin dépendent de la piste de déploiement :
  • compute et servicenetworking : nécessaires pour la piste Cloud SQL avec IP privée
  • run : Cloud Run uniquement
  • container : GKE uniquement
2

Créer le compte de service et accorder l'IAM

La passerelle s’exécute en tant que compte de service dédié avec permission d’appeler Agent Platform. Elle atteint Cloud SQL sur le VPC avec un utilisateur de mot de passe, donc aucun rôle IAM Cloud SQL n’est requis :
gcloud iam service-accounts create claude-gateway --display-name="Claude apps gateway"
SA="claude-gateway@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member="serviceAccount:${SA}" --role="roles/aiplatform.user" --condition=None
Ensuite, activez les modèles Claude pour le projet dans Model Garden ; les modèles publient dans des régions spécifiques, donc vérifiez chaque fiche de modèle.
3

Construire et pousser l'image vers Artifact Registry

Construisez l’image selon les exigences d’image de conteneur, en utilisant le binaire glibc linux-x64, et poussez-la :
gcloud artifacts repositories create claude-gateway \
  --repository-format=docker --location="$REGION"
gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet

# Cloud Run requires linux/amd64. --provenance=false avoids a buildx OCI
# image index that Cloud Run rejects.
docker build --platform=linux/amd64 --provenance=false \
  -t "${REGION}-docker.pkg.dev/${PROJECT_ID}/claude-gateway/gateway:<version>" .
docker push "${REGION}-docker.pkg.dev/${PROJECT_ID}/claude-gateway/gateway:<version>"
4

Provisionner Cloud SQL pour PostgreSQL

Créez l’instance sur un VPC via Private Services Access afin qu’elle n’ait pas d’IP publique ; cela satisfait également les projets où constraints/sql.restrictPublicIp est appliqué :
VPC=cc-gateway-vpc
gcloud compute networks create "$VPC" --subnet-mode=custom
gcloud compute networks subnets create cc-gateway-subnet \
  --network="$VPC" --region="$REGION" --range=10.0.0.0/24

# Private Services Access: one-time per VPC
gcloud compute addresses create "google-managed-services-${VPC}" \
  --global --purpose=VPC_PEERING --prefix-length=16 --network="$VPC"
gcloud services vpc-peerings connect \
  --service=servicenetworking.googleapis.com \
  --ranges="google-managed-services-${VPC}" --network="$VPC"

gcloud sql instances create claude-gateway-db \
  --database-version=POSTGRES_16 --tier=db-g1-small --region="$REGION" \
  --network="projects/${PROJECT_ID}/global/networks/${VPC}" --no-assign-ip
gcloud sql databases create claude_gateway --instance=claude-gateway-db
PGPASS="$(openssl rand -hex 24)"
gcloud sql users create gateway --instance=claude-gateway-db --password="$PGPASS"

PRIVATE_IP="$(gcloud sql instances describe claude-gateway-db \
  --format='value(ipAddresses[0].ipAddress)')"
GATEWAY_POSTGRES_URL="postgres://gateway:${PGPASS}@${PRIVATE_IP}:5432/claude_gateway?sslmode=require"
Le runtime Cloud Run ou GKE doit être sur, ou routé dans, ce VPC.
5

Écrire gateway.yaml

Le bloc upstreams pointe vers Agent Platform avec auth: {}, donc la passerelle s’authentifie via Application Default Credentials du compte de service du runtime. Consultez la référence de configuration pour chaque champ.Deux champs listen dépendent de ce qui se trouve devant la passerelle :
  • public_url : requis derrière Cloud Run ou un GKE Ingress. La passerelle construit le redirect_uri IdP et son document de découverte uniquement à partir de cette valeur, jamais à partir des en-têtes X-Forwarded-*.
  • trusted_proxies : les plages source du front-end. La passerelle honore X-Forwarded-For uniquement lorsque le pair TCP se trouve dans cette liste, puis parcourt la chaîne au-delà des sauts de confiance, donc les limites de taux de connexion par IP et les événements d’audit enregistrent les IP des développeurs au lieu de celle de l’équilibreur de charge.
Définissez trusted_proxies pour correspondre à votre front-end. Un GKE Ingress externe de classe gce n’est pas listé : il provisionne une adresse de règle de transfert publique, que la vérification réseau privé de /login rejette.
Front-endtrusted_proxies
Cloud Run atteint directement, sans équilibreur de charge[169.254.0.0/16]
Équilibreur de charge d’application interne devant Cloud Run169.254.0.0/16 plus le CIDR de votre sous-réseau réservé au proxy
GKE Ingress interne, classe gce-internalLe CIDR de votre sous-réseau réservé au proxy
L’exemple ci-dessous utilise les valeurs de l’équilibreur de charge interne devant Cloud Run.
gateway.yaml
listen:
  host: 0.0.0.0
  port: 8080
  public_url: https://claude-gateway.internal.example.com
  trusted_proxies: [169.254.0.0/16, <your-proxy-only-subnet-cidr>]

oidc:
  issuer: https://accounts.google.com
  client_id: <your-oauth-client-id>
  client_secret: ${OIDC_CLIENT_SECRET}           # GKE: ${file:/secrets/oidc-client-secret}
  allowed_email_domains: [example.com]
  # Google ignores offline_access; these yield refresh tokens:
  scopes: [openid, profile, email]
  extra_auth_params: { access_type: offline, prompt: consent }

session:
  jwt_secret: ${GATEWAY_JWT_SECRET}              # GKE: ${file:/secrets/jwt-secret}

store:
  postgres_url: ${GATEWAY_POSTGRES_URL}          # GKE: ${file:/secrets/postgres-url}

upstreams:
  - provider: vertex
    region: <your-region>                        # must match $REGION
    project_id: <your-project>
    auth: {} # ADC via the runtime service account
Les id_tokens Google ne portent aucune revendication groups. Pour utiliser des politiques basées sur les groupes dans managed.policies avec Google Workspace comme IdP, configurez oidc.google_groups, qui recherche les groupes de chaque utilisateur via l’API Admin SDK Directory en utilisant un compte de service avec délégation au niveau du domaine. Sans cela, faites correspondre sur email_domain à la place.
6

Stocker les secrets dans Secret Manager

Créez quatre secrets et accordez roles/secretmanager.secretAccessor au compte de service claude-gateway :
SecretSource
gateway-jwt-secretopenssl rand -base64 32
gateway-oidc-client-secretGoogle Cloud Console → Client OAuth
gateway-postgres-url$GATEWAY_POSTGRES_URL de l’étape Cloud SQL
gateway-configle gateway.yaml complet de l’étape précédente
La façon dont les secrets atteignent le conteneur diffère selon la piste :
  • Sur GKE, ils se montent en tant que fichiers via le pilote CSI Secret Manager, et gateway.yaml référence ${file:/secrets/...}.
  • Sur Cloud Run, qui ne peut pas monter plusieurs secrets dans un seul répertoire, gateway.yaml se monte en tant que fichier et les trois autres s’injectent en tant que variables d’environnement, donc gateway.yaml référence ${GATEWAY_JWT_SECRET}, ${OIDC_CLIENT_SECRET} et ${GATEWAY_POSTGRES_URL} à la place.
7

Déployer

La commande ci-dessous déploie pour la production derrière un équilibreur de charge interne.
gcloud run deploy claude-gateway \
  --image="${REGION}-docker.pkg.dev/${PROJECT_ID}/claude-gateway/gateway:<version>" \
  --region="$REGION" \
  --service-account="claude-gateway@${PROJECT_ID}.iam.gserviceaccount.com" \
  --min-instances=1 \
  --timeout=3600 \
  --ingress=internal-and-cloud-load-balancing \
  --network="$VPC" --subnet=cc-gateway-subnet --vpc-egress=private-ranges-only \
  --set-secrets=/etc/claude/gateway.yaml=gateway-config:latest,GATEWAY_JWT_SECRET=gateway-jwt-secret:latest,OIDC_CLIENT_SECRET=gateway-oidc-client-secret:latest,GATEWAY_POSTGRES_URL=gateway-postgres-url:latest \
  --no-invoker-iam-check
L’accès VPC direct, via --network, --subnet et --vpc-egress=private-ranges-only, permet au service d’atteindre l’IP privée Cloud SQL directement. L’accès public aux points de terminaison Agent Platform et accounts.google.com va directement sur Internet plutôt que via le VPC, donc aucun Cloud NAT n’est nécessaire.La vérification IAM de l’invocateur doit être ouverte ou désactivée. La passerelle exécute son propre OIDC et ses clients ne portent aucun jeton GCP, donc la vérification de l’invocateur de Cloud Run doit admettre les demandes non authentifiées. L’authentification OIDC de la passerelle authentifie la demande une fois qu’elle atteint le conteneur, avec allowed_email_domains contrôlant les domaines autorisés à se connecter.Deux drapeaux admettent les demandes non authentifiées :
  • --no-invoker-iam-check : désactive la vérification sans liaison allUsers à gérer, et fonctionne sous Domain Restricted Sharing
  • --allow-unauthenticated : accorde à allUsers le rôle run.invoker ; utilisez-le si votre organisation n’autorise pas --no-invoker-iam-check
La restriction d’accès via --ingress est une couche indépendante et séparée de la vérification de l’invocateur ; gardez-la définie pour limiter le service à votre réseau d’entreprise.Par défaut, l’URL Cloud Run *.run.app se résout en une adresse publique, que la vérification réseau privé de /login rejette. Deux topologies donnent aux développeurs un nom d’hôte résoluble en privé, et Cloud Run ne provisionne ni l’une ni l’autre pour vous :
  • Équilibreur de charge d’application interne, la topologie que la commande de déploiement ci-dessus suppose : déployez avec --ingress=internal-and-cloud-load-balancing, provisionnez un équilibreur de charge d’application interne devant le service avec un nom DNS interne et un certificat, et définissez listen.public_url sur ce nom d’hôte.
  • Accès interne uniquement sans équilibreur de charge : déployez avec --ingress=internal et laissez listen.public_url comme l’URL *.run.app, la valeur par défaut dans les actifs de référence ci-dessous. Pour que *.run.app se résolve en privé, votre équipe réseau doit déjà exploiter un point de terminaison Private Service Connect pour les API Google, une zone privée Cloud DNS résolvant *.run.app vers celui-ci, et un routage sur site vers ce point de terminaison.
Le guide de mise en réseau privée de Google pour Cloud Run couvre l’infrastructure que les deux options nécessitent. Vérifiez la connexion une fois que la passerelle est servie sur un nom d’hôte privé ; jusqu’à ce moment, confirmez que le conteneur a démarré à partir de ses journaux dans Cloud Run.Mettez à jour l’URI de redirection autorisé du client OAuth vers <public_url>/oauth/callback avant la première connexion. Redéployez après avoir modifié public_url, car la passerelle construit son origine publique uniquement à partir de ce paramètre et ignore X-Forwarded-Host et X-Forwarded-Proto. X-Forwarded-For est honoré pour les IP client uniquement lorsque listen.trusted_proxies est défini.
8

Pousser l'URL de la passerelle vers les machines des développeurs

La passerelle s’exécute maintenant, mais les développeurs ne peuvent pas la atteindre à partir de /login jusqu’à ce que l’URL de la passerelle soit sur leurs machines. Définissez forceLoginMethod et forceLoginGatewayUrl dans le fichier de paramètres gérés que vous déployez sur chaque appareil via MDM. Il n’y a pas d’option de passerelle dans le sélecteur de connexion pour qu’un développeur sélectionne manuellement.

Référence Terraform

Les actifs de déploiement de référence automatisent la piste Cloud Run sur cette page ; les actifs de configuration et d’image s’appliquent aux deux pistes :
  • setup.sh : un provisionneur gcloud idempotent qui parcourt le chemin Cloud Run complet, de l’activation des API au premier déploiement
  • terraform/ : le même déploiement en tant qu’infrastructure en tant que code, pour un déploiement sur terrain vierge : une application ciblée pour créer le référentiel Artifact Registry, puis construire et pousser l’image, puis une application complète
  • gateway.yaml.example et un Dockerfile pour l’image de runtime distroless
Les artefacts par défaut Cloud Run ingress à internal, donc aucun équilibreur de charge n’est requis. Pour correspondre au déploiement de production derrière un ALB de cette page, exécutez setup.sh avec INGRESS=internal-and-cloud-load-balancing, ou définissez la variable Terraform ingress à INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER. Les artefacts définissent également par défaut la couche d’invocateur à une concession allUsers run.invoker plutôt qu’à --no-invoker-iam-check, l’inverse de la procédure pas à pas de cette page ; l’un ou l’autre fonctionne, et le choix dépend des contraintes de politique de votre organisation. Les actifs sont fournis en tant qu’exemples fonctionnels, non en tant qu’artefact de production pris en charge ; examinez-les et adaptez-les à votre environnement.

Dépannage

Pour les erreurs de démarrage et de connexion de la passerelle, consultez le tableau dépannage indépendant de la plateforme. Les entrées ci-dessous sont spécifiques à Google Cloud.
SymptômeCauseCorrection
Cloud Run retourne 403 Forbidden avant d’atteindre le conteneurLa vérification IAM de l’invocateur est toujours activéeDéployez avec --no-invoker-iam-check, ou accordez à allUsers le rôle run.invoker avec --allow-unauthenticated
--no-invoker-iam-check rejeté avec invoker_iam_disabled is not currently availableBloqué par constraints/run.managed.requireInvokerIamUtilisez --allow-unauthenticated. Si Domain Restricted Sharing via constraints/iam.allowedPolicyMemberDomains bloque également cela, utilisez la piste GKE, qui expose la passerelle au niveau du réseau sans liaison allUsers.
Container manifest type … must support amd64/linux au déploiementL’image a été construite sur un hôte non-amd64, ou buildx a émis un index d’image OCIConstruisez avec --platform=linux/amd64 --provenance=false
Le démarrage de la passerelle se termine avec une erreur de délai d’expiration de connexion Postgres sur Cloud RunLe service n’est pas attaché au VPC, ou Cloud SQL n’a pas d’IP privée sur ce VPC ; le store arrête d’attendre après 5 secondesDéployez avec --network et --subnet pour l’accès VPC direct, et créez l’instance Cloud SQL avec --no-assign-ip et --network pointant vers le même VPC
Les demandes Agent Platform retournent 403 PERMISSION_DENIEDLe runtime n’utilise pas le compte de service claude-gateway, ou le modèle n’est pas activé dans Model Garden pour le projetDéfinissez --service-account sur Cloud Run ou liez Workload Identity sur GKE, et activez chaque modèle Claude dans Model Garden pour la région cible
Les réponses de streaming se coupent après une durée fixeDélai d’expiration de la demande du front-end : le service backend de l’équilibreur de charge derrière GKE Ingress par défaut à 30 secondes et Cloud Run à 300 secondesAttachez un BackendConfig avec un timeoutSec augmenté sur GKE, ou déployez avec --timeout=3600 sur Cloud Run

Étapes suivantes