S'authentifier avec des coffres-forts
Enregistrez des identifiants propres à chaque utilisateur lors de la création de sessions.
Les coffres-forts (vaults) et les identifiants (credentials) sont des primitives d'authentification qui vous permettent d'enregistrer une seule fois des identifiants pour des services tiers et de les référencer par ID lors de la création d'une session. Cela signifie que vous n'avez pas besoin d'exécuter votre propre magasin de secrets, de transmettre des jetons à chaque appel, ou de perdre la trace de l'utilisateur final pour le compte duquel un agent a agi.
La référence au coffre-fort est un paramètre par session, vous pouvez donc gérer votre produit à la granularité de la ressource agent et vos utilisateurs à la granularité de la ressource session.
Créer un coffre-fort
Un coffre-fort est l'ensemble des credentials associés à un utilisateur final. Attribuez-lui un display_name et, éventuellement, étiquetez-le avec des metadata afin de pouvoir le rattacher à vos propres enregistrements d'utilisateurs.
vault = client.beta.vaults.create(
display_name="Alice",
metadata={"external_user_id": "usr_abc123"},
)
print(vault.id) # "vlt_01ABC..."La réponse est l'enregistrement complet du coffre-fort :
{
"type": "vault",
"id": "vlt_01ABC...",
"display_name": "Alice",
"metadata": { "external_user_id": "usr_abc123" },
"created_at": "2026-03-18T10:00:00Z",
"updated_at": "2026-03-18T10:00:00Z",
"archived_at": null
}Ajouter un identifiant
Deux catégories d'identifiants sont prises en charge :
- Identifiants MCP (
mcp_oauth,static_bearer) : chaque identifiant est indexé par unmcp_server_url. Lorsque l'agent se connecte à un serveur à cette URL pendant l'exécution de la session, le jeton est injecté automatiquement. - Variables d'environnement (
environment_variable) : chaque identifiant est indexé par unsecret_name(le nom de la variable d'environnement) et stocké dans le bac à sable sous la forme d'un placeholder opaque. Lorsque l'agent lance une requête sortante, le placeholder opaque est remplacé par le véritable secret en sortie (egress). L'agent ne voit jamais la valeur du secret. Utilisez cette option pour tout service qui s'authentifie via une variable d'environnement, comme les CLI, les SDK ou les appels API directs.
Les valeurs réelles des identifiants que vous fournissez (token, access_token, refresh_token, client_secret, secret_value) sont traitées comme des champs sensibles en écriture seule et ne sont jamais renvoyées dans les réponses de l'API.
Pour obtenir le même comportement avec un bac à sable auto-hébergé, vous pouvez exécuter votre propre proxy qui remplace les valeurs de placeholder par les véritables secrets en sortie.
Utilisez mcp_oauth lorsque le serveur MCP utilise OAuth 2.0. Si vous fournissez un bloc refresh, Anthropic rafraîchit le jeton d'accès en votre nom lorsqu'il expire.
Le champ refresh.token_endpoint_auth.type indique comment authentifier l'appel de rafraîchissement :
none: client publicclient_secret_basic: authentification HTTP Basic avec le secret clientclient_secret_post: secret client dans le corps POST
credential = client.beta.vaults.credentials.create(
vault_id=vault.id,
display_name="Alice's Slack",
auth={
"type": "mcp_oauth",
"mcp_server_url": "https://mcp.slack.com/mcp",
"access_token": "xoxp-...",
"expires_at": "2099-12-31T23:59:59Z",
"refresh": {
"token_endpoint": "https://slack.com/api/oauth.v2.user.access",
"client_id": "1234567890.0987654321",
"scope": "channels:read chat:write",
"refresh_token": "xoxe-1-...",
"token_endpoint_auth": {
"type": "client_secret_post",
"client_secret": "abc123...",
},
},
},
)Définissez refresh.token_endpoint sur le point de terminaison de jeton du flux OAuth qui a émis le jeton de rafraîchissement, car Anthropic envoie chaque requête de rafraîchissement à cette URL et ce champ ne peut pas être modifié après la création de l'identifiant.
Utilisez static_bearer lorsque le serveur MCP accepte un jeton bearer fixe (clé API, jeton d'accès personnel ou similaire). Aucun flux de rafraîchissement n'est nécessaire.
bearer_credential = client.beta.vaults.credentials.create(
vault_id=vault.id,
display_name="Linear API key",
auth={
"type": "static_bearer",
"mcp_server_url": "https://mcp.linear.app/mcp",
"token": "lin_api_your_linear_key",
},
)Utilisez environment_variable pour vous authentifier auprès de services externes via une variable d'environnement, comme les CLI, les SDK ou les appels API directs. Les identifiants de variables d'environnement fonctionnent pour les clients qui envoient la valeur du secret telle quelle dans une requête sortante, alors vérifiez les critères d'éligibilité du client dans cet onglet avant d'en configurer un.
Le tableau allowed_hosts dans networking contrôle les hôtes sortants pour lesquels le secret peut être substitué. Utilisez "type": "limited" avec une liste spécifique, ou "type": "unrestricted" si l'appelant accède à des domaines que vous ne pouvez pas énumérer à l'avance.
Limiter les domaines est fortement recommandé à des fins de sécurité, et empêche votre clé d'être jamais partagée avec des hôtes non autorisés.
Le champ facultatif injection_location délimite l'endroit où le secret est substitué ; la sémantique complète est décrite après l'exemple.
env_credential = client.beta.vaults.credentials.create(
vault_id=vault.id,
display_name="Notion API key for sandbox",
auth={
"type": "environment_variable",
"secret_name": "NOTION_API_KEY",
"secret_value": "ntn_your-secret-here",
"networking": {
"type": "limited",
"allowed_hosts": ["api.notion.com"],
},
"injection_location": {"header": True},
},
)
if env_credential.auth.type == "environment_variable":
location = env_credential.auth.injection_location
print(
f"header: {location.header}, body: {location.body}"
) # header: True, body: FalseLes charges utiles des requêtes sont souvent assemblées à partir du contenu sur lequel l'agent travaille ; le corps de la requête constitue donc la surface d'exposition la plus large. La plupart des services lisent une clé API depuis un en-tête de requête ; activer uniquement header est donc la configuration la plus restreinte. Elle limite la substitution aux valeurs des en-têtes de requête pour cet identifiant.
Le champ injection_location de l'identifiant contrôle les parties d'une requête sortante dans lesquelles le secret est substitué. Il s'agit d'un objet facultatif, au même niveau que networking, avec deux champs booléens : header (en-têtes de requête) et body (corps de la requête). injection_location est indépendant de allowed_hosts dans networking : allowed_hosts délimite les hôtes pour lesquels le secret est substitué, et injection_location délimite les parties de la requête dans lesquelles il est substitué.
injection_location se comporte différemment lors de la création et lors de la mise à jour :
| Opération | Comportement de injection_location |
|---|---|
| Créer un identifiant | Si vous fournissez l'objet, tout champ que vous omettez à l'intérieur prend par défaut la valeur false : {"header": true} crée un identifiant uniquement pour l'en-tête. Omettez entièrement l'objet et les deux emplacements sont activés. |
| Mettre à jour un identifiant | Les champs fusionnent individuellement : {"body": false} désactive la substitution dans le corps et laisse header inchangé. |
Un identifiant doit avoir au moins un emplacement activé ; une création ou une mise à jour qui désactiverait les deux emplacements renvoie donc une erreur 400. Transmettre un null explicite pour l'objet injection_location ou pour l'un de ses champs renvoie également une erreur 400 (« omit the field instead »). La réponse renvoie toujours les deux champs avec leurs valeurs résolues.
Un placeholder situé dans un emplacement désactivé n'est ni substitué ni supprimé. La requête est envoyée au tiers avec la chaîne de placeholder opaque littérale à cet emplacement. Si une requête parvient au tiers en contenant la chaîne de placeholder littérale, soit cet emplacement est désactivé pour l'identifiant, soit l'hôte de destination n'est pas couvert par les allowed_hosts dans le networking de l'identifiant.
La substitution a lieu en sortie, et non à l'intérieur du bac à sable. Tout ce qui traite l'identifiant localement voit le placeholder opaque, et non la valeur réelle : les clients qui valident le format de l'identifiant au démarrage peuvent le rejeter, et les clients qui calculent une signature de requête à partir du secret (par exemple, AWS SigV4) produisent une signature invalide. Les identifiants de variables d'environnement fonctionnent pour les clients qui envoient la valeur du secret telle quelle dans une requête sortante, à un emplacement activé par le champ injection_location de l'identifiant.
La substitution est uniquement sortante. Si un client utilise le secret stocké pour récupérer un jeton de session (par exemple, une autorisation OAuth client-credentials), le jeton renvoyé arrive dans le bac à sable non masqué. Pour les flux basés sur l'échange, effectuez l'échange vous-même et stockez plutôt le jeton résultant dans le coffre-fort.
Les identifiants sont stockés tels que fournis et ne sont pas validés avant l'exécution de la session. Un identifiant invalide se manifeste comme une erreur d'authentification ou une erreur en aval pendant la session, qui est émise mais n'empêche pas la session de continuer.
Contraintes :
- Clé unique par coffre-fort.
mcp_server_url(identifiants MCP) etsecret_name(identifiants de variables d'environnement) doivent être uniques parmi les identifiants actifs d'un coffre-fort. La création d'un doublon renvoie une erreur 409. - Les clés sont immuables. Pour modifier
mcp_server_urlousecret_name, archivez l'identifiant et créez-en un nouveau. - Maximum de 20 identifiants par coffre-fort.
Référencer le coffre-fort lors de la création de la session
Transmettez vault_ids lors de la création d'une session :
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
vault_ids=[vault.id],
title="Alice's Slack digest",
)Comportement à l'exécution :
- Lorsqu'aucun identifiant MCP ne correspond par
mcp_server_url, la connexion est tentée sans authentification et échouera si le serveur exige une authentification. - Lorsque plusieurs coffres-forts contiennent un identifiant correspondant, le premier coffre-fort avec une correspondance l'emporte.
- Dans les sessions multiagents, les identifiants du coffre-fort s'appliquent à chaque thread. Un agent dont la propre définition déclare le serveur MCP correspondant s'authentifie avec ces identifiants. Consultez Connecter des agents à des serveurs MCP.
Faire tourner un identifiant
Les valeurs secrètes, display_name et (pour les identifiants de variables d'environnement) injection_location peuvent être mis à jour. Les mises à jour de injection_location sont fusionnées champ par champ, comme décrit dans l'onglet Variable d'environnement de Ajouter un identifiant. Pour une session en cours d'exécution, une mise à jour de injection_location se propage de la même manière qu'une rotation de secret : les identifiants de la session sont re-résolus sans redémarrage, comme décrit dans Cycle de vie des identifiants, et les emplacements mis à jour s'appliquent aux requêtes sortantes ultérieures de la session. Les champs structurels (mcp_server_url, secret_name, token_endpoint, client_id) sont verrouillés après la création. Pour les modifier, archivez l'identifiant et créez-en un nouveau.
client.beta.vaults.credentials.update(
credential.id,
vault_id=vault.id,
auth={
"type": "mcp_oauth",
"access_token": "xoxp-new-...",
"expires_at": "2099-12-31T23:59:59Z",
"refresh": {"refresh_token": "xoxe-1-new-..."},
},
)Cycle de vie des identifiants
Les identifiants sont re-résolus périodiquement, à la fois pendant une session et pendant le cycle de vie du coffre-fort. Cela garantit que la rotation, l'archivage ou la suppression d'un identifiant se propage aux sessions en cours sans redémarrage.
Pour être notifié si un identifiant est archivé, supprimé ou échoue à se rafraîchir, vous pouvez vous abonner aux webhooks de coffre-fort et d'identifiant associés à ces changements de cycle de vie.
| Événement | Déclencheur |
|---|---|
vault.archived | Coffre-fort archivé. Un événement vault_credential.archived est également émis pour chaque identifiant sous-jacent. |
vault.deleted | Coffre-fort supprimé. Un événement vault_credential.deleted est également émis pour chaque identifiant sous-jacent. |
vault_credential.archived | Identifiant archivé, soit directement, soit à la suite de l'archivage du coffre-fort. |
vault_credential.deleted | Identifiant supprimé, soit directement, soit à la suite de la suppression du coffre-fort. |
vault_credential.refresh_failed | Un identifiant mcp_oauth ne peut pas être rafraîchi (jeton de rafraîchissement invalide, ou erreur irrécupérable du serveur OAuth). |
Pour les identifiants mcp_oauth, la re-résolution rafraîchit également le jeton d'accès s'il a expiré. Si le rafraîchissement échoue, un événement vault_credential.refresh_failed est émis.
Diagnostiquer un échec de rafraîchissement OAuth
Pour diagnostiquer la cause d'un échec de rafraîchissement, appelez POST /v1/vaults/{vault_id}/credentials/{credential_id}/mcp_oauth_validate (ou client.beta.vaults.credentials.mcp_oauth_validate(...) dans le SDK). Vous pouvez ainsi décider comment traiter l'échec, car l'action appropriée dépend du type d'erreur.
Le champ status de premier niveau vous indique la marche à suivre :
valid: le jeton fonctionne ; aucune action nécessaire.invalid: l'autorisation a disparu ou le serveur OAuth a rejeté le rafraîchissement avec une erreur 4xx. Invitez l'utilisateur final à se réautoriser.unknown: une erreur transitoire (5xx, 429, ou échec réseau). Attendez et réessayez.
validation = client.beta.vaults.credentials.mcp_oauth_validate(
credential.id,
vault_id=vault.id,
)
print(validation.status) # "valid", "invalid", or "unknown"La réponse est un objet vault_credential_validation. mcp_probe inclut l'étape de handshake MCP ayant échoué ; refresh inclut le résultat du rafraîchissement tenté.
{
"type": "vault_credential_validation",
"credential_id": "vcrd_01ABC...",
"vault_id": "vlt_01XYZ...",
"validated_at": "2026-04-29T17:12:00Z",
"has_refresh_token": false,
"status": "invalid",
"mcp_probe": {
"method": "initialize",
"http_response": {
"status_code": 401,
"content_type": "application/json",
"body": "{\"error\":\"invalid_token\"}",
"body_truncated": false
}
},
"refresh": {
"status": "no_refresh_token",
"http_response": null
}
}Autres opérations
- Lister les coffres-forts ou les identifiants : Paginé, du plus récent au plus ancien. Les enregistrements archivés sont exclus par défaut (passez
include_archived=truepour les inclure). - Archiver un coffre-fort :
POST /v1/vaults/{id}/archive. Se répercute sur tous les identifiants. Les secrets sont purgés ; les enregistrements sont conservés à des fins d'audit. Les futures sessions référençant ce coffre-fort échouent ; les sessions en cours continuent. - Archiver un identifiant :
POST /v1/vaults/{id}/credentials/{cred_id}/archive. Purge la charge utile du secret ; la clé de l'identifiant (mcp_server_urlousecret_name) reste visible et est libérée pour un identifiant de remplacement. - Supprimer un coffre-fort ou un identifiant : Suppression définitive. L'enregistrement n'est pas conservé. Utilisez l'archivage si vous avez besoin d'une piste d'audit.
Was this page helpful?