[PARTIE-2]

Article technique pour développeurs et architectes — stack Spring Boot / Spring Cloud Gateway, comparant AWS AgentCore, Azure Foundry Agent Service et Keycloak.

suite Partie 1.

2. Les concepts à comprendre

OAuth 2.0 Token Exchange (RFC 8693)

La RFC 8693 définit un mécanisme standard pour échanger un token contre un autre. La requête se fait sur le /token endpoint d'un STS avec grant_type=urn:ietf:params:oauth:grant-type:token-exchange et accepte deux paramètres clés :

  • subject_token : le token qui représente l'identité au nom de qui la requête est faite (typiquement l'utilisateur final).
  • actor_token : le token qui représente l'identité de l'acteur qui agit (typiquement l'application ou l'agent).

Le STS valide les deux, applique sa politique, et retourne un token composite — le token OBO (On-Behalf-Of).

None
Le mécanisme du Token Exchange RFC 8693 — entrée, traitement, sortie

Le schéma montre les deux tokens d'entrée (subject_token + actor_token), les vérifications du STS au centre, et le token composite résultant à droite. La requête HTTP exacte vers le /token endpoint figure en bas.

Le claim act et la délégation

Quand le STS produit un token OBO, il inclut un claim act qui décrit l'acteur :

{
  "sub": "diaguily@acme.com",
  "act": {
    "sub": "service-account-claude",
    "iss": "https://kc.acme.com/realms/main"
  },
  "aud": "agentcore",
  "scope": "salesforce:read"
}

Lis-le comme une phrase : "le sujet de ce token est Diaguily, et il est manipulé par l'agent Claude". Si Claude appelle un autre agent, on chaîne les act (l'acteur précédent devient un act imbriqué). La chaîne entière reste cryptographiquement vérifiable.

Délégation vs impersonation

La RFC distingue deux sémantiques :

  • Impersonation : A reçoit tous les droits de B et devient indistinguable de B. Le sub change vers B. Pas de trace de A.
  • Délégation : A garde son identité (dans act), mais agit pour B (dans sub). Les actions sont attribuables aux deux.

Pour les agents IA, on veut TOUJOURS la délégation. L'impersonation efface la responsabilité — exactement ce qu'on cherche à éviter.

None
Délégation vs Impersonation — la distinction critique

À gauche, l'impersonation : l'agent prend l'identité de l'utilisateur, aucune trace de qui a vraiment agi. À droite, la délégation : les deux identités cohabitent dans le token, l'audit reste attribuable.

Pourquoi c'est critique pour les agents IA

Trois propriétés qui n'existent pas avec un JWT classique :

  1. Audit attribuable. Le log d'accès Salesforce dit "écriture par diaguily" — vrai ou faux selon que c'était lui ou son agent ? Avec act, on sait.
  2. Moindre privilège. La politique côté ressource peut être "si act.sub est un agent IA, refuser les opérations destructives, même si le sub a normalement les droits".
  3. Confinement de fuite. Le token OBO a un aud restreint et un TTL court (10 minutes typiquement). Volé, il ne fonctionne que pour AgentCore et expire vite.
None
La chaîne act — agent → agent → outil avec délégation préservée

Quand un agent appelle un autre agent qui appelle un outil, le claim act se chaîne par imbrication. Le serveur final voit toute la délégation et peut appliquer une politique sophistiquée — comme refuser les opérations destructives quand un agent intervient dans la chaîne.

3. Le gateway : Spring Cloud Gateway ou Traefik ?

Critères d'évaluation

Pour porter cette logique de sécurité, le gateway doit :

  1. Valider le JWT entrant (signature, JWKS cache, claims).
  2. Appeler un STS pour obtenir un token OBO (logique programmatique, pas du routage).
  3. Réécrire la requête vers le runtime (en JWT, en SigV4 selon le pattern).
  4. Logger l'audit de manière asynchrone.
  5. Gérer les erreurs proprement avec retry et circuit breaker.

Spring Cloud Gateway

Forces.

  • Logique custom triviale via GatewayFilter ou GlobalFilter en Java pur.
  • Spring Security OAuth2 intégré : validation JWT, cache JWKS, refresh, c'est natif.
  • Écosystème complet : AWS SDK for Java (SigV4), MSAL4J (OBO Entra ID), Nimbus JOSE+JWT (signature de tokens custom), Resilience4j (circuit breaker), Micrometer (métriques).
  • Si vos agents sont déjà en Spring Boot, une seule stack à maintenir.
  • Reactor (Project Reactor) : tout est non-bloquant, scalable.

Limites.

  • JVM = ~300–500 MB de RAM minimum. Réductible à ~80 MB avec GraalVM native image, mais ça complique le build.
  • Démarrage : 5–10 secondes en JVM, <1 s en native. Critique en autoscaling agressif, sinon non bloquant.
  • Performance : ~30 000 req/s par instance, vs ~80 000 pour Envoy. Largement suffisant pour la plupart des charges.

Traefik

Forces.

  • Léger (Go, ~50 MB de RAM).
  • Démarrage instantané.
  • Service discovery natif (Docker, K8s).
  • Très performant (~80 000 req/s par instance).

Limites pour notre cas.

  • Le token exchange n'est pas natif. Tu peux utiliser le middleware ForwardAuth qui délègue à un service externe HTTP — qui sera en Java/Spring de toute façon. Tu te retrouves avec deux composants à déployer et à monitorer.
  • SigV4 vers AWS : pas supporté nativement. Plugin tiers ou sidecar.
  • Plugins Yaegi (interpréteur Go embarqué) limités, pas d'accès à toutes les libs Go.
  • Pas d'intégration Spring Security, MSAL, AWS SDK.

Orientation correcte

Spring Cloud Gateway pour ce cas. Le token exchange est une logique métier, pas du routage. Avec Spring Gateway, c'est un GatewayFilter custom, intégré au reste de la stack. Avec Traefik, tu construis un service externe en Java de toute façon — autant tout mettre au même endroit.

Quand préférer Traefik : routage L7 pur sans logique custom, équipe Go, contrainte mémoire forte (<100 MB), edge proxy frontal devant Spring Gateway pour le TLS termination et le rate limiting global. Cette combinaison Traefik + Spring Gateway en deux niveaux est d'ailleurs un pattern courant.

4. Architecture commune des trois solutions

Toutes les solutions partagent la même structure :

[Frontend] → [Spring Cloud Gateway] → [STS] → [Runtime agent] → [Outils/MCP]
                    ↑                    ↑
              valide JWT           produit token OBO

Ce qui change selon le cloud :

None
Provider Auth

[Suite partie 3]