SpyBara
Go Premium

claude-apps-gateway-deploy.md 2026-09-24 22:57 UTC to 2026-09-25 23:58 UTC

This page contains 1 addition and 1 deletion.

2026
Wed 9 22:58 Sat 12 03:02 Fri 18 23:58 Sat 19 23:57 Fri 25 23:58

Déploiement et exploitation de la passerelle Claude apps

Enregistrez la passerelle auprès de votre fournisseur d'identité, créez le conteneur, déployez sur Kubernetes ou Cloud Run, et exploitez-la : vérifications de santé, rotation des secrets, mises à jour et sécurité.

Cette page couvre l'aspect opérationnel de l'exécution de la passerelle Claude apps : enregistrement d'un client OAuth auprès de votre fournisseur d'identité (IdP), déploiement de la passerelle en tant que conteneur, et son exploitation au quotidien. Pour chaque option du fichier gateway.yaml que la passerelle lit au démarrage, consultez la Référence de configuration.

Un déploiement en production suit quatre étapes dans l'ordre, et les sections ci-dessous les correspondent. Les deux premières sont des choix à faire ; les deux dernières sont des documents de référence à consulter une fois qu'elle est en cours d'exécution.

  1. Configurer votre fournisseur d'identité : enregistrez le client OAuth et consultez les notes spécifiques à chaque IdP pour Okta, Entra et Google
  2. Déployer la passerelle : créez une image de conteneur épinglée et exécutez-la sur Kubernetes, Cloud Run ou votre propre plateforme. Cette section couvre également les décisions concernant les coûts, le contournement, les passerelles multiples et les environnements sans serveur
  3. Configurer les opérations : journaux, sondes de santé, comportement en cas de panne, rotation des secrets et mises à jour. Référence pour le moment où vous configurez la surveillance et les runbooks
  4. Examiner la posture de sécurité : où les données circulent, le modèle de menace et les réponses de conformité. Référence pour un examen de sécurité

Si une connexion ou un démarrage échoue en cours de route, allez directement à Dépannage, qui est indexé sur l'erreur que vous voyez.

Configuration du fournisseur d'identité

Enregistrez une application web OAuth/OpenID Connect (OIDC) confidentielle auprès d'un seul URI de redirection, https://<gateway>/oauth/callback, et assignez-la aux utilisateurs ou groupes qui doivent avoir accès à la passerelle.

Tout IdP conforme à OIDC fonctionne : Okta, Microsoft Entra ID, Google Workspace, Keycloak, Dex, PingFederate et autres. L'IdP doit répondre à trois exigences :

  • Servir /.well-known/openid-configuration, via HTTPS en production ; la passerelle accepte un émetteur http://, et un émetteur de bouclage local nécessite en outre CLAUDE_GATEWAY_ALLOW_LOOPBACK=1
  • Supporter le flux de code d'autorisation. PKCE (Proof Key for Code Exchange) est activé par défaut ; désactivez-le avec oidc.use_pkce: false pour les IdP qui ne le supportent pas
  • Retourner email et optionnellement groups dans l'id_token, ou les servir à partir du point de terminaison userinfo avec oidc.userinfo_fallback: true

Pour l'infrastructure à clé publique privée, définissez oidc.ca_cert_pem.

Quelques fournisseurs gèrent les revendications d'email et de groupe différemment :

  • Okta : le serveur d'autorisation de l'organisation à https://example.okta.com retourne un id_token mince qui omet email et groups, donc définissez oidc.userinfo_fallback: true chaque fois que vous l'utilisez comme issuer. Un serveur d'autorisation personnalisé tel que https://example.okta.com/oauth2/default qui inclut email et optionnellement groups dans l'id_token les émet directement et n'a besoin d'aucun fallback. Okta émet groups uniquement lorsque la portée groups est demandée dans oidc.scopes et que le filtre de revendication de groupes de l'application le permet ; userinfo_fallback ne peut pas remplir une revendication pour laquelle l'IdP n'a pas été interrogé.
  • Microsoft Entra ID : issuer = https://login.microsoftonline.com/<tenant-id>/v2.0. Entra émet des ID d'objet de groupe plutôt que des noms, donc utilisez les GUID dans managed.policies.match.groups, ou utilisez les rôles d'application pour des noms lisibles par l'homme. Si votre locataire émet des rôles sous roles au lieu de groups, définissez oidc.groups_claim: roles.
  • Google Workspace : issuer = https://accounts.google.com. L'id_token de Google ne porte pas de groupes. Pour utiliser allowed_groups basé sur les groupes ou managed.policies avec Google comme IdP, configurez oidc.google_groups, qui recherche les groupes de chaque utilisateur via l'API Directory du SDK Admin en utilisant un compte de service avec délégation au niveau du domaine. Sans cela, utilisez oidc.allowed_email_domains pour le contrôle d'accès à l'adhésion et managed.policies.match.email_domain pour l'attribution de politique. Google ignore également la portée standard offline_access. Pour les jetons d'actualisation, définissez oidc.scopes: [openid, profile, email] et oidc.extra_auth_params: { access_type: offline, prompt: consent }.

Déploiement

La passerelle est un seul binaire Linux sans état qui se coordonne via Postgres, donc déployez-la comme vous déployez tout autre service sans état dans votre environnement. Gardez-la à l'intérieur de votre réseau, où vos développeurs et votre IdP peuvent la joindre via HTTPS, et traitez-la comme tout service détenant une credential de production.

Quelques décisions façonnent le déploiement au-delà de l'endroit où il s'exécute :

  • Coûts : pas de licence séparée ou de frais par siège. La passerelle fait partie du binaire claude, donc vous payez l'inférence via votre engagement existant, plus le calcul qu'elle exécute.
  • Contournement : la passerelle n'impose pas que la seule route vers un modèle passe par elle. Un développeur avec sa propre credential peut toujours appeler le fournisseur directement, donc fermer ce chemin est une décision de politique réseau, par exemple bloquer la sortie vers api.anthropic.com sauf depuis la passerelle. Bloquer cette sortie casse également la vérification de sécurité du domaine WebFetch, qui appelle api.anthropic.com depuis la machine de chaque développeur. Définissez skipWebFetchPreflight: true dans la politique gérée pour la désactiver.
  • Passerelles multiples : chaque est un déploiement séparé avec sa propre configuration, et le CLI stocke la confiance et les credentials par nom d'hôte de passerelle, donc les équipes peuvent utiliser différentes passerelles sans conflit. Pour servir plusieurs émetteurs OIDC, exécutez des instances séparées.
  • Sans serveur : Cloud Run fonctionne si vous définissez min-instances: 1 pour éviter la découverte OIDC à froid. Lambda et Cloud Functions ne fonctionnent pas, car la passerelle est un serveur HTTP de longue durée.

Chaque topologie de production ici place un proxy L7, tel qu'une Ingress, le front-end de Cloud Run ou un ALB, devant les répliques HTTP simples. Définissez listen.trusted_proxies sur les plages sources du proxy afin que la passerelle lise les adresses IP des clients à partir de X-Forwarded-For. La passerelle honore l'en-tête uniquement lorsque le pair TCP est de confiance. Les exemples travaillés Google Cloud et AWS ont des valeurs concrètes par topologie. Sans proxies de confiance, chaque demande semble provenir de l'adresse IP du proxy, ce qui réduit les limites de débit par IP en un seul compartiment partagé et enregistre l'adresse IP du proxy dans les événements d'audit.

Ne redirigez pas les demandes vers les points de terminaison d'autorisation d'appareil et de jeton de la passerelle, par exemple avec une réécriture HTTP-vers-HTTPS ou de canonicalisation d'hôte à l'entrée. Claude Code ne suit pas les redirections sur ces demandes, donc une règle d'entrée qui les redirige casse la connexion et l'actualisation des jetons.

Donnez au proxy un délai d'inactivité plus long que l'intervalle de maintien de la connexion de la passerelle, qui dépend de l'amont :

  • Sur chaque amont sauf provider: anthropic, la passerelle écrit un ping SSE une fois qu'un flux a été silencieux pendant environ 15 secondes.
  • Sur provider: anthropic, la passerelle transmet la réponse inchangée, y compris les propres pings de l'API Anthropic.

Une valeur par défaut telle que les 60 secondes de l'ALB est suffisante pour garder un flux silencieux ouvert. L'exemple travaillé AWS l'augmente à une heure de toute façon, et sa ligne de dépannage couvre les passerelles antérieures à v2.1.229, qui n'envoyaient rien pendant les périodes silencieuses sur les amonts qui reçoivent maintenant des pings.

Image de conteneur

Créez votre propre image autour du binaire claude natif de la version standard de Claude Code :

  1. Téléchargez la version Linux pour l'architecture de votre image à partir d'une version épinglée ; consultez Installer une version spécifique pour l'URL de téléchargement.
  2. Vérifiez-la par rapport au manifest.json signé GPG de la version comme décrit dans Intégrité binaire et signature de code.
  3. Copiez-la dans le contexte de construction.

Miroitez la version dans votre registre interne si vos constructions ne peuvent pas atteindre l'hôte de version, et épinglez la version que votre flotte exécute.

Au-delà du binaire, l'image a besoin de :

  • Une image basée sur glibc : la seule dépendance dynamique de la version glibc est les bibliothèques glibc. Les images basées sur Musl ont besoin de la version linux-x64-musl ou linux-arm64-musl plus des packages supplémentaires ; consultez Configuration Alpine Linux.
  • Un répertoire d'état inscriptible : la passerelle s'exécute en tant qu'utilisateur quelconque, mais les images minimales n'ont pas de répertoire personnel inscriptible. Définissez CLAUDE_CONFIG_DIR sur un chemin inscriptible tel que /tmp/.claude.
  • La commande du conteneur : claude gateway --config /etc/claude/gateway.yaml, avec le fichier de configuration monté en lecture seule et les secrets fournis en tant que variables d'environnement ; la passerelle écoute sur listen.port, par défaut 8080.

Kubernetes

Exécutez la passerelle en tant que Deployment, comme tout service sans état :

  • Montez la configuration à partir d'une ConfigMap et les secrets à partir d'un Secret ; référencez les secrets dans le YAML via ${file:/path/to/secret} ou en tant que variables d'environnement
  • Terminez TLS à l'Ingress et définissez listen.public_url sur le nom d'hôte de l'Ingress
  • Pointez la sonde de disponibilité sur GET /readyz et la sonde de vivacité sur GET /healthz

Pour un exemple travaillé complet sur AWS, couvrant ECS Fargate ou EKS, Amazon RDS et AWS Secrets Manager, consultez Déployer sur AWS.

Préférez l'identité de charge de travail de la plateforme aux clés statiques ; la référence upstreams a des détails de configuration par plateforme. Pour un appairage inter-cloud, tel qu'un amont Bedrock sur GKE, définissez des credentials explicites dans le bloc auth de l'amont à la place.

Cloud Run

Configurez le service comme suit :

  • Laissez listen.port à sa valeur par défaut de 8080, qui correspond au PORT par défaut de Cloud Run, ou définissez port: ${PORT}
  • Définissez public_url sur l'origine accessible de l'extérieur. Pour la production, c'est normalement le nom d'hôte d'un équilibreur de charge interne, car /login rejette les adresses publiques et l'URL *.run.app se résout en une, donc l'URL Cloud Run seule fonctionne uniquement pour un test de fumée curl ou navigateur. L'exception est un réseau où *.run.app se résout en privé via Private Service Connect et une zone privée Cloud DNS ; dans cette topologie l'URL Cloud Run est un public_url valide. L'exemple travaillé Google Cloud couvre les deux.
  • Montez la configuration en tant que volume secret
  • Définissez min-instances: 1 pour éviter une découverte OIDC à froid à la première demande

Pour un exemple travaillé complet sur Google Cloud, couvrant Cloud Run ou GKE, Cloud SQL et Secret Manager, consultez Déployer sur Google Cloud.

Envoyer l'URL de la passerelle aux machines des développeurs

Une fois que la passerelle est en service, envoyez forceLoginMethod, forceLoginGatewayUrl et parentSettingsBehavior: "merge" à la machine de chaque développeur via les paramètres gérés, via MDM ou en écrivant directement le fichier managed-settings.json par système d'exploitation. Sans cela, /login affiche le sélecteur de compte standard sans option de passerelle.

Une fois que vous déployez les clés, Claude Code cesse d'utiliser une clé API restante ou une connexion claude.ai sur la machine, donc planifiez l'envoi avec vos instructions de connexion. La politique de l'administrateur nécessite une connexion à la passerelle Cloud décrit les messages que les développeurs voient.

Consultez où chaque mécanisme stocke la politique pour les chemins de fichiers, et Paramètres gérés côté client pour l'équivalent bootstrapUrl de Claude Desktop.

Déploiements à grande échelle

La connexion est limitée en débit par adresse IP client, et les valeurs par défaut conviennent à une petite équipe. Chaque adresse obtient 30 démarrages de connexion et 10 soumissions de code toutes les 10 minutes. Un déploiement pour des milliers de développeurs peut atteindre ces limites le premier matin, pour l'une de deux raisons :

  • La passerelle ne peut pas voir au-delà de votre équilibreur de charge. Sans listen.trusted_proxies, chaque développeur semble provenir de l'adresse de l'équilibreur de charge et partage une limite. Définissez-le avant toute autre chose. La passerelle enregistre un avertissement la première fois qu'elle ignore un en-tête X-Forwarded-For.
  • De nombreux développeurs partagent quelques adresses de sortie NAT ou VPN. Ils partagent les limites de ces adresses même lorsque trusted_proxies est correct. Augmentez rate_limits pour l'adapter.

Pour dimensionner max, divisez les développeurs par les adresses de sortie qu'ils partagent. Estimez combien d'entre eux se connectent dans une période window_seconds, qui est 10 minutes par défaut. Puis doublez-le pour couvrir les tentatives et les développeurs qui se connectent à la fois à Claude Code et Claude Desktop.

Par exemple, 10 000 développeurs derrière 4 adresses de sortie se connectent uniformément sur une heure. C'est 2 500 développeurs par adresse et environ 420 d'entre eux dans chaque 10 minutes, que vous doublez et arrondissez à 1 000. L'exemple ci-dessous définit les deux limites à 1 000 :

rate_limits:
  device_authorization: { max: 1000, window_seconds: 600 }
  device_verify: { max: 1000, window_seconds: 600 }

device_verify est ce qui empêche quelqu'un de deviner le code de connexion d'un autre développeur, donc augmentez-le uniquement autant que votre estimation le nécessite. Même à ces limites, un code est 8 caractères d'un alphabet de 20 caractères et expire après 10 minutes, donc deviner reste impraticable ; consultez Résistance à la force brute du code utilisateur.

Lorsque votre IdP émet des jetons d'actualisation, Claude Code renouvelle les sessions silencieusement, donc vous pouvez remettre la limite après le déploiement. Sans jetons d'actualisation, les développeurs se connectent à nouveau tous les session.ttl_hours. Dimensionnez les deux limites pour ce débit régulier aussi et laissez-les augmentées.

Lorsqu'une limite est atteinte, Claude Code v2.1.274 ou ultérieur affiche The gateway is limiting sign-in attempts right now. Une passerelle sur v2.1.274 ou ultérieur affiche Too many attempts came from your network address sur la page de vérification, avec les paramètres à vérifier. Elle écrit également une ligne de journal sign-in refused qui nomme le paramètre à modifier.

Opérations

Une fois que la passerelle traite le trafic, l'exploitation au quotidien consiste à lire ses journaux, à sonder sa santé et à faire tourner ses secrets selon votre calendrier. Les sous-sections couvrent chacun, plus ce que Postgres détient et comment les mises à jour et les restaurations se comportent.

Journaux

La passerelle écrit deux flux sur stderr, tous deux JSON-friendly :

  • Événements d'audit : JSON sur une seule ligne par événement pertinent pour la sécurité. Canalisez stderr vers votre agrégateur de journaux.

    Les événements émis incluent config.load, session.mint, session.refresh, device.authorize, device.verify, device.callback, auth.denied, access.denied, access.public_client, inference, managed.serve, desktop_bootstrap.serve, desktop_bootstrap.denied, spend.blocked, admin.denied, admin.limit.upsert et admin.limit.delete. Les champs varient selon l'événement :

    • Les événements de mint et refresh réussis portent sub, email, client_ip et le résultat
    • auth.denied et access.denied portent la raison et l'adresse IP du client, plus le chemin de la demande pour auth.denied, car aucune identité utilisateur n'existe à ces refus. Deux raisons access.denied changent ce que l'événement porte :
      • xff_unparseable : l'événement porte également l'entrée X-Forwarded-For qui n'a pas pu être lue
      • client_ip_unknown : l'événement ne porte pas d'adresse IP client, car la connexion n'avait pas d'adresse de pair tandis qu'une liste access_control était définie
    • access.public_client porte l'adresse IP du client de la première demande par processus à arriver d'une adresse publique tandis que access_control.allow_cidrs est vide. La passerelle sert la demande comme d'habitude ; l'événement signale que la passerelle peut être accessible depuis l'internet public. Consultez la référence access_control pour ce qui compte comme public et pour la liste d'autorisation recommandée.
    • inference enregistre quel amont a servi la demande et le statut de la réponse
    • desktop_bootstrap.denied enregistre une récupération de bootstrap Claude Desktop rejetée avec la raison (not_configured, policy_not_opted_in ou no_policy_matched) et l'identité de l'utilisateur
    • admin.denied enregistre une tentative d'authentification d'API admin rejetée avec l'adresse IP du client, la méthode, le chemin et une raison, sans le matériel de clé présenté : invalid_key quand une x-api-key a été présentée mais ne correspondait à aucune clé configurée, bearer_rejected quand seul un en-tête Authorization a été présenté et il n'a pas vérifié comme une session de passerelle dans admin.admin_groups, ou no_credentials quand aucun en-tête n'a été présenté
  • Journaux opérationnels : lignes lisibles par l'homme avec préfixe [gateway] pour le démarrage, les avertissements et les erreurs en amont. La variable d'environnement CLAUDE_GATEWAY_LOG_LEVEL contrôle la verbosité et accepte debug, info, warn ou error, avec info par défaut. À debug, chaque connexion et actualisation enregistre également les noms, pas les valeurs, des revendications dans l'id_token, plus les noms des revendications userinfo quand userinfo_fallback en a fourni, afin que vous puissiez diagnostiquer les paramètres email_claim et groups_claim sans enregistrer les PII. Cela n'affecte pas les événements d'audit, qui sont toujours émis.

Santé

La passerelle sert GET /healthz comme sonde de vivacité et GET /readyz comme sonde de disponibilité ; /readyz vérifie que le magasin est accessible. Les deux sont exempts de access_control.allow_cidrs, donc les sondes continuent de fonctionner sur un écouteur verrouillé.

Le document de découverte OAuth à /.well-known/oauth-authorization-server retourne également 200 uniquement après le chargement de la configuration, la découverte OIDC, la construction du client en amont et la migration Postgres réussissent, donc il double comme vérification de démarrage de bout en bout.

Demandes en amont concurrentes

Par défaut, chaque réplique de passerelle envoie au maximum 256 demandes en amont en même temps. Une réponse en streaming compte par rapport à la limite jusqu'à ce que le flux se termine.

Une demande qui arrive tandis qu'une réplique est à la limite attend à l'intérieur de la passerelle pour un créneau libre. Le développeur voit une réponse qui est lente à démarrer ou semble se bloquer. Sur une amont provider: anthropic, une demande qui attend plus longtemps que timeouts.upstream_ttfb_ms abandonne cet amont, et échoue avec un 502 quand aucun amont ultérieur ne la sert.

La ligne de journal de démarrage qui contient upstream requests: affiche la limite en vigueur. Tandis qu'une réplique a plus de demandes ouvertes que la limite, elle enregistre également un avertissement qui contient client requests are open, au maximum une fois par minute.

Pour servir plus de demandes à la fois, vous avez deux options :

  • Ajouter des répliques.
  • Augmenter la limite sur chaque réplique. Définissez la variable d'environnement BUN_CONFIG_MAX_HTTP_REQUESTS sur le conteneur de passerelle à un nombre entier de 1 à 65535, puis redémarrez le conteneur.

Une réplique remplit sa limite à un taux de demande d'environ la limite divisée par le nombre moyen de secondes qu'une demande reste ouverte. Par exemple, si les demandes restent ouvertes pendant 10 secondes en moyenne, une réplique à la limite par défaut de 256 la remplit à environ 26 demandes par seconde.

Si vous mettez à l'échelle automatiquement sur CPU, une réplique à la limite met en file d'attente les demandes sans déclencher une montée en charge, donc définissez la cible en dessous du niveau CPU que vos répliques affichent quand elles enregistrent l'avertissement client requests are open.

Comportement en cas de panne

Si Postgres tombe en panne, la passerelle elle-même continue de servir les développeurs connectés et les nouvelles connexions échouent. Que les développeurs continuent réellement à travailler dépend de la façon dont votre orchestrateur gère la disponibilité :

  • Sessions existantes : les jetons porteurs valident localement avec le secret JWT, les actualisations de session ne touchent pas le magasin, et le processus de passerelle peut toujours servir l'inférence
  • Nouvelles connexions : échouent jusqu'à la récupération de Postgres, car le flux d'appareil et ses compteurs de limite de débit vivent dans Postgres
  • Application des limites de dépenses : échoue ouvert par défaut pendant la panne, donc l'inférence continue de circuler ; basculez-la pour échouer fermé si vous préférez bloquer plutôt que de fonctionner sans compteur
  • Disponibilité : /readyz signale non-prêt pendant la panne, donc les orchestrateurs qui contrôlent le trafic sur la disponibilité retirent chaque réplique de la rotation à la fois. Dans cette topologie tout le trafic, y compris l'inférence que la passerelle pourrait toujours servir, échoue à l'équilibreur de charge jusqu'à la récupération de Postgres. La sonde de vivacité sur /healthz continue de passer, donc les répliques ne sont pas redémarrées. Pointez la sonde de disponibilité sur /healthz à la place si vous préférez que les développeurs connectés continuent de travailler pendant une panne du magasin ; le coût est que les nouvelles connexions échouent contre une réplique qui signale toujours prête.

Si votre IdP tombe en panne, les sessions existantes fonctionnent jusqu'à ttl_hours, les nouvelles connexions échouent, et une actualisation de session obtient une réponse de réessai et se termine une fois que l'IdP est de retour. Définissez un ttl_hours plus long si votre IdP a des fenêtres de maintenance fréquentes.

Rotation du secret JWT

Faites tourner le secret de signature en trois étapes afin que les sessions existantes restent valides :

  1. Générez un nouveau secret. Ajoutez-le au début du tableau session.jwt_secret.
  2. Déployez le déploiement. Les nouveaux jetons signent avec le nouveau secret ; les anciens jetons valident toujours.
  3. Après ttl_hours plus une marge, supprimez l'ancien secret et déployez à nouveau.

La rotation est également le seul moyen de forcer les sessions à sortir avant leur expiration : les jetons porteurs valident localement par rapport au secret JWT, donc il n'y a pas de révocation par session. Remplacer le secret directement, sans conserver l'ancien dans le tableau, invalide chaque session en attente à la fois. Pour le déprovisionnement individuel, déprovisionner l'utilisateur dans votre IdP ; sa session se termine dans ttl_hours.

Postgres

La passerelle détient cinq tables de données plus une table _migrations, toutes créées par ses migrations au démarrage :

Table Contenu Rétention
kv Subventions d'appareil (TTL de 10 minutes) et compteurs de limite de débit TTL par ligne
spend Compteurs de dépenses période-à-date par principal, en cents admin.spend_retention_months, par défaut 13
spend_limits Plafonds de dépenses configurés Jusqu'à suppression via l'API
admin_audit Piste de mutation de l'API admin admin.audit_retention_days, par défaut 365
principal_emails Email, nom d'affichage et groupes IdP de chaque principal vus en dernier. Contient des PII. admin.identity_retention_days depuis la dernière activité, par défaut 90

Une boucle de 30 secondes expire les lignes kv au-delà de leur TTL, et un balayage horaire applique les fenêtres de rétention sur les tables de dépenses, donc rien ne croît sans limite. Sans limites de dépenses configurées, seul kv est écrit. La passerelle applique ses propres migrations de schéma au démarrage et à chaque mise à jour, donc son rôle de base de données a besoin de droits pour créer et modifier les tables. Pointez-le vers une base de données ou un schéma dédié à la passerelle pour garder cette autorisation étroite.

Avec les limites de dépenses en usage, une base de données perdue signifie le suivi des dépenses et les plafonds perdus, pas seulement les re-connexions des développeurs, donc exécutez des sauvegardes régulières. Pour effacer immédiatement un développeur parti plutôt que d'attendre la rétention, exécutez DELETE FROM principal_emails WHERE principal = '<sub>' directement ; cela supprime la seule table contenant son email, son nom et ses groupes. Les lignes spend et admin_audit ne référencent que le sub OIDC pseudonyme.

Mises à jour

Les répliques sont sans état, donc un redémarrage roulant ne perd aucun état de passerelle. La passerelle exécute les migrations de schéma au démarrage, ce qui signifie que le déploiement du nouveau binaire auto-migre la base de données. Les répliques concurrentes se sérialisent sur un verrou consultatif Postgres, donc seule une applique chaque migration.

Quand votre orchestrateur arrête une réplique avec SIGTERM, comme dans un redémarrage roulant ou une réduction d'échelle, la passerelle arrête d'accepter les nouvelles connexions et laisse les demandes et les flux déjà en vol se terminer avant de quitter. Elle attend jusqu'à 25 secondes, appelée la fenêtre de drainage, puis ferme tout ce qui est toujours ouvert. Un SIGINT, tel que Ctrl+C dans un terminal, démarre le même drainage, et un deuxième signal pendant le drainage ferme les demandes ouvertes et quitte immédiatement. Le drainage nécessite la passerelle v2.1.274 ou ultérieure.

Les générations longues peuvent diffuser en continu pendant des minutes. Sur Kubernetes et Amazon ECS, augmentez les deux ensemble pour donner à ces flux plus de temps :

  • La fenêtre de drainage : définissez la variable d'environnement CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS sur le conteneur de passerelle à un nombre entier positif de millisecondes, tel que 120000. La passerelle ignore une valeur sous toute autre forme, telle que 120s, et conserve la valeur par défaut de 25 secondes
  • La période de grâce de votre orchestrateur : terminationGracePeriodSeconds sur Kubernetes, ou stopTimeout sur Amazon ECS

La période de grâce par défaut est de 30 secondes sur les deux plates-formes. Gardez-la au moins 5 secondes plus longue que la fenêtre de drainage, ou l'orchestrateur tue la passerelle avant la fin du drainage. Sur Kubernetes, ajoutez également la durée de tout crochet preStop, car la période de grâce commence à compter avant que le crochet ne s'exécute plutôt que quand la passerelle reçoit SIGTERM.

Votre plate-forme peut également limiter la durée du drainage :

  • Amazon ECS sur Fargate : stopTimeout permet au maximum 120 secondes
  • Cloud Run : arrête une instance 10 secondes après SIGTERM, donc les flux ouverts obtiennent au maximum 10 secondes là, quelle que soit la fenêtre de drainage

Quand la fenêtre de drainage se termine avec des demandes toujours ouvertes, la passerelle enregistre un avertissement qui contient drain window over after, compte les demandes qu'elle a coupées, et nomme les deux paramètres à augmenter.

Les migrations sont en ajout seul, donc revenir à un binaire antérieur qui connaît moins de migrations est sûr ; il ignore les lignes supplémentaires. La restauration re-valide également le YAML par rapport au schéma du binaire plus ancien, donc une configuration qui a adopté une clé introduite par la version plus récente échoue au démarrage sur l'ancienne. Supprimez la nouvelle clé avant de revenir.

Parce que vous épinglez la version de la passerelle dans votre propre image, les correctifs dans les nouvelles versions de Claude Code, y compris les correctifs de sécurité, atteignent votre déploiement uniquement lorsque vous mettez à jour l'épingle et redéployez. Incluez la passerelle dans le même calendrier de correction que vous utilisez pour les autres services qui détiennent des credentials de production.

Sécurité

Cette section répond aux questions qu'un examen de sécurité pose : quelles données circulent à travers la passerelle et où elles vont, quelles attaques la conception défend, et quelles réponses appartiennent à un questionnaire de conformité.

Flux de données

Données Chemin Envoyé à Anthropic par la passerelle
Inférence (invites, complétions) CLI → passerelle → votre amont Uniquement si l'API Anthropic est un amont configuré
Télémétrie (métriques OTLP, plus journaux et traces opt-in) CLI → passerelle → votre collecteur Jamais
Identité (email, groupes, sub) IdP → passerelle → JWT → CLI ; le CLI l'estampille sur les exports OTLP. Si vous activez forward_user_identity, la passerelle envoie également l'email du développeur et le sujet IdP en tant qu'en-têtes à votre proxy Jamais
Paramètres gérés Votre YAML de passerelle → CLI Jamais
Journal d'audit Stderr de passerelle → votre agrégateur Jamais

Résumé du modèle de menace

La passerelle se trouve à l'intérieur de votre périmètre réseau, mais les ordinateurs portables des développeurs individuels ne sont pas traités comme de confiance. La conception en tient compte de trois façons :

  • Les développeurs détiennent des JWT de courte durée au lieu de clés en amont brutes. La jambe CLI-à-passerelle utilise la subvention d'appareil RFC 8628, et l'échange de code d'autorisation de la passerelle avec l'IdP exécute PKCE dans la configuration par défaut, donc un code d'autorisation IdP intercepté est inutile.

  • La page de vérification d'appareil applique POST de même origine et une limite de débit par IP par RFC 8628 §5.1. Consultez Résistance à la force brute du code utilisateur.

  • Les demandes de la passerelle à votre IdP, vos collecteurs OTLP, et les amonts provider: anthropic passent par une protection contre la falsification de demande côté serveur (SSRF) qui résout DNS, bloque les adresses de lien local et de métadonnées cloud plus la bouclage par défaut, et épingle la connexion à l'IP résolue, donc les URL influencées par l'opérateur ne peuvent pas être redirigées vers les points de terminaison de métadonnées cloud. Les plages privées RFC 1918 sont délibérément autorisées, car les IdP et les collecteurs OTLP vivent couramment sur des adresses IP privées. Pour les autres fournisseurs, la passerelle refuse une base_url qui nomme l'une de ces adresses ou un nom d'hôte de métadonnées lorsqu'elle charge la config, et le SDK du fournisseur se connecte ensuite sans la vérification DNS.

    Si vous activez sortie proxy uniquement, cette vérification d'adresse se déplace vers votre proxy avant : la passerelle lui transmet les noms d'hôte et la liste d'autorisation du proxy doit refuser ces destinations.

    Définissez CLAUDE_GATEWAY_ALLOW_LOOPBACK=1 dans l'environnement de la passerelle uniquement lorsque quelque chose que la passerelle doit atteindre légitimement vit sur la bouclage, comme un IdP de développement local ou un collecteur OTLP sidecar sur localhost. La variable assouplit le bloc de bouclage pour chaque URL configurée par l'opérateur et ignore également l'avertissement au démarrage qui vérifie si le pod peut atteindre le point de terminaison de métadonnées cloud, donc préférez donner au collecteur sa propre adresse interne.

Si vous ajoutez vos propres contrôles de sortie, la passerelle doit atteindre le serveur de métadonnées chaque fois qu'elle utilise des credentials de métadonnées d'instance tels que l'identité de charge de travail.

Deux menaces sont hors de portée car c'est votre infrastructure à sécuriser :

  • Un hôte de passerelle compromis : l'hôte détient à la fois la credential en amont et distribue les paramètres gérés à chaque développeur connecté, donc le contrôle de la configuration de la passerelle est comparable au contrôle de votre MDM. La boîte de dialogue d'approbation du CLI pour les paramètres capables de shell limite les changements silencieux mais ne remplace pas la sécurité de l'hôte.
  • Un fournisseur OIDC malveillant : le fournisseur signe les id_tokens que la passerelle fait confiance, donc il peut affirmer n'importe quelle identité. L'examen et la sécurisation de votre IdP sont votre responsabilité.

Résistance à la force brute du code utilisateur

Le user_code qu'un développeur tape dans la page de vérification /device est 8 caractères tirés d'un alphabet de 20 caractères, ce qui donne 20⁸ ou environ 2,56×10¹⁰ combinaisons, et il expire après 10 minutes.

La passerelle applique des limites de débit par IP sur les points de terminaison de subvention d'appareil, configurables via rate_limits. Augmentez les limites si de nombreux développeurs se connectent à partir d'une seule adresse NAT d'entreprise partagée. Les déploiements à grande échelle montre comment les dimensionner. Les limites s'appliquent uniquement au flux de connexion, pas à l'inférence.

Posture de conformité

  • Résidence des données : le plan de données de la passerelle elle-même n'envoie rien à Anthropic sauf si l'API Anthropic est un amont configuré ; lorsqu'elle l'est, votre accord de traitement des données existant s'applique au chemin d'inférence. La télémétrie, l'audit, l'identité et les paramètres vont uniquement aux destinations que vous configurez.
  • Trafic du processus hôte : le processus hôte est le CLI Claude Code. La commande claude gateway s'exécute selon les mêmes règles tierces que les déploiements Amazon Bedrock et Google Cloud Agent Platform et n'envoie rien à Anthropic. Avant la v2.1.227, le processus hôte envoyait la télémétrie de démarrage telle que la version du produit et la plateforme, que le paramètre CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 dans l'environnement du conteneur désactivait. Ces versions envoyaient également une demande HEAD au démarrage, sans corps ni credentials, à /api/hello sur https://api.anthropic.com, ou sur ANTHROPIC_BASE_URL lorsque l'environnement l'a défini, sauf si l'environnement a également défini une variable proxy telle que HTTPS_PROXY ou un certificat client mTLS. Elles ignoraient la réponse, donc bloquer cette demande au pare-feu de sortie n'affectait pas la passerelle.
  • Analytique client : le CLI désactive sa propre analytique d'utilisation et le rapport d'erreurs lorsqu'il est connecté à une passerelle. Avant la première connexion, le CLI envoie toujours les événements de démarrage à Anthropic, y compris sur les machines dont les paramètres gérés forcent la connexion à la passerelle. Pour les désactiver aussi, livrez DISABLE_TELEMETRY dans les mêmes paramètres gérés côté client qui forcent la connexion à la passerelle.
  • Rapport d'erreurs : le CLI désactive le rapport d'erreurs chaque fois que ses demandes de modèle vont à n'importe quel point de terminaison autre que l'API première partie d'Anthropic, comme Amazon Bedrock ou un ANTHROPIC_BASE_URL personnalisé.
  • Machines client : les CLI des développeurs envoient toujours les vérifications de nom d'hôte WebFetch et les vérifications de version à Anthropic sauf si CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 et skipWebFetchPreflight: true sont définis. Consultez utilisation des données.
  • Évaluations d'enquête : lorsqu'il est connecté à une passerelle, le CLI désactive le téléchargement d'évaluation lié à Anthropic ainsi que les flux d'analytique, donc il n'envoie pas les évaluations à Anthropic.
  • Partage de transcription : choisir Oui sur une invite de partage de transcription d'enquête écrit un fichier local sous ~/.claude/feedback-bundles/ au lieu de télécharger vers Anthropic.
  • Mises à jour client : les vérifications de mise à jour sont séparées du trafic de passerelle. Épinglez les versions via votre propre distribution et définissez DISABLE_UPDATES si les ordinateurs portables ne doivent pas récupérer les versions. DISABLE_AUTOUPDATER arrête uniquement les mises à jour en arrière-plan tandis que claude update fonctionne toujours.
  • TLS : servez public_url via HTTPS en production, soit à partir du propre écouteur de la passerelle via listen.tls, soit à partir d'une ingress terminant TLS devant les répliques HTTP simples, avec listen.public_url défini dans les deux cas. La passerelle ne refuse pas HTTP simple. L'IdP doit servir HTTPS en production, et Postgres supporte ?sslmode=require. Définissez Strict-Transport-Security à votre ingress.
  • Divulgation de vulnérabilité : suivez Signaler les problèmes de sécurité

Dépannage

Pour les questions et les commentaires, utilisez le support Claude Code, ou ouvrez un problème sur le référentiel GitHub Claude Code. Lors de la signalisation d'un problème, incluez :

  • Problème de passerelle : la sortie d'erreur de la passerelle pour la fenêtre pertinente, votre gateway.yaml avec les secrets masqués, la version de la passerelle, affichée sur la page d'accueil à / et dans l'en-tête de réponse x-cc-gateway-version sur /managed/settings, et ce qui a changé récemment
  • Problème de connexion : le développeur exécute claude --debug-file ./claude-debug.txt, reproduit le problème, et envoie ce fichier plus le journal d'audit de la passerelle pour la même fenêtre
  • Problème d'inférence : le modèle demandé, les upstreams configurés, et le journal d'audit de la passerelle pour la demande, qui enregistre quel upstream l'a servie et le statut de la réponse

La sortie d'erreur de la passerelle inclut le flux d'événements d'audit, le journal d'audit enregistre les identités des développeurs, et le fichier de débogage enregistre la sortie des hooks et du serveur MCP de la machine du développeur. Examinez et masquez ces éléments avant de les publier sur un problème public.

Symptôme Cause Correction
L'écran /login d'un développeur affiche le sélecteur de compte standard au lieu de l'écran Passerelle Cloud forceLoginMethod ou forceLoginGatewayUrl n'est pas défini dans les paramètres gérés sur cette machine Déployez le fichier de paramètres gérés sur l'appareil ; /login lit l'URL de la passerelle à partir de là
Les demandes d'un développeur échouent avec Not signed in to the Cloud gateway — run /login. Les paramètres gérés de la machine définissent forceLoginMethod: "gateway" ou forceLoginGatewayUrl, et la session n'a pas de connexion à la passerelle. Une connexion claude.ai restante ne satisfait pas à l'exigence. Demandez au développeur d'exécuter /login et de terminer la connexion à la passerelle. Voir aussi La politique de l'administrateur nécessite une connexion à la passerelle Cloud.
Claude Desktop signale que sa configuration d'amorçage n'a pas pu être récupérée /user/bootstrap a renvoyé 404 : la politique correspondant à l'utilisateur ne porte pas de clé desktop, ou aucune politique n'a correspondu. Le journal d'audit de la passerelle enregistre chaque rejet sous la forme desktop_bootstrap.denied avec la raison. Ajoutez un bloc desktop à la politique qui correspond à l'utilisateur, ou à la couche de base match: {} ; un desktop: {} vide suffit. Voir Superposition Claude Desktop.
Le démarrage affiche Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support. La version de Claude Code installée est antérieure au support de la passerelle Demandez au développeur de mettre à jour Claude Code vers une version qui inclut le support de la passerelle Cloud
Le démarrage se termine avec Administrator policy requires a Cloud gateway sign-in on this machine L'environnement du développeur définit ANTHROPIC_API_KEY ou ANTHROPIC_AUTH_TOKEN, ses paramètres configurent un apiKeyHelper, ou une clé API d'une connexion Claude Console antérieure est toujours enregistrée Demandez au développeur d'effacer chacun de ces éléments : désactiver la variable, supprimer l'entrée apiKeyHelper, ou exécuter claude auth logout pour supprimer la clé enregistrée. Ensuite, demandez-lui de démarrer claude et de se connecter avec /login. Voir aussi La politique de l'administrateur nécessite une connexion à la passerelle Cloud.
Le démarrage ou /login signale Claude Code may not be enabled for your organization après un 403 lors du chargement des paramètres gérés La passerelle, ou quelque chose devant elle, a répondu à la demande /managed/settings avec 403. La route de paramètres propre de la passerelle ne répond jamais 403. Le statut provient des vérifications IP access_control ou d'un proxy ou WAF devant la passerelle. Le journal d'audit enregistre un refus de vérification IP sous la forme access.denied avec la raison. Le développeur reste connecté. Vérifiez le journal d'audit pour access.denied au moment de l'échec et corrigez les listes access_control ou le front-end, puis demandez au développeur de démarrer claude à nouveau
CLI /login : The gateway is limiting sign-in attempts right now, ou Request failed with status code 429 sur les versions antérieures. La page /device peut afficher Too many attempts aux développeurs qui n'ont pas essayé auparavant La limite de débit de connexion par IP a été atteinte. Soit listen.trusted_proxies ne couvre pas l'équilibreur de charge, donc chaque développeur partage son adresse, soit de nombreux développeurs partagent une adresse de sortie NAT ou VPN. Les événements d'audit avec result: rate_limited affichent la même une ou quelques valeurs client_ip. Définissez d'abord listen.trusted_proxies sur les plages sources de l'équilibreur de charge, puis augmentez rate_limits si les développeurs partagent toujours des adresses. Voir Déploiements à grande échelle.
CLI /login : Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip> Le nom d'hôte de la passerelle se résout en au moins une adresse IP publique. Claude Code vérifie chaque adresse résolue et exige que chacune soit privée. Une cause courante est un nom double pile où une famille se résout en une adresse publique, y compris les équilibreurs de charge double pile internes AWS, qui renvoient des adresses AAAA de plage publique. Faites en sorte que le nom de la passerelle se résout uniquement en adresses privées sur les machines des développeurs. Pour un nom double pile, supprimez l'enregistrement de plage publique ou servez un nom DNS interne uniquement. Voir la condition préalable du réseau privé. Si l'adresse est un espace public que votre organisation possède et utilise en interne, déclarez ce bloc à la place.
CLI /login : Gateway login would go through proxy <proxy>, which is not on a private network Un HTTPS_PROXY ou HTTP_PROXY s'applique à l'hôte de la passerelle et le nom d'hôte du proxy se résout en une adresse publique. Un proxy dont l'hôte se résout uniquement en adresses privées est autorisé et ne déclenche pas cette erreur Ajoutez l'hôte de la passerelle à NO_PROXY sur la machine du développeur pour que la connexion soit directe, ou utilisez un proxy dont le nom d'hôte se résout en adresses privées. Le message nomme l'entrée NO_PROXY exacte à ajouter
CLI /login : Claude Code only signs in to <host> from inside its declared network <block> (managed settings), and this machine is connecting from <ip>, outside it La passerelle se trouve sur un bloc déclaré dans gatewayInternalNetworks, et la machine du développeur l'a atteinte à partir d'une adresse en dehors de ce bloc : une adresse de pool VPN, un segment NAT de conteneur ou WSL2, ou un réseau qui n'est pas le vôtre Demandez au développeur d'exécuter /login à partir du système d'exploitation hôte sur votre réseau. Si l'adresse affichée est également votre propre espace public, remplacez l'entrée de la passerelle par un bloc qui couvre les deux, jusqu'à /8 ; une deuxième entrée chevauchante est refusée
CLI /login : Every address for gateway host <host> must be inside its declared network <block>, and it also resolves to <ip> Le nom de la passerelle se résout en une adresse en dehors du bloc déclaré dans gatewayInternalNetworks : un deuxième site, ou un enregistrement IPv6 sur un nom double pile. Sous un bloc déclaré, chaque enregistrement doit être à l'intérieur de ce bloc IPv4, adresses privées et IPv6 incluses Publiez uniquement les enregistrements à l'intérieur du bloc pour le nom de la passerelle sur les machines des développeurs, ou servez un nom interne uniquement
CLI /login : <host> is on the declared network <block>, which Claude Code checks over a direct connection, not through an HTTP proxy Un HTTPS_PROXY ou HTTP_PROXY s'applique à une passerelle sur un bloc déclaré Sur la machine du développeur, ajoutez l'entrée NO_PROXY que le message nomme
CLI /login : un message commençant par gatewayInternalNetworks in managed settings La valeur viole l'une des règles de validation, et le message nomme laquelle. Jusqu'à ce que vous la corrigiez, Claude Code refuse chaque nouveau /login de passerelle sur la machine, y compris les passerelles sur adresses privées ; les connexions existantes continuent de fonctionner Dans la source des paramètres gérés que vous déployez, corrigez l'entrée que le message nomme, puis réexécutez /login
CLI /login : Could not resolve the configured HTTP proxy Le nom d'hôte dans HTTPS_PROXY ou HTTP_PROXY ne se résout pas à partir de la machine du développeur, généralement parce qu'il n'est pas connecté au réseau d'entreprise Demandez au développeur de se connecter à votre réseau ou VPN et de réessayer, ou corrigez l'URL du proxy
CLI /login : Could not resolve gateway host <host> La machine ne peut pas résoudre le nom DNS interne de la passerelle, généralement parce qu'elle n'est pas sur le réseau d'entreprise Demandez au développeur de se connecter à votre réseau ou VPN, puis de réessayer /login
Le démarrage se termine avec une erreur de validation de configuration nommant store.postgres_url Aucun Postgres configuré ; la passerelle nécessite Postgres Définissez store.postgres_url. Pour le développement local, utilisez un conteneur jetable : docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres.
Le démarrage se termine : requires the native binary Exécution sous Node au lieu du binaire natif Installez Claude Code avec l'une des méthodes d'installation autonome
Le démarrage se termine avec une erreur de découverte OIDC après config.load oidc.issuer inaccessible, ou chaîne TLS non approuvée Vérifiez que l'émetteur est accessible à partir du pod et sert /.well-known/openid-configuration. Définissez ca_cert_pem pour l'infrastructure à clé publique privée. Si le pod atteint l'IdP uniquement via un proxy de transfert, définissez oidc.use_proxy: true ; sur les versions antérieures à v2.1.227, donnez au pod une route directe vers chacun des points de terminaison de l'IdP à la place. Si le pod ne peut pas non plus résoudre le nom d'hôte de l'IdP, ou le proxy refuse CONNECT à une adresse IP, voir Sortie proxy uniquement, qui nécessite v2.1.277 ou ultérieur.
Le démarrage se termine avec une erreur de permission Postgres Le rôle de base de données manque de droits DDL sur son schéma Accordez au rôle CREATE sur le schéma de la passerelle pour qu'il puisse créer et modifier ses tables au démarrage
Journal : could not connect to Postgres at boot, attempt 1 of 3 La base de données n'était pas accessible lorsque la passerelle a démarré, par exemple sur une instance froide dont le réseau est encore en cours de configuration Si la passerelle termine ensuite le démarrage, aucune action n'est nécessaire. Lorsque la base de données n'est pas accessible, la passerelle essaie la connexion trois fois, deux secondes d'intervalle, avant de se terminer. Si elle se termine avec could not connect to Postgres, vérifiez store.postgres_url et le chemin réseau vers la base de données. Si les tentatives expirent plutôt que d'être refusées, augmentez store.connect_timeout_seconds pour donner à chacune plus de temps.
/oauth/callback affiche « Sign-in could not be completed » Domaine de courrier électronique rejeté, validation id_token échouée, ou email_verified est explicitement false, que la passerelle rejette toujours sans remplacement Vérifiez allowed_email_domains et que l'IdP renvoie une réclamation email vérifiée. Pour email_verified: false, corrigez la vérification côté IdP. Si votre IdP émet le courrier électronique sous un nom de réclamation différent, définissez oidc.email_claim.
Journal : token exchange failed request_id=<id>: id_token missing email claim L'IdP n'inclut pas email dans l'id_token par défaut. Ce rejet ne se déclenche que lorsque allowed_email_domains est défini ; sans lui, un courrier électronique manquant crée une session sans courrier électronique Configurez l'IdP pour émettre email dans l'id_token. Okta : ajoutez email aux réclamations de jeton d'ID d'un serveur d'autorisation personnalisé. Entra : ajoutez email comme réclamation facultative sur l'enregistrement de l'application. PingFederate : activez une politique OpenID Connect qui émet email. Si l'IdP sert email à partir du point de terminaison userinfo mais ne l'inclura pas dans l'id_token, comme le serveur d'autorisation org Okta, définissez oidc.userinfo_fallback: true.
Journal : refresh failed request_id=<id>: invalid_token (…) (at userinfo_no_id_token, …), et les développeurs voient Cloud gateway session expired tous les session.ttl_hours L'IdP a accepté le jeton d'actualisation mais n'a renvoyé aucun id_token avec lui, donc la passerelle a demandé au point de terminaison userinfo de l'IdP les réclamations de l'utilisateur. L'IdP a rejeté le jeton d'accès actualisé là. La passerelle répond temporarily_unavailable, donc Claude Code conserve le jeton d'actualisation mais ne peut pas renouveler la session. Les versions de passerelle antérieures à v2.1.260 enregistrent la même ligne sans le détail (at …). Définissez oidc.scope_on_refresh: true, disponible dans la passerelle v2.1.260 ou ultérieure, pour que la demande d'actualisation demande à nouveau openid. Certains IdP, comme Okta, renvoient un id_token lors de l'actualisation uniquement lorsqu'on le demande. Sur PingFederate, activez Return ID Token On Refresh Grant sous Applications > OAuth > OpenID Connect Policy Management à la place. La clé ne change pas le comportement de PingFederate. Pour les autres IdP qui l'omettent toujours, vérifiez si le point de terminaison userinfo accepte les jetons d'accès émis par une actualisation. En tant que solution temporaire, augmentez session.ttl_hours. Voir Configuration du fournisseur d'identité pour le compromis de déprovisionnement.
Chaque demande Amazon Bedrock renvoie 502 ; le journal affiche Could not load credentials from any providers Sur EC2, la limite de saut par défaut d'IMDSv2 de 1 bloque la demande de métadonnées d'instance de l'intérieur du conteneur. Le démarrage et /readyz réussissent quand même parce que le SDK AWS résout les identifiants d'instance à la première demande, pas à la construction du client Augmentez la limite de saut avec aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2, ou définissez-la dans le modèle de lancement. La modification s'applique à chaque conteneur sur l'instance. Préférez les rôles de tâche ECS le cas échéant, qui lisent les identifiants à partir du point de terminaison des identifiants de conteneur ECS et évitent complètement la modification, ou appliquez la modification sur une instance de passerelle dédiée pour limiter l'exposition.
À charge maximale, les réponses sont lentes à démarrer ou semblent se bloquer, ou échouent avec un 502 all upstreams failed alors que l'upstream est sain Une réplica a plus de demandes ouvertes qu'elle n'en envoie en amont à la fois, donc les demandes supplémentaires attendent à l'intérieur de la passerelle. Sur un upstream provider: anthropic, une demande qui attend plus longtemps que timeouts.upstream_ttfb_ms abandonne cet upstream, ce qui produit le 502 lorsqu'aucun upstream ultérieur ne la sert. Le journal affiche un avertissement contenant client requests are open. Ajoutez des réplicas, ou augmentez la limite sur chaque réplica. Voir Demandes upstream concurrentes.
Erreur IdP : portée inconnue ou non prise en charge L'IdP rejette les portées qu'il ne reconnaît pas Définissez oidc.scopes exactement à la liste que votre IdP accepte ; elle doit inclure openid. La valeur par défaut est openid profile email offline_access.
Les sessions ne se renouvellent pas silencieusement après la définition de oidc.scopes offline_access a été supprimé de la substitution Rajoutez offline_access si votre IdP le prend en charge. Sans jeton d'actualisation, les développeurs réexécutent la connexion du navigateur tous les session.ttl_hours.
Le navigateur affiche « This request came from another site and was blocked » POST de formulaire intersite, bloqué comme protection CSRF. Attendu pour les pages intégrées ou proxifiées Ouvrez le lien de vérification directement
Chrome bloque le bouton Approuver avec « Refused to send form data … violates … Content Security Policy directive: form-action », mais la même page fonctionne dans Safari ou Firefox Chrome applique form-action à toute la chaîne de redirection. Votre IdP redirige ensuite vers un deuxième hôte qui n'est pas sur la liste blanche. Ajoutez chaque origine supplémentaire dans la chaîne de redirection à oidc.form_action_origins. Ouvrez Chrome DevTools → Console sur la page Approuver pour voir quelle origine a été bloquée.
La connexion se termine à l'IdP mais le rappel échoue, avec une erreur CSP dans Chrome ou « this sign-in link has expired » dans Safari L'IdP a renvoyé le code via response_mode=form_post, qui le soumet automatiquement intersite via POST à /oauth/callback. Chrome bloque cela sous une CSP stricte ; Safari autorise la soumission mais le rappel lit uniquement la chaîne de requête. Assurez-vous que votre IdP honore response_mode=query, que la passerelle demande explicitement pour que le rappel soit une redirection simple
La connexion fonctionne localement mais échoue derrière un ALB public_url nomme toujours l'origine http:// locale ou interne, donc l'IdP obtient le mauvais redirect_uri Définissez listen.public_url sur l'origine https:// externe et enregistrez <public_url>/oauth/callback auprès de l'IdP
Le développeur voit l'invite de confiance à plusieurs reprises Le certificat TLS tourne par réplica ou par demande Utilisez un certificat stable à l'entrée, ou terminez TLS une fois et exécutez les réplicas sur HTTP simple en interne
CLI /login : « Could not verify the gateway's TLS certificate » ou SELF_SIGNED_CERT_IN_CHAIN La chaîne TLS de la passerelle est signée par une CA privée qui n'est pas dans le magasin de confiance de l'hôte CLI Claude Code lit le magasin de confiance du système d'exploitation par défaut sur le binaire natif et sur Node 22.15 ou ultérieur ; CLAUDE_CODE_CERT_STORE contrôle ce comportement. Si la CA est installée dans le magasin de confiance du système d'exploitation, assurez-vous que les développeurs utilisent un runtime actuel. Sinon, définissez NODE_EXTRA_CA_CERTS sur le certificat CA PEM avant de lancer. L'invite d'empreinte digitale de première connexion s'applique toujours.
CLI /login termine la connexion du navigateur, puis la session se termine avec Cloud gateway sign-in was not completed et une incompatibilité de certificat TLS À la première demande après la connexion, la passerelle a présenté un certificat qui ne correspond pas à l'empreinte digitale que Claude Code a épinglée, donc Claude Code n'a conservé aucune identifiant de passerelle. Les causes habituelles sont les réplicas derrière une adresse qui servent des certificats différents, ou quelque chose sur le chemin réseau qui intercepte TLS. Servez un certificat pour le nom d'hôte, par exemple en terminant TLS une fois à l'entrée, puis demandez au développeur d'exécuter /login à nouveau. Si ce certificat diffère de celui épinglé, Claude Code affiche l'invite de confiance à nouveau avec un avertissement que le certificat a changé.
CLI /login s'arrête avec The gateway's TLS certificate changed during sign-in: it no longer matches the one you trusted Une demande de connexion a atteint un serveur dont le certificat ne correspond pas à celui que le développeur a accepté au démarrage de /login : réplicas derrière une adresse servant des certificats différents, interception TLS sur le chemin, ou rotation de certificat pendant que la connexion était en cours. Servez un certificat pour le nom d'hôte, puis demandez au développeur de recommencer la connexion et d'examiner le nouveau certificat à l'invite de confiance.

Le message Cloud gateway sign-in was not completed nomme le nom d'hôte de la passerelle. Lorsque Claude Code a à la fois l'empreinte digitale épinglée et celle présentée, le message affiche également les 16 premiers caractères de chacune.

Si Claude Code signale couldn't load your organization's managed settings après une connexion à la passerelle, Claude Code nomme la raison, redémarre sur place et reprend la conversation. Si Claude Code ne peut pas redémarrer, par exemple dans une session d'arrière-plan, Claude Code termine la session et conserve la connexion.