Aller au contenu

Donner une clé d'API à une équipe

Créer le compte, engendrer la clé et la remettre : la clé n'est lisible qu'au moment où elle s'affiche.

Dans l’architecture de référence, Lemniscate ne gère pas d’identités : chaque développeur s’authentifie auprès de votre annuaire, et aucune clé n’est à remettre (livre blanc sécurité V3, section 6.1). Des comptes locaux n’existent que là où aucun annuaire n’est disponible. Cette page concerne les consoles dont le profil de construction porte un référentiel de comptes local, où chaque compte s’authentifie par une clé d’API. Elle décrit la création du compte, la remise de la clé, et le seul moment où la clé 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 est obligatoire à la création, dans la console comme en ligne de commande : la passerelle répond 403 à un compte sans plan. Quand aucun plan n’existe, la console remplace le formulaire de création par un message qui renvoie à l’onglet Plans. Le choix du plafond est décrit dans Plafonner la dépense d’un client.

Onglet Users, section New user : un nom et un plan. Le bouton Create user reste inactif tant que les deux champs ne sont pas remplis.

Le serveur engendre la clé lui-même ; l’administrateur n’en fournit pas. La réponse à la création la rend en clair, une seule fois. La console l’affiche avec la mention qu’elle ne sera plus montrée.

La base n’enregistre 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 ; aucun clic ne révèle la clé entière.

La clé entière n’apparaît qu’à trois moments : la réponse à une création, la réponse à une rotation, et la réponse à l’émission d’une clé supplémentaire depuis l’écran Keys d’un compte. Aucune requête, aucun écran, aucun accès à la base ne la retrouve ensuite. Le fragment sert à reconnaître une clé, par exemple pour vérifier au téléphone qu’on parle de la même ; il ne sert pas à la récupérer.

Copiez la clé 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. 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 pour ses secrets.

Deux points à connaître avant de choisir ce moyen :

  • La clé accompagne chaque appel du poste à la passerelle. Ce trajet est chiffré en TLS (livre blanc sécurité V3, section 6.2) : la passerelle termine TLS quand TLS_CERT_FILE et TLS_KEY_FILE sont posées, et le journal de démarrage annonce le mode retenu. Ne remettez pas de clé tant que ce journal annonce une écoute en clair sans terminaison TLS placée devant.
  • Dans ce profil, 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 se tient hors du produit, au moment de la remise.

Sur une base neuve, ou un déploiement inachevé, 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 : la clé n’est pas enregistré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'

Ce chemin sert à l’amorçage. Dès que la console répond, elle gère les comptes : elle fait aussi tourner une clé et retire un compte, ce que le script ne fait pas.

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

Toutes les clés que le compte détenait cessent d’authentifier immédiatement ; il n’y a pas de période où l’ancienne et la nouvelle fonctionnent ensemble. Prévenez le porteur avant la rotation.

Le compte garde son identité : son identifiant ne change pas, 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, bouton Delete, derrière une confirmation. Deux issues sont possibles, 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 l’historique d’usage : supprimer une ligne que request_logs référence détruirait l’attribution d’appels déjà comptés. Un compte désactivé n’authentifie plus : la passerelle ne retient que les comptes actifs, quelles que soient leurs clés.

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

Aucun bouton de la console ne le fait : la colonne Active est en lecture seule, et les actions par ligne sont l’écran des clés, la rotation et la suppression. La route existe (PATCH /api/users/:id accepte active). Le rattrapage se fait en SQL :

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

Cet écart de la console est connu.