La clé d'API est un aveu
Une clé statique dans un header, c'est un mot de passe qui ne tourne jamais, envoyé à chaque appel. Où la clé suffit, où elle est coupable, et par quoi la remplacer.
La clé d'API est le mécanisme d'authentification le plus courant sur les API qu'on croise en audit, et le plus mal employé. C'est un mot de passe applicatif : un secret statique, transmis en clair dans un header à chaque appel, valable jusqu'à révocation explicite, c'est-à-dire, dans la pratique, pour toujours.
Elle dit une chose et une seule : cet appel vient d'un porteur de la clé. Elle n'identifie pas l'utilisateur final, ne porte aucun périmètre de droits, n'expire pas, et se copie dans un fichier de configuration aussi facilement que dans un canal Slack. Ce n'est pas qu'elle soit mauvaise en soi : elle est presque toujours utilisée au-delà de ce qu'elle sait faire.
Où elle suffit
Il y a des usages où la clé est le bon outil, et il faut le dire clairement pour être crédible quand on la refuse ailleurs :
- l'identification de trafic entre services internes de faible sensibilité, où l'enjeu est de savoir qui appelle pour mesurer et limiter, pas de protéger la donnée.
- les API publiques en lecture sur données publiques, où la clé sert au quota et à la facturation.
- les webhooks sortants, en complément d'une signature.
Le point commun : la clé y sert à compter et attribuer, pas à protéger.
Où elle est coupable
Dès que l'API touche des données personnelles, de l'argent ou une action métier, la clé seule est en dessous de l'état de l'art, et l'écart se paie à l'audit ou à l'incident.
Trois défauts, qui se cumulent. Elle ne tourne pas : la rotation demande une coordination avec le consommateur, donc elle n'a jamais lieu, et les clés survivent aux projets comme aux prestataires. Elle ne porte pas de contexte : le backend reçoit « la clé du partenaire X », à charge pour lui d'inventer le reste. Elle fuit bien : dépôts Git, journaux, tickets de support, exports Postman, et sa durée de vie infinie transforme chaque fuite en porte ouverte permanente.
Une clé dans un front est une clé publique
Une clé embarquée dans une application monopage, une application mobile ou n’importe quel code exécuté chez le client est publique. Pas « exposée à un risque » : publique. Elle se lit dans l’onglet réseau du navigateur, dans le bundle JavaScript, dans le binaire décompilé. Aucune obfuscation ne change ce fait, elle ne fait que rallonger de quelques minutes le temps nécessaire pour la trouver.
Elle n’identifie rien. Une clé que n’importe qui peut extraire n’authentifie pas l’application, elle indique seulement quelle application était censée appeler. C’est une information de routage et de comptage, pas une preuve.
Le quota devient une ressource partagée avec des inconnus. Le premier usage d’une clé extraite est d’en profiter, et le quota se consomme au détriment des vrais utilisateurs.
La révocation est une mise à jour d’application. Sur mobile, la validation du magasin se compte en heures, mais l’adoption par le parc installé s’étale sur des semaines. Une clé compromise reste active tant que les utilisateurs n’ont pas basculé, et couper la clé avant qu’ils l’aient fait revient à couper le service.
Ce qu’il faut faire à la place dépend de qui est censé être authentifié. S’il s’agit de l’utilisateur, c’est un flux authorization code avec PKCE, sans aucun secret embarqué, voir accès. S’il s’agit de l’application elle-même, il faut un back-end : c’est lui qui détient le secret et appelle l’API, et le front ne parle qu’à lui.
Si une clé publique reste nécessaire, pour compter ou pour router, elle se traite comme telle : quota bas, aucune donnée sensible derrière, surveillance de son usage. La restriction par origine n’arrête qu’un navigateur et se contourne en une ligne de commande, elle ne compte pas comme une protection. Une clé publique assumée est acceptable, une clé publique traitée comme un secret ne l’est pas.
Par quoi remplacer
La réponse standard est OAuth 2 en client credentials pour le machine à machine : des jetons courts, émis par un fournisseur d’identité, avec un périmètre. La fuite d’un jeton vaut sa durée de vie, quelques minutes à une heure, pas des années. Encore faut-il fixer cette durée courte, c’est le réglage qui décide de la valeur de la mesure.
Une objection s’impose ici, et il faut la traiter plutôt que la laisser au lecteur. Un
client_secret partagé est lui aussi un secret statique, transmis à chaque demande de
jeton, et qui ne tourne jamais faute de coordination avec le consommateur. Déplacer le
problème d’un cran ne le résout pas.
Deux mécanismes le ferment. L’authentification du client par clé privée signée ou par certificat, plutôt que par secret partagé : le consommateur prouve qu’il détient une clé sans jamais la transmettre. Et les jetons liés au porteur, par mTLS (RFC 8705) ou par DPoP, qui rendent inutilisable un jeton volé. Sans l’un des deux, la migration vers OAuth améliore la rotation et pas l’authentification.
Pour les flux portant l’utilisateur final, le même cadre transporte son identité et ses droits jusqu’au backend, ce qui vide le problème du « contexte inventé ».
Pour le partenaire à forte sensibilité, le mTLS ajoute l’authentification mutuelle au transport. Il fonctionne très bien, à une condition : que le cycle de vie des certificats appartienne à quelqu’un, avec inventaire et alerte d’expiration.
La migration sans drame
On ne convertit pas un parc de consommateurs à OAuth par décret. La méthode qui marche ressemble à toutes les dépréciations réussies :
- les nouvelles souscriptions n'ont plus le choix : jetons dès le premier jour.
- la gateway accepte les deux mécanismes sur les API existantes, et journalise qui utilise encore la clé.
- chaque consommateur à clé reçoit une date, un guide, et l'aide nécessaire.
- la clé est fermée API par API, à la date dite.
Le levier caché est le portail : si obtenir un client OAuth est en libre-service et prend cinq minutes, la migration avance. Si c'est un ticket, elle n'avancera pas, et ce ne sera pas la faute des consommateurs.
L'inventaire des mécanismes réellement en service, API par API, est une des premières choses qu'on regarde en audit : l'écart entre la policy déclarée et ce que la gateway accepte vraiment est en général le premier constat du rapport.
Publié en mai 2025.
Sur le même sujet