+2
−1
apps/api/src/amorce-cli.ts
0 → 100644
+77
−0
apps/api/src/auth/amorce.ts
0 → 100644
+214
−0
+45
−0
+29
−0
Loading
Installer Kastell laissait l'exploitant devant trois gestes qu'il fallait
connaître, dans un ordre qu'on ne pouvait pas deviner : créer un compte au
navigateur, y activer un second facteur, puis lancer une commande d'amorçage.
Le script demande maintenant une adresse, et l'instance fait le reste.
Ce qu'elle remet dépend de ce qu'elle sait faire
Un relais de courriel configuré : un lien de 24 heures, qui mène à poser un
mot de passe puis un second facteur. Aucun relais : un mot de passe
temporaire affiché dans le terminal. Le second est moins bon — il passe par
l'épaule de qui regarde l'écran — mais c'est ce qui reste quand rien ne peut
sortir, et le taire aurait laissé l'exploitant sans porte.
Le mot de passe SMTP se saisit désormais à l'invite, sans écho. La règle qui
l'en écartait reposait sur une prémisse fausse — une saisie par « read »
n'entre pas dans l'historique du shell — et coûtait cher : il fallait ouvrir
le .env et relancer la pile pour un secret qu'on avait sous les yeux.
Le parcours ne se contourne pas
Tant que le laissez-passer n'est pas remplacé, ou que le second facteur
manque, le compte ne peut rien faire d'autre que régler ces deux points.
Le garde vit dans serveur.ts, en un seul endroit. Chacun des quatorze
fichiers de routes réimplémente sa propre exigence de session ; y ajouter la
vérification quatorze fois, c'est la promettre treize fois et l'oublier une.
L'écran conduit, il ne garde pas.
Le droit root arrive au bout, et de lui-même
La demande était qu'il soit accordé tout de suite. Il ne l'est pas, et c'est
la seule chose que je n'ai pas faite telle quelle : la migration 0005 défend
par un déclencheur en base qu'aucune ligne root n'existe sans second facteur
— un droit qu'on ne peut pas exercer et dont on croira disposer le jour où
il faudra s'en servir. Elle avait même révoqué rétroactivement les droits
dans ce cas.
L'amorce marque donc le compte comme destiné à root, et le droit lui vient à
l'activation du second facteur, sans commande. Pour qui installe, la
différence ne se voit pas : il donne une adresse et ressort administrateur.
Pour la base, elle est entière.
Une commande, jamais une route
Ce geste fabrique le premier administrateur. L'exposer en HTTP le mettrait à
la portée de quiconque trouve une instance fraîche avant son exploitant — et
une instance fraîche n'a personne pour la défendre. dist/amorce.js voyage
dans l'image, comme dist/racine.js : l'accès à la machine reste la preuve.
Contrôlé — 18 garanties
Qu'une session au parcours inachevé reçoive 403 sur une route ordinaire et
200 sur celles qui servent à l'achever. Que le laissez-passer cesse d'ouvrir
quoi que ce soit une fois remplacé. Que le compte ne soit pas root avant le
second facteur, et le soit après, sans commande. Qu'une seconde amorce soit
refusée. Que le lien parte, ouvre une session, et exige quand même qu'on
pose un mot de passe — sans en réclamer un ancien que personne n'a reçu.
Deux défauts trouvés en éprouvant : la longueur minimale du mot de passe ne
vivait que dans le schéma de la route, donc pas pour qui appelle la fonction ;
et mon premier contrôle du garde visait une route inexistante, dont le 404
passait pour un refus — un preHandler ne s'exécute pas sur un chemin
introuvable.
938 garanties au total, aucune en échec.
Co-Authored-By:
Claude Opus 5 <noreply@anthropic.com>