Claude Platform Docs
Managed AgentsConfiguration d'entreprise

Identité et identifiants des agents

Faites signer par votre serveur Claude Managed Agents auto-hébergé un jeton de courte durée qui nomme chaque agent, conservez les identifiants des coffres-forts dans votre gestionnaire de secrets, et tenez les secrets à l’écart des sandboxes grâce à la passerelle de sortie.

Cette page montre comment permettre aux systèmes extérieurs à votre serveur de faire confiance à un agent, et où conserver les identifiants qu’utilisent vos agents :

  • Identité des agents : Permettez à un serveur MCP ou à une passerelle d’accorder à chaque agent ses propres accès. Le serveur signe un jeton de courte durée qui nomme l’agent.
  • Gestionnaire de secrets : Le serveur conserve les identifiants des coffres-forts dans AWS Secrets Manager, Google Cloud Secret Manager, HashiCorp Vault ou Azure Key Vault.
  • Identifiants de variables d’environnement : Permettez aux commandes d’un agent d’appeler un service alors que le sandbox ne contient qu’un espace réservé. La passerelle de sortie insère la valeur réelle dans les requêtes de l’agent.

Identité des agents

Votre serveur peut signer un « JSON Web Token » (jeton web JSON), ou JWT, de courte durée qui nomme un agent, et l’envoyer avec les appels MCP de cet agent. Le destinataire, un serveur MCP ou une « MCP gateway » (passerelle MCP), vérifie le jeton à l’aide des clés publiques que vous publiez, et peut ensuite accorder à chaque agent ses propres accès.

Configurer l’émetteur

  1. Choisissez l’URL de l’« issuer » (émetteur). Vous publiez vos clés publiques à cette URL à l’étape 3, et les destinataires les y récupèrent. Un hébergeur web statique convient. N’utilisez pas l’adresse de votre serveur, car le serveur ne sert pas les clés aux chemins que les destinataires récupèrent. Utilisez une URL https:// sans chemin ni barre oblique finale, sur un nom d’hôte que vous pouvez conserver.

  2. Créez la clé de signature. Exécutez ces commandes à la racine de l’archive extraite :

    mkdir -m 700 agent-identity
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out agent-identity/signing-key.pem
  3. Publiez les clés publiques. Cette commande les écrit dans issuer-files/.well-known/. Servez issuer-files à la racine du nom d’hôte de l’émetteur, avec le type de contenu application/json.

    CMA_AGENT_IDENTITY__ISSUER=https://agents.example.com \
    CMA_AGENT_IDENTITY__KEY_FILE=./agent-identity/signing-key.pem \
      ./cma-server export-issuer -out issuer-files
  4. Fournissez la clé au serveur.

    1. Si l’archive contient un répertoire compose, déplacez-y le répertoire de la clé : mv agent-identity compose/agent-identity.
    2. Dans docker-compose.yml, supprimez la ligne volumes: *server_mounts du service cma-server, et décommentez le bloc volumes: situé en dessous. Si vous avez modifié la liste x-server-mounts, apportez la même modification dans ce bloc, car le service cma-server ne lit plus la liste.
    3. Dans le répertoire qui contient agent-identity, exécutez sudo chown -R root:root agent-identity, sauf si vous utilisez Docker Desktop sur macOS ou Docker en mode rootless.
  5. Modifiez le fichier de paramètres. Ajoutez le nom d’hôte du destinataire dans mcp.allowed_hostnames, et ajoutez cette section :

    agent_identity:
      issuer: https://agents.example.com
      key_file: /run/cma-server/agent-identity/signing-key.pem
      direct:
        audiences:
          - audience: https://mcp-gateway.example.com
            urls:
              - https://mcp-gateway.example.com

    Chaque audience nomme un destinataire, sous la forme d’une URL https://. Ses urls sont les préfixes d’URL des serveurs MCP qui peuvent recevoir un jeton pour celle-ci.

  6. Redémarrez le serveur. Dans la stack Compose, exécutez docker compose up -d depuis le répertoire du fichier Compose au lieu d’un redémarrage.

Pour ne pas stocker la clé privée dans des fichiers, utilisez key_secret (votre gestionnaire de secrets) ou kms_key (AWS KMS ou Google Cloud KMS). La référence de configuration décrit ces deux paramètres.

Envoyer le jeton à un serveur MCP

Connecteur MCP décrit les champs de l’entrée de serveur MCP d’un agent. Ajoutez un champ auth à cette entrée :

mcp_servers:
  - type: url
    name: tickets
    url: https://mcp-gateway.example.com/tickets
    auth:
      type: agent_token
      audience: https://mcp-gateway.example.com

Pour chaque listage d’outils ou appel d’outil, votre serveur signe un nouveau jeton. Il envoie le jeton sous la forme Authorization: Bearer <token>, à la place d’un identifiant de coffre. Ni le modèle ni le worker ne le reçoivent.

Pour envoyer à la fois le jeton et un identifiant de coffre, remplacez le champ auth par un champ agent_token_header :

mcp_servers:
  - type: url
    name: tickets
    url: https://mcp-gateway.example.com/tickets
    agent_token_header:
      audience: https://mcp-gateway.example.com

L’identifiant de coffre est placé dans l’en-tête Authorization, comme pour une entrée ne comportant aucun de ces deux champs. Le jeton est placé dans un en-tête Agent-Identity-Token, sans préfixe Bearer.

Le SDK ne comporte pas les champs auth et agent_token_header. Dans le code SDK, ajoutez le champ à l’entrée de serveur MCP en tant que champ supplémentaire, ou envoyez la requête en JSON brut.

Ces pages indiquent comment envoyer des champs supplémentaires :

SDK Python · SDK TypeScript · SDK Go · SDK Java · SDK PHP · SDK Ruby

Certaines de ces pages ne présentent les champs supplémentaires qu’au niveau supérieur d’une requête, et non dans une entrée de liste. Dans ce cas, faites de mcp_servers lui-même le champ supplémentaire. Envoyez toute la liste de cette façon, avec auth ou agent_token_header dans son entrée.

Pour arrêter les jetons d’un agent, supprimez l’entrée de l’agent, ou archivez l’agent. Un jeton déjà envoyé reste valide jusqu’à son exp, soit 5 minutes au maximum par défaut.

Ce que vérifie le destinataire

Faites en sorte que le destinataire n’accepte une requête que si toutes ces conditions sont remplies :

  • La signature est vérifiée avec une clé de votre jeu de clés, <issuer>/.well-known/jwks.json. La bonne clé est celle dont l’identifiant correspond au kid de l’en-tête du jeton. Pour une clé RSA, l’algorithme est RS256.
  • iss est égal à l’URL de votre émetteur, et aud est égal à l’audience du destinataire.
  • exp est dans le futur, et iat n’est pas dans le futur.
  • typ dans l’en-tête du jeton vaut agent+jwt, et token_use vaut agent.

Appliquez ensuite ces règles :

  • Fondez les règles d’accès de chaque agent sur la claim agent_id, l’identifiant de l’agent dans l’API.
  • Acceptez un jti répété, car un même listage ou appel peut nécessiter plusieurs requêtes avec le même jeton.
  • Faites en sorte qu’une passerelle appelle chaque outil avec son propre identifiant, et ne transmette jamais le jeton.

Avec l’authentification unique, le jeton d’un appel d’outil nomme également l’appelant qui a créé la session, dans les claims actor_sub et actor_iss. actor_sub ne signifie pas que l’appelant a approuvé l’appel. C’est le modèle qui choisit chaque appel.

Ces jetons n’ont pas d’actor_sub :

  • Le jeton d’un listage d’outils
  • Le jeton d’un appel d’un sous-agent
  • Chaque jeton d’une session créée par la clé API du serveur

Si une règle dépend de l’appelant, refusez un appel d’outil qui n’a pas d’actor_sub.

Tester la passerelle MCP

La commande check-gateway envoie à une passerelle MCP des jetons valides et invalides. Fournissez à la commande son propre fichier de paramètres, ici check-gateway.yaml :

  1. Copiez dans le fichier uniquement les sections mcp et agent_identity des paramètres du serveur, ainsi que limits.mcp_call_timeout si le serveur le définit.
  2. Dans la copie, définissez key_file sur le chemin de la clé sur la machine où vous exécutez la commande, par exemple ./agent-identity/signing-key.pem. Si vous avez déplacé le répertoire dans compose, il s’agit de ./compose/agent-identity/signing-key.pem.

Pour -agent, indiquez l’identifiant d’un agent que la passerelle autorise. Si la clé appartient à root, utilisez sudo.

./cma-server check-gateway -config check-gateway.yaml -agent agent_011CYm1BLqPXpQRk5khsSXrs \
  -url https://mcp-gateway.example.com/tickets

La commande affiche une ligne pour chaque requête qu’elle envoie, avec la réponse de la passerelle. Une exécution réussie affiche ensuite une ligne qui commence par check-gateway: PASS, et s’arrête avec le code 0. Une exécution qui échoue indique ce qui n’a pas fonctionné, sur une ligne qui commence par check-gateway:, et s’arrête avec le code 1.

Gestionnaire de secrets

Par défaut, le serveur stocke les secrets des identifiants des coffres-forts dans sa base de données. Avec une section secret_store, le serveur écrit le secret de chaque nouvel identifiant de coffre dans votre « secret manager » (gestionnaire de secrets), sous un préfixe de nom que vous lui réservez. La base de données ne conserve qu’une référence.

Ajoutez le bloc correspondant à votre gestionnaire de secrets au fichier de paramètres :

secret_store:
  type: aws_secrets_manager
  region: us-east-1
  prefix: cma-server/prod/

Accorder l’accès

Attribuez au serveur une identité unique, et limitez-la au préfixe. Le répertoire iam/ de l’archive contient un fichier pour chaque gestionnaire de secrets :

  • AWS Secrets Manager : Remplacez les espaces réservés dans aws-secrets-manager-policy.json, et associez la politique à l’identité sous laquelle le serveur s’exécute.
  • Google Cloud Secret Manager : Exécutez les commandes figurant dans les commentaires de gcp-secret-manager-role.yaml.
  • Azure Key Vault : Un rôle Azure couvre un coffre de clés entier, et non un préfixe. Attribuez donc au déploiement son propre coffre de clés, qui utilise le contrôle d’accès en fonction du rôle Azure. Remplacez SUBSCRIPTION_ID dans azure-key-vault-role.json, et créez-en un rôle personnalisé. Attribuez ce rôle, sur le coffre de clés, à l’identité sous laquelle le serveur s’exécute.
  • HashiCorp Vault : Remplacez les espaces réservés dans hashicorp-vault-policy.hcl, et associez la politique à l’identité sous laquelle le serveur s’exécute.

Auprès d’AWS et de Google Cloud, le serveur s’authentifie de la même manière que pour l’inférence. Auprès d’Azure Key Vault, il s’authentifie avec Microsoft Entra ID, comme pour Microsoft Foundry.

Vérifier la configuration

Exécutez validate-store avant le premier démarrage et après toute modification de politique. Il crée, lit et supprime un secret de test sous le préfixe, sans démarrer le serveur. Exécutez la commande là où le serveur s’exécute, avec l’environnement du serveur :

  • Docker Compose : Exécutez-la dans le conteneur du serveur. Sur Arm, remplacez linux_amd64 par linux_arm64 dans cette commande :

    docker compose exec cma-server /opt/cma-server/bin/linux_amd64/cma-server validate-store -config /etc/cma-server/config.yaml
  • Sur un hôte :

    ./cma-server validate-store -config /etc/cma-server/config.yaml
  • Kubernetes : Exécutez la même commande en tant que Job sous le compte de service du serveur.

Une exécution réussie se termine par une ligne indiquant pass, et s’arrête avec le code 0.

Avec Azure Key Vault, exécutez cette vérification sur votre coffre de clés avant de vous y fier.

Limites du gestionnaire de secrets

  • Choisissez les paramètres une fois pour toutes. Après l’une de ces modifications, le serveur ne trouve plus les secrets qu’il a écrits avant la modification :

    • Vous supprimez la section secret_store.
    • Vous modifiez type, prefix, region, project, vault_url, mount ou namespace. Les deux derniers sont des paramètres facultatifs de HashiCorp Vault.
    • Vous faites pointer address vers un autre Vault.

    Le serveur ne retrouve ces secrets que lorsque vous restaurez les anciennes valeurs.

  • Une seule identité lit l’ensemble du préfixe. Si deux groupes ne doivent pas pouvoir accéder aux identifiants l’un de l’autre, attribuez à chaque groupe son propre déploiement. Chaque déploiement nécessite son propre préfixe ou coffre de clés et sa propre identité.

Identifiants de variables d’environnement

Avec un identifiant de variable d’environnement, les commandes d’un agent peuvent appeler un service alors que le sandbox ne contient qu’un espace réservé pour le secret. L’« egress gateway » (passerelle de sortie) insère la valeur réelle dans les requêtes vers les hôtes que l’identifiant répertorie.

La passerelle, cma-egress, est un proxy inclus dans l’archive de la version, qui se place entre vos sandboxes et Internet. Elle est désactivée par défaut, et votre serveur n’accepte ces identifiants que si la passerelle est activée.

Lorsque la passerelle est activée, deux limites s’appliquent à vos sandboxes :

  • Les sandboxes n’accèdent à Internet que par la passerelle.
  • La passerelle ne se connecte qu’aux hôtes que vous indiquez dans le paramètre egress.allowed_hostnames du serveur.

Indiquez des noms d’hôte publics exacts, sans caractères génériques. Incluez chaque hôte depuis lequel les commandes de vos agents téléchargent.

Si vous avez créé votre propre image de sandbox, démarrez le worker via cma-with-egress, comme indiqué dans Créer votre propre image de sandbox.

Activer la passerelle dans la stack Compose

Depuis le répertoire qui contient docker-compose.yml, ajoutez deux lignes à .env. La première répertorie les hôtes auxquels la passerelle se connecte, séparés par des virgules. La seconde charge le fichier Compose de la passerelle. Démarrez ensuite la stack :

echo 'CMA_EGRESS__ALLOWED_HOSTNAMES=api.github.com' >> .env
echo 'COMPOSE_FILE=docker-compose.yml:docker-compose.egress.yml' >> .env
docker compose up --build -d

Si vous utilisez également un autre fichier Compose, ajoutez-le à la ligne COMPOSE_FILE. Une variable COMPOSE_FILE dans votre shell remplace celle de .env ; supprimez donc la variable du shell.

Le fichier de la passerelle définit les autres paramètres egress du serveur ; n’ajoutez donc pas de section egress à compose.config.yaml.

Activer la passerelle sur Kubernetes

Ces étapes partent du déploiement décrit dans Déployer sur Kubernetes. Elles utilisent les variables REGISTRY, TAG et PLATFORM de cette page ainsi que ses deux fichiers de valeurs. Exécutez les commandes depuis le répertoire racine de l’archive, avec OpenSSL 3.0 ou une version ultérieure. Le chart des sandboxes ne propose pas la passerelle sur Azure Kubernetes Service (AKS).

La mise à niveau du chart du serveur dans ces étapes ajoute également une politique réseau sur les pods des serveurs. Vérifiez deux des ports qu’elle couvre avant de commencer :

  • Port 9464, le port des métriques : La politique le ferme. Si Prometheus collecte les métriques sur ce port, définissez server.telemetry.prometheus.scraper.namespace dans cma-server-values.yaml sur l’espace de noms dans lequel Prometheus s’exécute.
  • Port 8400, le port de l’API : La politique autorise toutes les sources. Si l’une de vos propres politiques limite les sources pouvant atteindre le port 8400, cette limite cesse de fonctionner. Les politiques réseau se cumulent ; une connexion passe donc si l’une quelconque des politiques l’autorise.
  1. Construire et pousser l’image de la passerelle

    docker buildx build --platform "$PLATFORM" -f kubernetes/egress/Dockerfile -t "$REGISTRY/cma-egress:$TAG" --push .
  2. Créer l’autorité de certification et la clé de la passerelle

    (umask 077 && openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -days 825 \
      -subj "/CN=cma-server egress gateway" \
      -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
      -addext "keyUsage=critical,keyCertSign,cRLSign" \
      -keyout egress-ca.key -out egress-ca.crt)
    kubectl -n cma create secret tls cma-egress-ca --cert=egress-ca.crt --key=egress-ca.key
    kubectl -n cma-server create configmap cma-egress-ca --from-file=ca.crt=egress-ca.crt
    GATEWAY_KEY=$(openssl rand -hex 32)
    printf %s "$GATEWAY_KEY" | kubectl -n cma create secret generic cma-egress-gateway-key --from-file=gateway-key=/dev/stdin
    printf %s "$GATEWAY_KEY" | kubectl -n cma-server create secret generic cma-egress-gateway-key --from-file=gateway-key=/dev/stdin
    unset GATEWAY_KEY

    Supprimez ensuite egress-ca.key, la clé privée de l’autorité de certification. Quiconque la détient peut usurper l’identité de n’importe quel site web auprès de vos sandboxes. Le certificat est valide pendant 825 jours. Consultez Renouveler le certificat.

  3. Supprimer les sandboxes des sessions précédentes

    Si l’environnement n’a exécuté aucune session, ignorez cette étape. Un sandbox antérieur à la modification ne peut plus démarrer son worker ensuite. Ces commandes suppriment également l’espace de travail de chaque sandbox :

    kubectl -n cma scale deployment cma-dispatcher --replicas=0
    kubectl -n cma delete sandboxwarmpool cma-sandbox
    kubectl -n cma delete sandboxclaims --all

    Sur Google Kubernetes Engine (GKE), exécutez également cette commande :

    kubectl -n cma delete sandboxes --all

    Répétez kubectl -n cma get sandboxes,pods,pvc jusqu’à ce qu’il ne trouve plus rien. Le helm upgrade de l’étape « Activer le côté sandboxes » redémarre le dispatcher.

  4. Activer le côté serveur

    Choisissez pour la passerelle une adresse IPv4 libre dans la plage de Services du cluster. La colonne CLUSTER-IP de kubectl get svc -A affiche des adresses de cette plage. Ajoutez ceci à cma-server-values.yaml. Si le fichier contient déjà un bloc server, fusionnez-y ces lignes :

    egressGateway:
      enabled: true
      proxyAddress: 34.118.224.53:3128   # the address that you chose, and port 3128
    server:
      config:
        egress:
          allowed_hostnames:
            - api.github.com

    Exécutez ensuite la mise à niveau :

    helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
  5. Activer le côté sandboxes

    Exécutez kubectl -n cma-server get svc pour lister les deux Services du serveur. Dans une nouvelle installation, ils sont nommés cma-server et cma-server-egress.

    Dans cma-values.yaml, remplacez egress.mode par gateway, et ajoutez un bloc gateway sous egress. Donnez au bloc les deux noms que la commande a listés :

    egress:
      mode: gateway
      gateway:
        serviceIP: 34.118.224.53   # the address that you chose
        serverService: cma-server
        serverEgressService: cma-server-egress
        apiServerCIDRs:
          - 203.0.113.10/32        # the cluster's API endpoint

    Conservez les autres valeurs egress du fichier. Pour afficher les adresses et le port du point de terminaison de l’API, exécutez kubectl get endpoints kubernetes -n default. Si le port n’est pas 443, définissez également egress.gateway.apiServerPort.

    helm upgrade cma kubernetes/chart --namespace cma -f cma-values.yaml --wait

    Si la mise à niveau s’arrête sur un conflit concernant .spec.replicas, exécutez kubectl -n cma scale deployment cma-dispatcher --replicas=1, puis relancez la mise à niveau.

Ajouter un identifiant

Créez un identifiant de variable d’environnement comme indiqué dans Ajouter un identifiant. Les guides du service hébergé indiquent que ces identifiants ne sont pas pris en charge avec les sandboxes auto-hébergés. Cela décrit le service hébergé, et non votre serveur.

Votre serveur ajoute ses propres règles. Il refuse une requête qui en enfreint une avec une erreur 400 qui nomme le champ. Voici deux de ces règles :

  • networking doit être de type limited, et chaque hôte de allowed_hosts doit figurer dans la liste egress.allowed_hostnames du serveur.
  • injection_location doit valoir {"header": true} en JSON, et ne peut pas être omis.

Après avoir ajouté un hôte à la liste du serveur, appliquez la modification. Sur Docker Compose, exécutez docker compose up -d. Sur Kubernetes, exécutez la commande helm upgrade du serveur et kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server.

Vérifier la passerelle de sortie

Créez une session avec le coffre de l’identifiant, et demandez à l’agent d’exécuter deux commandes. Cet exemple concerne un identifiant nommé GITHUB_TOKEN qui répertorie api.github.com :

printenv GITHUB_TOKEN
curl -sS -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/user

La première commande affiche un espace réservé qui commence par cma_ph_. La seconde affiche le profil du compte GitHub du jeton, car la passerelle a remplacé l’espace réservé par le jeton. La passerelle refuse une requête vers un hôte qui ne figure pas dans votre liste avec une erreur 403.

Sur Kubernetes, si chaque requête reçoit une erreur 503, le réseau de votre cluster réécrit probablement les adresses des pods, comme le fait l’option --masquerade-all de kube-proxy. La passerelle distingue les sandboxes par les adresses de leurs pods ; ces adresses doivent donc lui parvenir inchangées.

Renouveler le certificat

Sur Kubernetes, renouvelez le certificat lorsqu’aucune session n’est en cours d’exécution. Répétez l’intégralité de l’étape « Créer l’autorité de certification et la clé de la passerelle » de la section Activer la passerelle sur Kubernetes. Elle recrée l’autorité de certification et la clé de la passerelle ; vous n’avez donc pas besoin du fichier egress-ca.key que vous avez supprimé. Apportez une seule modification : ajoutez --dry-run=client -o yaml | kubectl apply -f - à la fin de chacune des quatre lignes qui exécutent kubectl create. Une ligne qui se termine par --from-file=gateway-key=/dev/stdin, par exemple, se termine alors par --from-file=gateway-key=/dev/stdin --dry-run=client -o yaml | kubectl apply -f -.

Redémarrez ensuite les serveurs et la passerelle :

kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server
kubectl -n cma rollout restart deployment/cma-egress

Limites de la passerelle de sortie

  • En-têtes : La passerelle n’insère une valeur que dans un en-tête de requête, jamais dans une URL ni dans un corps. Par défaut, le seul en-tête est Authorization. Pour en autoriser d’autres, indiquez-les avec Authorization dans egress.swap_header_names, ou dans CMA_EGRESS__SWAP_HEADER_NAMES dans .env pour la stack Compose.
  • Programmes qui ignorent les variables de proxy : Les sandboxes trouvent la passerelle via HTTPS_PROXY et les variables associées. Les outils Java tels que Maven et Gradle ne lisent pas ces variables ; ils n’atteignent donc rien.

Cette page vous a-t-elle été utile ?