Passer au contenu principal
GUIDE

Comment protéger les actions sensibles sans bloquer les agents légitimes

Un modèle pratique pour sécuriser les changements de compte et les opérations à fort impact tout en permettant aux clients automatisés légitimes d'effectuer un travail utile dans votre application.

Toshendra Sharma

Par Toshendra SharmaFondateur et CEO, AgentCredia · Updated November 13, 2026

Avancé · 10 min de lecture

Pourquoi ne pas simplement bloquer les agents pour les actions sensibles ?

Certaines actions de votre application comptent davantage que d'autres. Changer un mot de passe, ajouter un membre à l'équipe, exporter des données, supprimer un projet, approuver une commande : si l'une de ces opérations se produit sans l'autorité appropriée, les dégâts sont réels.

Dans le même temps, une part croissante du travail légitime dans votre application est effectuée par l'automatisation. Un utilisateur demande à un assistant de mettre à jour ses paramètres. Une intégration partenaire crée des enregistrements selon un calendrier. Un agent interne ouvre des tickets de support. Bloquer tout client automatisé sur les routes sensibles casse ce travail et renvoie les personnes vers des tâches manuelles ou des contournements plus difficiles à sécuriser.

La réponse n'est ni "bloquer les agents" ni "faire confiance aux agents". C'est un modèle dans lequel le risque de l'action, l'autorité derrière la requête et les éléments d'évidence sur l'acteur jouent chacun un rôle distinct. Ce guide construit ce modèle. Pour une réflexion plus large, voir concevoir des politiques au niveau de l'application pour les humains et les agents IA.

Étape 1 : classez vos routes selon le risque

Commencez par classer les actions, pas les clients. Un schéma simple à trois niveaux fonctionne pour la plupart des applications :

Niveau Exemples Exigence par défaut
Faible Lire des données publiques, rechercher, afficher son propre tableau de bord Authentification normale, le cas échéant
Moyen Créer ou modifier son propre contenu, inviter un lecteur Authentifié, autorisé pour la ressource
Élevé Modifier des identifiants, changer la propriété, exporter en masse, supprimer, approuver Autorisé plus contrôle de renforcement ou revue

Inscrivez le niveau dans la configuration de la route afin qu'il soit visible lors de la revue de code :

TS
type Tier = "low" | "medium" | "high";

export const routeTier: Record<string, Tier> = {
  "GET /projects": "low",
  "POST /projects": "medium",
  "POST /projects/:id/members": "medium",
  "POST /account/password": "high",
  "POST /exports": "high",
  "DELETE /projects/:id": "high",
};

Les niveaux évoluent lentement et sont faciles à raisonner. Tout le reste de ce guide en dépend.

Étape 2 : en quoi identité, identifiants et autorisation diffèrent-ils ?

Trois questions sont souvent confondues :

  1. Qui ou quoi agit ? Il s'agit de l'évidence sur l'acteur : une personne en interaction, une personne assistée par l'IA, un agent ou Unknown, avec une base telle que Verified ou Declared.
  2. Quel identifiant a été présenté ? Un cookie de session, une clé API, un jeton d'accès OAuth.
  3. Cet identifiant est-il autorisé à effectuer cette action sur cette ressource ? Il s'agit de l'autorisation.

Une signature d'agent vérifiée (RFC 9421) répond bien à la première question. Elle ne dit rien sur la troisième, point abordé en détail dans ce que prouvent les requêtes signées d'agents IA, et ce qu'elles ne prouvent pas. Un jeton OAuth avec le bon scope répond à la troisième question. Il dit peu de chose sur la première. Votre décision pour une action de niveau élevé a toujours besoin d'une bonne réponse à la troisième question, et utilise la première pour déterminer combien d'assurance supplémentaire demander.

TS
interface Context {
  actor: { actor: "human" | "human_ai" | "agent" | "unknown"; basis: "verified" | "declared" | "inferred" | "unknown" };
  credential: { type: "session" | "oauth" | "api_key"; scopes: string[]; subject: string };
}

function authorized(ctx: Context, action: string, resourceOwner: string): boolean {
  return ctx.credential.subject === resourceOwner && ctx.credential.scopes.includes(action);
}

L'autorisation n'est jamais relâchée à cause d'un résultat d'acteur favorable. Le contexte de l'acteur n'ajoute que des exigences supplémentaires ou choisit entre des chemins également sûrs.

Étape 3 : utilisez une autorité déléguée pour les agents qui agissent pour des personnes

Lorsqu'un agent agit au nom d'un utilisateur, donnez-lui son propre identifiant avec une autorité limitée au lieu de lui permettre de réutiliser la session de l'utilisateur. OAuth 2.0 est l'outil standard : l'utilisateur approuve des scopes spécifiques pour un client spécifique, et le jeton enregistre ce client. RFC 9700, le OAuth 2.0 Security Best Current Practice, décrit comment le déployer en toute sécurité. Les serveurs MCP suivent le même modèle : la spécification d'autorisation MCP traite un serveur MCP protégé comme un resource server OAuth 2.1. Notre article qui appelle votre serveur MCP ? applique cela aux appels d'outils.

Cela produit exactement ce qu'il faut pour les actions sensibles :

  • Le jeton vous indique quel client agit et pour qui.
  • Les scopes limitent ce qu'il peut faire. Un agent de planification avec calendar:write ne peut pas changer un mot de passe.
  • L'utilisateur peut révoquer l'octroi sans changer ses propres identifiants, et OAuth 2.0 Token Revocation (RFC 7009) définit comment un client indique au serveur d'autorisation qu'un jeton ne doit plus être valide.
  • Les journaux d'audit montrent que l'agent, et non l'utilisateur, a effectué l'action.

Si votre application ne prend pas encore en charge les identifiants délégués, faites-en une priorité pour les actions dont les agents ont le plus souvent besoin. C'est le contrôle le plus efficace pour l'accès automatisé.

Étape 4 : quand faut-il demander un contrôle de renforcement ?

Le contrôle de renforcement consiste à demander une assurance supplémentaire au moment d'une action sensible. Pour les API protégées par OAuth, RFC 9470 définit comment un resource server indique à un client que l'authentification du jeton actuel n'est pas assez forte ou assez récente. Le bon contrôle dépend de qui agit :

  • Personne en interaction (Human, Human + AI) : réauthentification (voir les exigences de réauthentification dans NIST SP 800-63B), une invite de passkey construite sur WebAuthn, ou un code à usage unique.
  • Agent avec identifiant délégué : un scope dédié à l'action de niveau élevé, accordé explicitement par l'utilisateur, ou une confirmation envoyée à l'utilisateur hors bande.
  • Unknown : le contrôle fort existant de la route, sans modification.
TS
type Requirement = "none" | "reauth" | "explicit_scope" | "user_confirmation" | "review";

function stepUp(tier: Tier, ctx: Context): Requirement {
  if (tier !== "high") return "none";
  const { actor } = ctx.actor;
  if (actor === "human" || actor === "human_ai") return "reauth";
  if (actor === "agent" && ctx.credential.type === "oauth") return "explicit_scope";
  if (actor === "agent") return "user_confirmation";
  return "reauth";
}

Remarquez qu'un résultat Human ne saute pas le contrôle de renforcement. Il sélectionne le contrôle de renforcement adapté à une personne en interaction. Les inférences peuvent être erronées, elles doivent donc modifier la forme du contrôle, pas le supprimer.

Étape 5 : orientez vers une revue humaine quand le jugement est nécessaire

Certaines actions sont rares, à fort impact et difficiles à automatiser en toute sécurité : export en masse de données clients, récupération de compte après perte d'identifiants, ou suppression d'une organisation. Pour celles-ci, une file de revue est souvent préférable à toute règle automatisée.

Le contexte de l'acteur accélère et rend la revue plus équitable en donnant au réviseur les éléments d'évidence : la classe, la base, l'identifiant utilisé, l'historique des demandes similaires. Le réviseur décide. La classification informe.

TS
function shouldReview(route: string, ctx: Context): boolean {
  const reviewRoutes = new Set(["POST /exports", "POST /account/recover"]);
  if (!reviewRoutes.has(route)) return false;
  return !(ctx.credential.type === "oauth" && ctx.credential.scopes.includes("export:bulk"));
}

Étape 6 : choisissez le comportement en cas d'échec pour chaque niveau

L'évaluation de l'acteur peut expirer ou manquer d'éléments d'évidence. Décidez à l'avance de ce qui se passe.

  • Niveau faible : fail open. La requête se poursuit normalement.
  • Niveau moyen : fail open, avec l'autorisation normale en place.
  • Niveau élevé : fail closed vers le contrôle fort existant. L'absence d'évidence sur l'acteur n'affaiblit jamais la protection, et elle ne bloque jamais une requête qui aurait autrement passé vos contrôles normaux.

La propriété clé est la symétrie. Un échec dans l'évaluation de l'acteur doit laisser l'action exactement aussi sûre, et exactement aussi disponible, qu'avant l'ajout du contexte d'acteur.

Étape 7 : ne prenez pas de décisions conséquentes sur des personnes à partir d'inférences

Une classification inférée est une évidence sur une interaction, pas un fait sur une personne. Ne refusez pas une candidature, une décision de crédit, un résultat d'examen, un logement ou l'accès à un service essentiel parce qu'une session semblait automatisée ou assistée par l'IA. Dans ces flux, utilisez le contexte de l'acteur pour choisir un processus, comme une revue humaine ou un parcours de vérification alternatif, et assurez-vous que la personne puisse le terminer.

C'est à la fois un principe d'équité et une mesure pratique. Les inférences comportent des faux positifs, et le coût d'un faux positif dans ces flux retombe sur quelqu'un qui n'a rien fait de mal.

Étape 8 : déployez d'abord en observation

Avant que tout cela n'affecte des requêtes réelles, exécutez-le en mode observation et preview :

  1. Enregistrez le niveau, la classe d'acteur, la base, le type d'identifiant et le contrôle de renforcement que votre politique exigerait.
  2. Examinez des échantillons de requêtes de niveau élevé par classe. Les agents légitimes utilisent-ils des identifiants délégués, ou réutilisent-ils les sessions utilisateur ?
  3. Corrigez les écarts que vous trouvez, souvent en proposant des identifiants limités, avant d'appliquer l'enforcement.
  4. Appliquez l'enforcement sur un petit échantillon d'une seule route, mesurez les taux de complétion, puis élargissez.

Étape 9 : conservez une piste d'audit qui répond à "qui et au nom de qui"

Pour chaque action de niveau élevé, consignez assez d'informations pour reconstituer ce qui s'est passé plus tard :

  • la classe d'acteur et la base au moment de la requête,
  • le type d'identifiant, le client auquel il a été délivré et le sujet qu'il représente (OAuth 2.0 Token Exchange, RFC 8693, définit une revendication act pour enregistrer exactement ce type de relation "agissant pour"),
  • les scopes qui ont autorisé l'action,
  • l'exigence de contrôle de renforcement ou de revue appliquée et son résultat.
TS
audit.write({
  action: "project.export",
  actor: ctx.actor,
  client: ctx.credential.type === "oauth" ? clientIdFromToken(req) : undefined,
  subject: ctx.credential.subject,
  scopes: ctx.credential.scopes,
  requirement,
  outcome: "approved",
  at: new Date().toISOString(),
});

Avec cette trace, une question comme "une personne ou un assistant a-t-il supprimé ce projet, et qui l'a approuvé ?" a une réponse claire. Cela accélère la réponse aux incidents et donne aux utilisateurs la confiance que l'aide automatisée dans votre application est traçable.

Un exemple concret

Une application de gestion de projet voit un assistant mettre à jour des dates d'échéance de tâches pour des utilisateurs, et tenter parfois d'exporter des projets entiers.

  • La mise à jour d'une tâche est de niveau moyen. L'assistant utilise un jeton OAuth avec tasks:write. Autorisé, pas de contrôle de renforcement. Autorisé.
  • L'export d'un projet est de niveau élevé. Le jeton de l'assistant ne contient pas export:bulk. L'application envoie à l'utilisateur une demande de confirmation. L'utilisateur approuve, et l'application accorde le scope pour ce client.
  • Un client Unknown tente le même export avec un cookie de session réutilisé. L'invite de réauthentification existante s'applique, exactement comme auparavant.

Personne n'a été bloqué parce qu'il s'agissait d'un agent. Chaque action à fort impact portait une autorité explicite.

Où se situe Proof of Actor

Proof of Actor fournit la partie liée à l'acteur dans ce modèle : qui ou quoi agit et sur quelle base. Votre application conserve l'authentification, l'autorisation et la décision finale. Detect l'acteur, Understand comment chaque classe utilise vos routes sensibles, et Route chaque requête vers le bon niveau d'assurance.

Pour concevoir cela pour votre application avec notre équipe, faites une demande d'accès anticipé. Pour des scénarios SaaS plus détaillés, voir SaaS Apps & Websites.

Sources

Construisez-le avec nous.

Rejoignez le programme fondateur développeur de Proof of Actor.

Vous préférez en parler d'abord ? Parler aux fondateurs