Aller au contenu
Facteur
ENCommencer

Les clés d'API — brancher une suite de tests sur vos inboxes

Créer une clé, l'utiliser depuis une CI, la renouveler sans coupure, la révoquer. Ce que la clé atteint, et ce qu'elle n'atteindra jamais.

Une clé d’API, c’est ce qui permet à vos tests d’appeler l’API sans navigateur et sans session. Elle se crée depuis Réglages → Clés d’API, au niveau de l’organisation.

Deux questions, jamais une seule

Une clé répond séparément à deux questions, et c’est ce qui permet d’en donner peu à la fois :

Ce qu’elle peut faire — quatre portées, en deux familles :

PortéeCe qu’elle ouvre
ws:readlire les messages des espaces visés
ws:writey créer et supprimer des inboxes
org:readlister les espaces de travail
org:writeen créer un, le renommer, le marquer

Où elle peut le faire — tous vos espaces de travail, ou seulement ceux que vous nommez.

Écrire implique lire dans une famille, et rien ne traverse les familles : org:write ne donne pas accès à votre courrier. Un script qui provisionne des espaces n’a pas à lire les messages qui s’y trouvent.

Créer une clé

Réglages → Clés d’API → Créer une clé. Quatre choix :

  • Un nom. C’est ce qui vous permettra de savoir laquelle révoquer dans six mois. « CI GitHub », « recette Camille ».
  • Ce qu’elle peut faire. Lecture seule par défaut : une suite de tests lit des messages, elle n’a en général pas besoin de créer ni de supprimer des inboxes. Une seconde case ouvre la gestion des espaces, pour un script de provisionnement.
  • Où. Si vous ne précisez rien, la clé ne vise que votre espace principal — le choix le plus étroit, pour qu’un champ oublié ne donne jamais trop. La réponse vous rappelle toujours la portée obtenue.
  • Une durée. 90 jours par défaut, un an au plus.

Le secret s’affiche une seule fois, juste après la création. Nous n’en gardons qu’une empreinte : ni vous ni nous ne pouvons le retrouver ensuite. Copiez-le directement dans les secrets de votre CI.

L’utiliser

Un en-tête Authorization, et c’est tout :

curl -H "Authorization: Bearer fk_votre_cle" \
  https://api.facteur.eu/v1/inboxes

La forme Basic fonctionne aussi, avec la clé en nom d’utilisateur et un mot de passe vide — c’est ce qu’envoient certains SDK conçus pour d’autres plateformes.

N’envoyez pas de cookie de session en même temps qu’une clé : la requête est refusée avec AMBIGUOUS_CREDENTIALS plutôt que tranchée au hasard. Deux identités dans une requête, c’est un test qui prouve quelque chose sur la mauvaise.

Chaque route, sa portée et ses refus sont listés dans la référence d’API, sur developers.facteur.eu. Elle est en anglais uniquement, et elle est engendrée depuis la spécification contre laquelle l’API est tenue.

Ce qu’une clé atteint

Les inboxes des espaces qu’elle vise, et leurs messages. Rien d’autre.

Une clé visant « recette » ne lit pas le courrier de l’espace principal — c’est la frontière que les espaces existent pour poser, et c’est la même que celle des membres (voir espaces-de-travail).

Si vous choisissez « tous les espaces », la portée inclut aussi ceux que vous créerez plus tard : c’est ce que vous avez demandé, et une liste figée au moment de la création serait une clé qui cesse silencieusement de couvrir vos nouveaux espaces.

Elle appartient à l’organisation, pas à la personne qui l’a créée ni à un espace : elle survit au départ de son auteur. Une clé rattachée à quelqu’un casserait votre intégration continue le jour d’un pot de départ, sans que personne fasse le lien.

Ce qu’une clé n’atteint jamais

  • La gestion des clés elles-mêmes. Une clé ne crée pas de clé. Sinon une clé volée se renouvellerait elle-même et sa révocation ne voudrait rien dire.
  • Votre compte. Mot de passe, second facteur, passkeys, organisation : une clé fuitée ne prend pas le compte.
  • Les écritures, si elle est en lecture seule. La réponse est alors 403 SCOPE_INSUFFICIENT, qui nomme la portée manquante et celles que la clé porte.
  • La forme de votre organisation, sans org:*. Une clé qui n’a que ws:read reçoit 403 SCOPE_INSUFFICIENT sur la liste des espaces — avec le nom de la portée manquante, pas un « interdit » sec.
  • Faire entrer quelqu’un. Jamais, quelle que soit la portée. Ni invitation adressée, ni lien d’organisation : 403 KEY_CANNOT_INVITE. Un accès humain accordé par une clé survivrait à la révocation de cette clé — on retire la clé, l’invité reste membre.
  • Supprimer un espace de travail. 403 KEY_CANNOT_DELETE_WORKSPACE. La suppression réattribue l’historique de consommation et peut être refusée si une clé vise encore l’espace : c’est un arbitrage qui demande quelqu’un pour le lire. Supprimez depuis l’application.

Une session d’assistance ne peut pas créer de clé non plus, même avec votre accord explicite : la clé serait ensuite indiscernable d’une clé que vous auriez créée vous-même.

Renouveler sans coupure

Renouveler crée une clé neuve et laisse l’ancienne vivre 24 heures. Vous déployez le nouveau secret, vous regardez passer un build vert, et l’ancienne s’éteint seule.

C’est la raison d’être de cette fonction : une rotation qui coupe est une rotation que personne ne fait.

Une clé déjà révoquée ne se renouvelle pas — cela la garderait vivante quelques heures, ce qui annulerait la révocation.

Révoquer

Immédiat, sans fenêtre de cache : l’appel suivant échoue. Y compris celui d’un pipeline en cours, ce qui est le comportement voulu.

Le message distingue trois cas, parce que les gestes qu’ils demandent sont différents :

CodeCe que ça veut dire
KEY_REVOKEDquelqu’un l’a retirée — créez-en une nouvelle
KEY_EXPIREDl’horloge a fait son travail — renouvelez
KEY_UNKNOWNcette clé n’a jamais existé — vérifiez ce que votre CI envoie

La colonne « utilisée le » vous dit si une clé sert encore. C’est ce qui permet de révoquer sans se demander ce qu’on va casser.

Qui peut le faire

Un propriétaire ou un administrateur de l’organisation. Une clé lit tout le courrier de son espace, ce qui est davantage que ce qu’un membre fait à la main.

Supprimer un espace visé par une clé

Refusé, avec 409 WORKSPACE_HAS_ACTIVE_KEYS et le nom des clés qui bloquent.

Deux gestes possibles avant de réessayer : révoquer la clé, ou retirer cet espace de sa portée. Les deux autres comportements imaginables sont pires — détacher en silence laisserait une clé dont la portée est vide, et désactiver la clé casserait un pipeline sans que personne relie la panne à la suppression d’un espace.

Une clé déjà révoquée ou expirée ne bloque rien : elle n’ouvre plus rien.

Provisionner un espace par branche

C’est ce que org:write sert à faire :

# Ouvrir un espace pour la branche courante
curl -X POST https://api.facteur.eu/v1/workspaces \
  -H "Authorization: Bearer fk_votre_cle" \
  -H "content-type: application/json" \
  -d '{"name": "recette-PR-1234"}'

Deux choses à savoir :

  • L’espace créé n’entre pas dans la portée de la clé. Une clé ne s’élargit pas elle-même. Si vos tests doivent lire le courrier de ce nouvel espace, visez « tous les espaces » à la création de la clé — cette portée couvre aussi les espaces futurs.
  • Le plafond du plan s’applique. Un plan qui ne vend qu’un espace répond 402, avec le plan à partir duquel c’est possible.

Ce qui n’existe pas encore

  • La gestion des membres — lister, changer un rôle, retirer, depuis un script. Cela demande d’abord des routes que l’API n’expose pas.
  • La restriction d’adresse IP — une liste d’adresses autorisées, pour les runners qui sortent par une adresse fixe.

L’écran annonce les deux comme à venir.