Aller au contenu

Donner une clé d'API à une équipe

Une équipe doit passer par la passerelle : elle a besoin d’un compte et d’une clé. Cette page décrit la remise de cette clé, et l’unique moment où elle est lisible.

Ce qu’il faut avoir décidé avant d’ouvrir la console

Section intitulée « Ce qu’il faut avoir décidé avant d’ouvrir la console »

Le plan. Il est obligatoire à la création, dans la console comme en ligne de commande. Ce n’est pas une formalité administrative : la passerelle répond 403 à un compte sans plan, donc un compte créé sans plan serait un compte créé déjà bloqué. La console refuse de le fabriquer, et remplace le formulaire par un message quand aucun plan n’existe encore. Choisir le plafond associé est décrit dans Plafonner la dépense d’un client.

Onglet Users, bouton New user : un nom et un plan. Le bouton reste inerte tant que les deux ne sont pas donnés.

Le serveur engendre la clé lui-même — l’administrateur n’en fournit jamais une — et la rend en clair, une seule fois, dans la réponse à la création. C’est ce que la console affiche, avec la mention qu’elle ne sera plus montrée.

C’est le point qui coûte le plus cher à découvrir après coup.

La base ne stocke pas la clé. Elle garde un condensat SHA-256, sur lequel l’authentification cherche, et un fragment affichable de la forme sk-lemniscate-…a3f9. La colonne « API Key » de la liste des comptes montre ce fragment, et rien d’autre : le clic qui révélait autrefois la clé entière a été retiré, parce qu’il n’y a plus rien à révéler.

La clé entière n’apparaît qu’à deux moments : la réponse à une création, et la réponse à une rotation. Aucune requête, aucun écran, aucun accès à la base ne la retrouve ensuite. Le fragment sert à reconnaître une clé — vérifier au téléphone qu’on parle bien de la même —, jamais à la récupérer.

Conséquence pratique : copiez-la au moment où elle s’affiche. Une clé perdue ne se retrouve pas, elle se remplace.

Le produit n’ouvre aucun canal de transmission : il affiche la clé une fois, et s’arrête là. Le dépôt ne décrit aucune procédure de remise, et cette page n’en invente pas. La clé voyage par le moyen que votre organisation emploie déjà pour ses secrets.

Deux éléments à peser dans ce choix, tous deux propres à cette passerelle :

  • La passerelle sert en HTTP clair. Aucune terminaison TLS n’est fournie ni documentée par le produit. Entre le poste du développeur et la passerelle, la clé et les prompts circulent sans chiffrement, sur le réseau où vous l’avez posée.
  • La console a un seul jeu d’identifiants partagé. Pas de comptes nominatifs, pas de rôles, pas de trace de qui a créé ou remis quoi. Si vous devez pouvoir dire plus tard qui détient quelle clé, cette trace est à tenir hors du produit, au moment de la remise.

Sur une base neuve, ou un déploiement à moitié fait, add-user.sh fait la même création depuis un shell :

Fenêtre de terminal
export DATABASE_URL="postgresql://<utilisateur>:<mot-de-passe>@<hôte>:<port>/<base>"
cd gateway-db
./add-user.sh <nom-du-compte> <nom-du-plan>

Le second argument est un nom de plan (plans.name), pas un identifiant : les identifiants sont des SERIAL dont la valeur diffère entre une base construite depuis init.sql et une base construite par la chaîne de migrations. Si le plan n’existe pas, le script refuse, liste les plans disponibles, et n’écrit rien.

Le script affiche la clé en fin d’exécution, avec les mêmes conséquences que la console : elle n’est pas stockée, seul son condensat l’est.

Pour lister les plans avant de choisir :

Fenêtre de terminal
psql "$DATABASE_URL" -c 'SELECT name, max_cost_euro FROM plans ORDER BY name'

C’est un chemin d’amorçage. Dès que la console répond, c’est elle qui gère les comptes : elle sait aussi faire tourner une clé et retirer un compte, ce que le script ne fait pas.

Onglet Users, Rotate key, derrière une confirmation dont le texte annonce la coupure. La nouvelle clé est affichée une fois, comme à la création.

L’ancienne cesse d’authentifier immédiatement — il n’y a pas de période où les deux fonctionnent. Prévenez le porteur avant, pas après.

Le compte, lui, garde son identité : son identifiant ne change pas, donc les appels déjà journalisés à son nom lui restent attribués, et sa consommation du mois n’est pas remise à zéro.

Onglet Users, Delete, derrière une confirmation. Deux issues, et la réponse dit laquelle a eu lieu :

Le compte… Ce qui se passe
n’a jamais rien appelé il est supprimé
a au moins un appel journalisé il est désactivé (active = FALSE), la ligne subsiste

La distinction protège la facturation : supprimer une ligne que request_logs référence détruirait l’attribution d’appels déjà facturés. Un compte désactivé n’authentifie plus — la passerelle ne retient que les comptes actifs.

Pour bloquer sans supprimer, il existe un troisième geste, plus réversible : retirer son plan au compte depuis le sélecteur de la colonne Plan, valeur No plan. Le badge « Blocked » apparaît aussitôt, et la passerelle répond 403.

Aucun bouton de la console ne le fait aujourd’hui : la colonne Active est un badge en lecture seule, et les actions par ligne se limitent à la rotation et à la suppression. La route existe pourtant (PATCH /api/users/:id accepte active). À défaut, le rattrapage se fait en SQL :

UPDATE users SET active = TRUE WHERE username = 'nom-du-compte';

C’est un écart connu de la console, pas un contournement à préférer.