Utiliser WIF avec SPIFFE
Authentifiez les charges de travail SPIFFE auprès de l'API Claude à l'aide de JWT-SVID provenant de SPIRE ou de tout autre émetteur conforme à SPIFFE.
SPIFFE est le standard CNCF pour l'émission d'identités destinées aux charges de travail. SPIRE en est l'implémentation de référence open source, et plusieurs produits commerciaux émettent également des identités conformes à SPIFFE. Anthropic se fédère avec toute implémentation SPIFFE qui émet des JWT-SVID compatibles OIDC. Pour une liste à jour des implémentations, consultez Commercial software that implements SPIFFE sur le site du projet SPIFFE.
La fédération fonctionne soit via un document de découverte OIDC à une URL HTTPS publique (mode discovery, soumis aux contraintes d'URL), soit en enregistrant directement le JWKS (mode inline).
La spécification JWT-SVID définit sub comme l'identifiant SPIFFE de la charge de travail, et la SPIFFE Workload API exige que l'appelant fournisse aud au moment de la récupération, de sorte que ces claims sont identiques d'une implémentation à l'autre. Anthropic exige en outre iss et iat, qu'aucune des deux la spécification JWT-SVID n'impose ; configurez donc votre implémentation pour renseigner les deux (dans SPIRE, iss correspond au paramètre serveur jwt_issuer et iat est défini automatiquement). Une fois ces éléments en place, les sections Configurer Anthropic, Acquérir et utiliser le jeton et Délimiter votre règle de ce guide s'appliquent à toute implémentation SPIFFE.
SPIFFE attribue à chaque charge de travail un URI d'identité stable de la forme spiffe://<trust-domain>/<path>, et SPIRE émet cette identité sous forme de JWT-SVID à la demande via la Workload API. Un JWT-SVID est un JWT signé ordinaire dont le claim sub est l'identifiant SPIFFE de la charge de travail et dont le claim aud est fourni par la charge de travail au moment de la récupération.
Le pont entre un « trust domain » (domaine de confiance) SPIRE et l'OIDC standard est le SPIRE OIDC Discovery Provider, un utilitaire autonome qui publie /.well-known/openid-configuration et un point de terminaison JWKS pour les clés de signature JWT du domaine de confiance. Lorsque le fournisseur de découverte est en cours d'exécution, un JWT-SVID se valide comme n'importe quel autre jeton OIDC : enregistrez l'URL de découverte en tant qu'émetteur de fédération, rédigez une règle de fédération qui correspond à l'identifiant SPIFFE de la charge de travail, et faites en sorte que la charge de travail présente son JWT-SVID au point de terminaison d'échange de jetons d'Anthropic.
Les exemples de cette page utilisent SPIRE et s'appliquent partout où SPIRE Agent s'exécute : pods Kubernetes, machines virtuelles et hôtes bare-metal.
Prérequis
- Une familiarité avec les concepts WIF : comptes de service, émetteurs de fédération et règles de fédération.
- Un déploiement SPIFFE avec des identités de charge de travail émises (les exemples de cette page utilisent SPIRE Server et Agent), et des entrées d'enregistrement pour les charges de travail qui doivent appeler l'API Claude.
- Un point de terminaison de découverte OIDC pour le domaine de confiance (dans SPIRE, l'OIDC Discovery Provider) fonctionnant avec un point de terminaison HTTPS accessible publiquement, ou le JWKS exporté pour un enregistrement
inline. - Votre émetteur SPIFFE configuré pour définir le claim
issdes JWT-SVID sur la valeur que vous enregistrerez commeissuer_urlde l'émetteur de fédération. En modediscovery, il s'agit de l'URL publique du point de terminaison de découverte (dans SPIRE, le paramètre serveurjwt_issuer). - Des JWT-SVID disponibles pour vos charges de travail. WIF accepte uniquement les JWT-SVID, pas les X.509-SVID.
- L'autorisation de créer des comptes de service, des émetteurs de fédération et des règles de fédération dans la Claude Console pour votre organisation Anthropic.
La valeur d'audience à demander lors de la récupération d'un JWT-SVID est toujours https://api.anthropic.com. Utilisez cette valeur dans le jwt_audience de spiffe-helper, dans l'appel FetchJWTSVID de la Workload API et dans le matcher audience de la règle de fédération.
Configurer SPIRE
Les instructions de cette section sont spécifiques à SPIRE. Si vous utilisez un autre émetteur SPIFFE, configurez son point de terminaison de découverte OIDC et la récupération des JWT-SVID conformément à sa propre documentation, puis poursuivez à la section Configurer Anthropic.
Si vous exécutez déjà SPIRE avec l'OIDC Discovery Provider, la fédération avec Anthropic nécessite trois éléments côté SPIRE : un jwt_issuer qui correspond à l'URL de découverte, une entrée d'enregistrement pour la charge de travail qui appellera l'API Claude, et un moyen pour cette charge de travail de récupérer un JWT-SVID avec l'audience Anthropic. Les sous-sections suivantes détaillent chacun de ces éléments. Les extraits de code de configuration ne montrent que les paramètres pertinents pour la fédération avec Anthropic, et non des configurations de déploiement SPIRE complètes.
Vérifier l'émetteur JWT
Anthropic valide un JWT-SVID en comparant son claim iss à un émetteur de fédération enregistré et en récupérant le JWKS à partir du document de découverte de cet émetteur. Deux paramètres SPIRE doivent s'accorder sur la même URL : le jwt_issuer de SPIRE Server (qui devient le claim iss de chaque JWT-SVID émis) et la liste domains de l'OIDC Discovery Provider (qui détermine l'hôte depuis lequel le document de découverte et le JWKS sont servis). Cette URL partagée est celle que vous enregistrez auprès d'Anthropic.
Le domaine de confiance et l'URL de l'émetteur sont indépendants. Le domaine de confiance (spiffe://prod.example.com) délimite le claim sub. L'URL de l'émetteur (https://oidc-discovery.prod.example.com) est l'endroit où Anthropic récupère les clés de signature. Ils n'ont pas besoin de partager un nom d'hôte.
Vérifiez que jwt_issuer est défini dans la configuration de SPIRE Server et pointe vers l'URL publique du fournisseur de découverte. L'exemple suivant montre également une durée de vie par défaut des JWT-SVID. La valeur par défaut intégrée de SPIRE est de 5 minutes, ce qui est suffisamment court pour qu'une rotation continue soit nécessaire (voir Exécuter spiffe-helper). Le point de terminaison d'échange de jetons d'Anthropic rejette tout jeton d'identité dont la durée de vie dépasse le maximum configuré pour l'émetteur de fédération, qui est de 1 heure par défaut (voir Règles de validation). Cette vérification s'applique à toute implémentation SPIFFE, pas seulement à SPIRE ; maintenez donc default_jwt_svid_ttl (ou toute surcharge par entrée) à une valeur inférieure ou égale à ce maximum.
server {
trust_domain = "prod.example.com"
jwt_issuer = "https://oidc-discovery.prod.example.com"
default_jwt_svid_ttl = "5m"
# ...
}Dans la configuration de l'OIDC Discovery Provider, le même nom d'hôte doit apparaître sous domains, et le fournisseur doit pouvoir atteindre le socket API de SPIRE Server. Le fournisseur sert le document de découverte et le JWKS via HTTPS. Terminez TLS avec sa prise en charge ACME intégrée, ou placez-le derrière un équilibreur de charge qui s'en charge.
domains = ["oidc-discovery.prod.example.com"]
server_api {
address = "unix:///run/spire/sockets/private/api.sock"
}
acme {
email = "platform@example.com"
tos_accepted = true
}Enregistrer la charge de travail
Chaque charge de travail qui appelle l'API Claude a besoin d'une entrée d'enregistrement SPIRE qui associe ses sélecteurs d'exécution à un identifiant SPIFFE. Si la charge de travail est déjà enregistrée, notez son identifiant SPIFFE, que vous utiliserez dans le subject_prefix de la règle de fédération. Sinon, enregistrez-la. Pour un pod Kubernetes, les sélecteurs sont généralement le namespace et le compte de service Kubernetes :
# Remplacez NODE_UID par l'UID du nœud :
# kubectl get node <node-name> -o jsonpath='{.metadata.uid}'
spire-server entry create \
-spiffeID spiffe://prod.example.com/ns/inference/sa/worker \
-parentID spiffe://prod.example.com/spire/agent/k8s_psat/prod-cluster/NODE_UID \
-selector k8s:ns:inference \
-selector k8s:sa:workerLes charges de travail hors Kubernetes utilisent des sélecteurs au niveau de l'hôte tels que unix:uid:1000 (unix:path est également disponible mais nécessite discover_workload_path = true dans la configuration de l'attestateur de charge de travail unix de l'agent). Les clusters exécutant spire-controller-manager peuvent déclarer des entrées avec la ressource personnalisée ClusterSPIFFEID au lieu d'appeler directement spire-server entry create.
Exécuter spiffe-helper
spiffe-helper est un utilitaire sidecar qui se connecte au socket de SPIRE Agent, récupère un JWT-SVID pour une audience donnée, l'écrit dans un fichier et le récupère à nouveau avant son expiration. L'utilitaire s'exécute en mode démon par défaut. L'exemple suivant définit explicitement daemon_mode = true.
agent_address = "/run/spire/sockets/agent.sock"
# The JWT-SVID file is written under cert_dir
cert_dir = "/var/run/secrets/anthropic.com"
daemon_mode = true
jwt_svids = [{
jwt_audience = "https://api.anthropic.com"
jwt_svid_file_name = "token"
}]Dans Kubernetes, exécutez spiffe-helper en tant que conteneur sidecar partageant un volume emptyDir en mémoire (medium: Memory) avec votre conteneur applicatif, afin que le SVID porteur n'atterrisse jamais sur le disque du nœud. Montez le socket de SPIRE Agent depuis l'hôte dans le sidecar, montez le volume partagé sur /var/run/secrets/anthropic.com dans les deux conteneurs, et définissez ANTHROPIC_IDENTITY_TOKEN_FILE=/var/run/secrets/anthropic.com/token sur le conteneur applicatif. Sur les VM et le bare metal, exécutez spiffe-helper en tant que service système aux côtés de la charge de travail et faites pointer les deux vers un répertoire partagé.
Configurer Anthropic
Dans la Claude Console, ouvrez Settings → Workload identity, cliquez sur Connect workload et sélectionnez Custom OIDC. L'assistant vous guide dans l'enregistrement de l'émetteur, la création d'un compte de service et la création d'une règle de fédération.
L'assistant crée ces ressources pour vous. Utilisez les valeurs suivantes, que vous les saisissiez dans l'assistant ou que vous les envoyiez à l'Admin API :
Émetteur de fédération : enregistrez l'URL publique de l'OIDC Discovery Provider en mode discovery. Anthropic récupère /.well-known/openid-configuration à partir de cette URL et suit le jwks_uri renvoyé pour obtenir les clés de signature du domaine de confiance.
{
"name": "spire-prod",
"issuer_url": "https://oidc-discovery.prod.example.com",
"jwks": { "type": "discovery" }
}Si le fournisseur de découverte n'est pas accessible depuis l'internet public, récupérez le JWKS vous-même (curl https://oidc-discovery.prod.example.com/keys) et enregistrez l'émetteur avec "jwks": {"type": "inline", "keys": [...]} en utilisant le contenu du tableau keys renvoyé. En mode inline, l'issuer_url est uniquement comparée au claim iss du JWT-SVID. Anthropic ne tente jamais de l'atteindre.
Pour automatiser les mises à jour du JWKS sans exposer de point de terminaison de découverte public, configurez un plugin BundlePublisher de SPIRE Server (aws_s3, gcp_cloudstorage ou k8s_configmap) avec format = "jwks" pour pousser les clés de signature JWT vers un stockage externe à chaque rotation, puis mettez à jour les clés inline de l'émetteur via l'API Admin.
Règle de fédération : faites correspondre le sub du JWT-SVID (l'identifiant SPIFFE) et l'aud que vous avez configuré spiffe-helper à demander. Les identifiants SPIFFE sont des chaînes URI et subject_prefix les compare en tant que texte opaque, de sorte qu'une valeur exacte ou une correspondance de préfixe avec un * final fonctionnent toutes deux. Pour des motifs plus complexes, utilisez une condition CEL.
{
"name": "spire-inference-worker",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "spiffe://prod.example.com/ns/inference/sa/worker",
"audience": "https://api.anthropic.com"
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}token_lifetime_seconds est la durée de vie du jeton d'accès Anthropic renvoyé par l'échange, et non celle du JWT-SVID. Le SDK actualise automatiquement le jeton d'accès.
Soyez aussi précis que la charge de travail le permet. N'élargissez subject_prefix à spiffe://prod.example.com/ns/inference/* que si chaque charge de travail enregistrée sous ce chemin doit correspondre au même compte de service Anthropic. Ajoutez l'identifiant fdrl_... de la règle à la variable d'environnement ANTHROPIC_FEDERATION_RULE_ID de la charge de travail.
Acquérir et utiliser le jeton
Les SDK Anthropic peuvent soit lire le JWT-SVID depuis le fichier maintenu par spiffe-helper, soit appeler directement la SPIFFE Workload API via un callable fournisseur de jeton. L'approche par fichier est l'intégration la plus simple et fonctionne dans tous les langages du SDK. L'approche par callable supprime le sidecar mais nécessite un client SPIFFE Workload API dans le langage de votre application.
Avec spiffe-helper écrivant un JWT-SVID frais dans /var/run/secrets/anthropic.com/token, définissez ANTHROPIC_IDENTITY_TOKEN_FILE sur ce chemin, ainsi que ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID et ANTHROPIC_WORKSPACE_ID. Le SDK lit le fichier à chaque échange de jeton, de sorte qu'il récupère toujours le SVID le plus récemment renouvelé, et actualise automatiquement le jeton d'accès Anthropic avant son expiration. Consultez Variables d'environnement pour savoir d'où provient chaque valeur.
import anthropic
# Lit le JWT-SVID que spiffe-helper écrit dans
# ANTHROPIC_IDENTITY_TOKEN_FILE, ainsi que ANTHROPIC_FEDERATION_RULE_ID,
# ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID et ANTHROPIC_WORKSPACE_ID.
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))Vérifier la configuration
Avant d'intégrer le SDK, récupérez un JWT-SVID directement depuis SPIRE Agent et vérifiez que les claims correspondent à ce que votre règle de fédération attend. Si vous utilisez une autre implémentation SPIFFE, récupérez un JWT-SVID avec son CLI ou son client Workload API et décodez la charge utile de la même manière.
spire-agent api fetch jwt \
-audience https://api.anthropic.com \
-socketPath /run/spire/sockets/agent.sock \
-output json \
| jq -r '.[0].svids[0].svid' \
| jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson'L'option -output json renvoie la réponse SVID et la réponse bundle sous forme de tableau JSON à deux éléments, de sorte que jq -r '.[0].svids[0].svid' extrait le jeton brut. Sur les versions plus anciennes de SPIRE sans -output, la commande affiche à la place un bloc étiqueté. Dans ce cas, redirigez la sortie par défaut vers awk '/^[[:space:]]*eyJ/{print $1; exit}' pour extraire la ligne du jeton. Vérifiez que iss est l'URL de l'OIDC Discovery Provider que vous avez enregistrée, que sub est l'identifiant SPIFFE de la charge de travail et que aud contient https://api.anthropic.com. Exécutez ensuite l'exemple cURL de la section Acquérir et utiliser le jeton. Un échange réussi renvoie un access_token commençant par sk-ant-oat01-. Si l'échange échoue avec la réponse opaque 401 authentication_error (message Authentication failed), consultez la page d'historique d'authentification pour connaître le motif du refus et reportez-vous à Dépanner un échange échoué. La cause la plus fréquente côté SPIRE est une discordance entre le jwt_issuer de SPIRE Server et l'URL enregistrée comme émetteur de fédération.
Délimiter votre règle
Les conventions de chemin des identifiants SPIFFE sont définies par l'opérateur ; le matcher subject_prefix de la règle de fédération doit donc refléter le schéma de chemin utilisé par vos entrées d'enregistrement. Les schémas courants incluent spiffe://<trust-domain>/ns/<namespace>/sa/<service-account> (la valeur par défaut émise par la ressource ClusterSPIFFEID dans spire-controller-manager) et spiffe://<trust-domain>/host/<hostname>/<service> pour les charges de travail sur VM et bare metal.
Verrouillez le bloc match de la règle sur la portée la plus étroite adaptée à votre cas d'usage :
- Épingler à une seule charge de travail : définissez
subject_prefixsur l'identifiant SPIFFE complet sans*final. - Toujours définir une audience : exigez
audiencesur la règle et configurez spiffe-helper (ou l'appel à la Workload API) avec la même valeur afin que les SVID émis pour d'autres parties utilisatrices soient rejetés. - Délimiter par segment de chemin : utilisez
spiffe://prod.example.com/ns/inference/*pour autoriser toutes les charges de travail enregistrées sous un namespace, et créez une règle et un compte de service Anthropic distincts par namespace plutôt que d'élargir une seule règle. - Un émetteur par domaine de confiance : chaque domaine de confiance SPIRE possède ses propres clés de signature et son propre OIDC Discovery Provider. Enregistrez chacun comme un émetteur de fédération distinct et liez les règles à l'émetteur qui possède les identifiants SPIFFE auxquels elles correspondent.
Étapes suivantes
Fédérez les identités d'applications de service Okta vers l'API Claude avec Workload Identity Federation.
Authentifiez les charges de travail auprès de l'API Claude avec des jetons d'identité de courte durée provenant de votre propre fournisseur d'identité au lieu de clés API statiques de longue durée.
Variables d'environnement, règles de validation, configuration des profils et référence des erreurs pour Workload Identity Federation.
Authentifiez-vous auprès de l'API Claude depuis des clusters Kubernetes autogérés à l'aide de jetons de compte de service projetés.
Was this page helpful?