Ton équipe utilise déjà Claude Code, avec ou sans ton accord. Le premier réflexe d'une DSI est de bloquer ; le deuxième, de lancer un chantier d'infrastructure qui finira par produire un outil que personne n'utilise. Entre les deux, il y a deux questions précises : où s'exécutent les sessions, et par où passe l'inférence, sous quelle identité et avec quel budget. Elles sont indépendantes, et on peut vouloir l'une sans l'autre.
Anthropic fournit une brique pour chacune. Les self-hosted runners font tourner les sessions cloud de Claude Code sur tes machines. La Claude apps gateway est un plan de contrôle auto-hébergé qui apporte SSO d'entreprise, politiques centralisées, plafonds de dépense et attribution des coûts par développeur. Cet article explique quand l'une, l'autre ou aucune des deux se justifie, comment les configurer d'après la documentation officielle, et comment piloter un déploiement en quatre semaines plutôt qu'en six mois.
Runners ou gateway : quelle brique répond à quel problème ?
Le runner fait tourner les sessions cloud, celles qu'on lance depuis claude.ai/code, les applications mobile et desktop ou des routines planifiées, dans ton réseau. Le plan de contrôle reste chez Anthropic : file d'attente, interface et historique de session. La fonctionnalité est en bêta publique sur les plans Team et Enterprise, désactivée par défaut ; un Owner l'active dans l'administration de claude.ai.
La gateway est un service que tu héberges entre les clients Claude Code (CLI et Claude Desktop) et ton fournisseur de modèles : Bedrock, Vertex, Foundry ou l'API Anthropic. Les développeurs s'authentifient en SSO OIDC, la gateway détient le credential du fournisseur, applique l'accès aux modèles par groupe et relaie la télémétrie vers ta stack. Elle est embarquée dans le binaire de Claude Code (claude gateway --config gateway.yaml), sans licence séparée.
Le piège de lecture que la plupart des présentations ratent : ces deux briques ne s'empilent pas. Les sessions web et mobile ne passent pas par la gateway, qui ne sert que la CLI et Desktop. Et le runner envoie le flux d'événements de session (prompts, réponses, résultats d'outils) à api.anthropic.com, même quand son inférence est redirigée vers Bedrock ou Vertex. Je n'ai trouvé dans la documentation aucune configuration qui fasse passer les sessions d'un runner par la gateway : ne la suppose pas dans ton architecture.
Quand en as-tu vraiment besoin ?
Commence par ne rien déployer : la doc rappelle elle-même que la plupart des équipes sont mieux servies par les environnements hébergés par Anthropic. L'auto-hébergement a un coût d'exploitation réel. Cinq déclencheurs le justifient :
- Accès au code et aux services internes (runner) : les sessions cloud doivent atteindre un GitLab interne, un registre privé ou une base de recette sans les exposer à Internet.
- Exécution dans ton périmètre (runner) : checkouts et artefacts de build restent chez toi. Mais le contenu de la conversation part toujours chez Anthropic, et le runner est indisponible pour les organisations en Zero Data Retention ou sous configuration HIPAA.
- Résidence des données d'inférence (gateway) : l'inférence passe par ton compte AWS, Google Cloud ou Azure, les credentials ne quittent pas ton réseau, télémétrie et journaux d'audit restent chez toi. Si ton exigence est « rien vers Anthropic », c'est la gateway avec un fournisseur cloud, pas le runner.
- Gouvernance et refacturation (gateway) : plafonds de dépense par développeur ou par groupe, attribution des coûts, liste des modèles autorisés par groupe, départ d'un collaborateur géré dans l'annuaire.
- Réseau privé strict (les deux) : le runner n'ouvre que des connexions sortantes, Anthropic ne se connecte jamais dans ton réseau ; le client refuse une gateway dont l'adresse n'est pas privée.
Tu n'as probablement besoin de rien si tu es une petite équipe sans exigence de confinement, avec une dépense que tu surveilles déjà : déployer ces briques ajouterait de la maintenance sans résoudre un problème que tu as. Pour le volet juridique européen, voir souveraineté et conformité RGPD des agents de code.
Comment faire tourner les sessions Claude Code sur ton infrastructure ?
D'après la doc des self-hosted environments, le runner est une sous-commande du binaire standard. Prérequis : Claude Code 2.1.224 ou plus, Git 2.24 ou plus, un hôte Linux ou macOS (Windows passe par un conteneur Linux), du HTTPS sortant vers api.anthropic.com et ton hébergeur Git, et une horloge synchronisée. Anthropic ne publie pas d'image : tu construis la tienne, avec le binaire épinglé et tes outils (PHP, Composer, CLI internes). Le secret d'environnement s'affiche une seule fois à la création et expire au bout de 365 jours.
claude self-hosted-runner --help # vérifie la version
mkdir -p /etc/claude
(umask 077 && cat > /etc/claude/environment-secret) # colle la clé, puis Ctrl-D
claude self-hosted-runner \
--environment-secret-file /etc/claude/environment-secret \
--base-dir /var/lib/claude-runner
# Variante guidée, avec un compte Owner
claude self-hosted-runner setupLancé ainsi, le runner sort volontairement après une session : en production, un orchestrateur le relance. Un runner se verrouille sur le premier propriétaire dont il prend une session et ne sert plus que lui, jusqu'à --capacity sessions simultanées. Pour l'isolation, la doc recommande --capacity 1 et un conteneur jetable par session ; ses propres exemples Compose et Kubernetes utilisent une capacité de 4 pour la démonstration, à ne pas copier en production. Extrait d'un Deployment Kubernetes :
spec:
template:
spec:
terminationGracePeriodSeconds: 90 # le drain demande jusqu'à 80 s par défaut
containers:
- name: runner
image: registry.example.com/claude-runner:2.1.299
args:
- self-hosted-runner
- --environment-secret-file
- /etc/claude/environment-secret
- --capacity
- "1"
- --confine-repo-settings
- enforce
resources:
requests: { cpu: "2", memory: 4Gi }
limits: { cpu: "4", memory: 4Gi }
readinessProbe:
httpGet: { path: /healthz, port: 8080 }- Drain : sur
SIGTERM, le runner arrête de prendre du travail, termine les sessions puis exécute son hook de fin, soit 80 secondes par défaut. Le délai par défaut de Kubernetes est de 30 secondes : sansterminationGracePeriodSecondsrelevé, le pod est tué avant la fin. Et avec--drain-wait-secà 0, un redémarrage progressif coupe les tours en cours. - Proxy de sortie authentifié : le runner respecte
HTTPS_PROXYetNO_PROXY. Pour un proxy qui exige un en-tête d'autorisation tournant,--proxy-authorization-commandou--proxy-authorization-file(v2.1.238+) démarrent un relais local qui l'ajoute. Le proxy ne doit pas bufferiser les réponses, le streaming de session utilise SSE. - Supervision :
/healthzrépond tant que le processus vit, même si sa boucle d'attente est bloquée. Alerte plutôt sur la métrique Prometheusclaude_code_self_hosted_runner_last_poll_age_seconds. - Runners à la demande : plutôt qu'une flotte fixe où le secret est lisible par le code de chaque session,
claude self-hosted-runner orchestratorcrée un runner par session avec un jeton à usage unique, et garde le secret sur un hôte qui n'exécute jamais de code utilisateur.
Qu'est-ce que la Claude apps gateway et comment la configurer ?
La Claude apps gateway, annoncée par Anthropic en juin 2026, est un conteneur Linux sans état adossé à PostgreSQL et à un fournisseur d'identité OIDC (Okta, Entra ID, Google Workspace, Keycloak… mais ni SAML ni LDAP). D'après la doc de la gateway, elle exige Claude Code 2.1.195 ou plus sur le serveur et sur chaque poste, PostgreSQL 11 ou plus et du HTTPS. Le client refuse de s'y connecter si son adresse ne résout pas vers une IP privée. Configuration minimale avec Bedrock :
listen:
host: 0.0.0.0
port: 8080
public_url: https://claude-gateway.internal.example.com # doit résoudre en IP privée
oidc:
issuer: https://login.example.com
client_id: 0oa1example2
client_secret: ${OIDC_CLIENT_SECRET}
allowed_email_domains: [example.com]
session:
jwt_secret: ${GATEWAY_JWT_SECRET}
ttl_hours: 1 # borne aussi le délai de révocation après départ
store:
postgres_url: ${GATEWAY_POSTGRES_URL}
upstreams:
- provider: bedrock
region: eu-west-3
auth: {} # chaîne de credentials AWS par défaut (IRSA, rôle de tâche)Votre équipe utilise Claude Code ?
Formation intra sur vos projets réels : de la demi-journée à 2 jours, 6 devs max.
Le démarrage échoue proprement si la configuration, PostgreSQL ou l'OIDC posent problème, mais les credentials Bedrock ne sont résolus qu'à la première requête : un démarrage réussi ne valide pas le chemin d'inférence. Côté postes, les clés de connexion se poussent par MDM dans les managed settings. allowedProviders (v2.1.285+) interdit le contournement par variable d'environnement ou par ANTHROPIC_BASE_URL :
{
"forceLoginMethod": "gateway",
"forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
"allowedProviders": ["gateway"]
}Comment plafonner les dépenses et refacturer par équipe ?
Les plafonds ne se déclarent pas dans gateway.yaml : on active le bloc admin avec des clés d'écriture, puis on les pose par API. Les montants sont en centimes de dollar, sur des périodes quotidiennes, hebdomadaires ou mensuelles, à la portée d'un utilisateur, d'un groupe de l'annuaire ou de l'organisation. Un plafond de groupe est un défaut par siège, pas une enveloppe partagée. Au dépassement, la gateway répond 429.
# 500 $ par mois et par développeur, par défaut pour l'organisation
curl -sS https://claude-gateway.internal.example.com/v1/organizations/spend_limits \
-H "x-api-key: $GATEWAY_ADMIN_WRITE_KEY" -H "Content-Type: application/json" \
-d '{"scope": {"type": "organization"}, "amount": "50000", "period": "monthly"}'
# 100 $ par jour pour le groupe des prestataires
curl -sS https://claude-gateway.internal.example.com/v1/organizations/spend_limits \
-H "x-api-key: $GATEWAY_ADMIN_WRITE_KEY" -H "Content-Type: application/json" \
-d '{"scope": {"type": "rbac_group", "rbac_group_id": "contractors"}, "amount": "10000", "period": "daily"}'- Ce que voit le développeur : des avertissements à 75 puis 95 %, une barre de plafond dans
/usageet dans la statusline, affichée en dollars depuis la v2.1.284 côté client et serveur. - Fail-open par défaut : si PostgreSQL tombe, les requêtes passent sans être mesurées. Pose
enforcement.fail_closed_on_error: truesi le plafond doit être un contrôle dur. - Tarification : le bloc
pricingde la gateway règle la mesure qui sert aux plafonds, avec unmultiplierentre 0 et 10 (supérieur à 1 pour une refacturation interne, à partir de la v2.1.271) et des tarifs par modèle. C'est une estimation et un coupe-circuit, pas une facture. À ne pas confondre avecmodelPricing, réglage managé côté client qui aligne l'affichage de/usagesur tes tarifs négociés. - Attribution : la télémétrie OTLP relayée par la gateway est estampillée avec l'identifiant, l'e-mail et les groupes de l'utilisateur, sans configuration sur les postes. Elle se branche sur la stack décrite dans l'article sur le suivi de consommation.
Comment utiliser Bedrock avec rôles AWS et guardrails ?
Depuis la v2.1.281, un upstream Bedrock peut assumer un rôle dans un autre compte AWS, avec une session STS distincte par développeur pour retrouver l'attribution des coûts dans CloudTrail et la facturation AWS, et appliquer un guardrail Bedrock. Si l'appel STS échoue, la gateway ne retombe pas sur les credentials de base : elle essaie l'upstream suivant.
upstreams:
- name: bedrock-isolated
provider: bedrock
region: eu-west-3
auth: {}
assume_role:
role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock-user
session_name: email # une session par développeur
guardrail:
id: gr-abc123
version: "1" # guillemets obligatoires, sinon le démarrage échoueLimites documentées de la gateway à connaître avant de t'engager : pas de recherche web côté serveur, pas de Remote Control, un cache de prompt limité à cinq minutes au lieu d'une heure, et pas de chemin pour une CI sans humain, car la connexion passe toujours par un flux navigateur. Les pipelines doivent parler directement au fournisseur.
Quels sont les points de sécurité à ne pas rater ?
- Runner : qui peut dispatcher exécute du code sur ton hôte. Tout membre de l'organisation peut envoyer une session vers n'importe quel environnement. Ne mets sur un hôte runner que des données lisibles par tous ces membres.
- Runner : métadonnées cloud. Bloque
169.254.169.254dans le conteneur de session, et préfère une identité de charge de travail en fichier. - Runner : credential d'inférence minimal. S'il passe par Bedrock, il est lisible depuis la session, donc par une injection de prompt : donne-lui uniquement le droit d'invoquer les modèles utilisés.
- Runner : réglages du dépôt.
--confine-repo-settings enforcerefuse les sessions dont les settings commités élargissent les droits d'écriture ou désactivent la sandbox. Démarre en modewarnpour voir ce qu'il signale. - Runner : sortie réseau fermée par défaut, à ta frontière : le produit ne peut ni la vérifier ni l'appliquer.
- Gateway : contournement. Elle n'impose pas d'être la seule route vers un modèle. Un développeur avec sa propre clé peut appeler le fournisseur directement : ferme ce chemin au niveau réseau, en plus d'
allowedProviders. - Gateway : réseau et identité. Renseigne
access_control.allow_cidrs, sinon elle sert n'importe quelle adresse. Les jetons durent une heure, et une rotation du certificat redemande une confirmation à chaque développeur : planifie-la. - Gateway : données. Elle ne stocke ni prompts ni réponses ; la table des identités contient des données personnelles, conservées 90 jours par défaut.
Combien coûte l’exploitation de ces briques ?
La gateway n'a pas de licence ; les runners exigent un plan Team ou Enterprise, et leurs sessions consomment l'usage de l'organisation. Côté calcul, la doc propose comme base 4 Gio de mémoire et 2 à 4 CPU par session de runner, mais c'est le pic d'un build représentatif de ton dépôt qui dicte la taille. La gateway est un Deployment sans état plus un petit PostgreSQL managé ; chaque réplique envoie au plus 256 requêtes simultanées vers le fournisseur. Les repères d'usage de la doc des coûts (environ 13 $ par développeur et par jour actif, 150 à 250 $ par mois) servent à caler les premiers plafonds, à affiner sur ton pilote ; le cadrage budgétaire complet est dans le coût réel des agents de code pour un CTO.
Le coût le plus sous-estimé est humain : une image de runner à maintenir et à épingler, une flotte à superviser, un secret à faire tourner, des versions client et serveur de la gateway à garder alignées, des sauvegardes PostgreSQL, et des arbitrages sur les plafonds. Et un coût moins visible encore : le délai. Un outil qui marchait en deux minutes exige désormais une demande d'accès et une règle de proxy. Si ce frottement grandit, tes équipes retourneront vers des outils non encadrés.
Comment piloter un déploiement en quatre semaines ?
- Semaine 0, décider : besoin d'exécution interne ou de gouvernance de l'inférence ? Vérifie ton plan, ta situation ZDR ou HIPAA, ton annuaire OIDC, ton fournisseur et ses quotas.
- Semaine 1, bac à sable : un runner sur un hôte avec
claude self-hosted-runner setupet une session de test ; ou une gateway en Compose avec PostgreSQL et un développeur pilote. - Semaine 2, durcir : capacité 1 et conteneur par session,
--confine-repo-settings enforce, sortie réseau fermée, métadonnées bloquées, délai de drain relevé, alertes ; côté gateway, plages réseau,fail_closed_on_error, rôles IAM minimaux et blocage du contournement. - Semaine 3, gouverner et mesurer : plafonds par groupe, message de blocage qui explique comment demander un relèvement, attribution AWS par développeur, export OTLP vers ton collecteur.
- Semaine 4, décider : redémarrage sous charge, rotation du secret et du certificat, panne PostgreSQL simulée, revue des coûts réels. Critère de sortie : tu sais chiffrer le coût d'exploitation par développeur et par mois, et tu as un plan de retour vers les environnements hébergés.
Avant ta prochaine réunion de gouvernance, réponds par écrit à deux questions : où le code doit-il rester, et qui paie, jusqu'à quel plafond ? Si la première appelle une réponse stricte, monte un runner pour une équipe. Si la seconde en appelle une, commence par des plafonds par développeur sur la gateway. Si aucune n'en appelle, ne déploie rien, et écris pourquoi. Le sujet n'est plus l'outil mais la manière dont l'équipe travaille avec lui. Prochain article de la série : quand économiser des tokens finit par coûter plus cher.

Écrit par
Flavien Métivier
Expert PHP/Symfony indépendant depuis 2014, ancien CTO de Kartable et d'Extrabat. Plus de 80 projets menés, de l'audit à la migration.
Mon parcours