Kanbante 0.46.0 : documentation — correspondance draco, JIT, liaison admin, amorçage, non-régressions (docs/correspondance-draco.md)
This commit is contained in:
@@ -0,0 +1,132 @@
|
|||||||
|
# Correspondance draco par utilisateur (HUB-16, 0.46.0)
|
||||||
|
|
||||||
|
Kanbante participe au SSO de la suite dracodev : ObsiGate émet le
|
||||||
|
cookie `draco_session` (JWS HS256, claims `sub`, `name`, `iat`,
|
||||||
|
`exp`, `jti`), Kanbante le valide localement (`app/draco.py`) et le
|
||||||
|
pont `GET /auth/draco` le convertit en session Kanbante native.
|
||||||
|
|
||||||
|
Depuis la 0.46.0, un jeton draco valide désigne **le compte
|
||||||
|
Kanbante de cette identité** — et aucun autre. L'ancienne
|
||||||
|
hypothèse mono-utilisateur (« un jeton valide = l'opérateur ») a
|
||||||
|
disparu. C'est ce qui fait tenir le critère de la suite : « un
|
||||||
|
compte créé fonctionne dans toutes les applications ».
|
||||||
|
|
||||||
|
## Où vit la correspondance
|
||||||
|
|
||||||
|
Dans le modèle existant des comptes : la colonne
|
||||||
|
**`users.draco_sub`** (texte, `UNIQUE`, présente depuis la 0.24.0)
|
||||||
|
porte le `sub` draco lié à chaque compte Kanbante.
|
||||||
|
`models.get_user_by_draco(sub)` est la résolution canonique ; la
|
||||||
|
règle de décision complète vit dans
|
||||||
|
`app.accounts.resolve_draco_user()`, seul point d'entrée du pont
|
||||||
|
et du contrôle draco de `/api/search`. La correspondance est donc
|
||||||
|
biunivoque : un `sub` ↔ un compte, garanti par la contrainte
|
||||||
|
d'unicité.
|
||||||
|
|
||||||
|
## Résolution d'une connexion draco (`/auth/draco`)
|
||||||
|
|
||||||
|
Dans l'ordre :
|
||||||
|
|
||||||
|
1. **Session native déjà ouverte** : si le navigateur porte à la
|
||||||
|
fois une session Kanbante et un cookie draco dont le `sub`
|
||||||
|
n'est lié à aucun compte, le `sub` est lié au compte de la
|
||||||
|
session (première visite doublement connectée — mécanisme
|
||||||
|
historique, inchangé, aussi appliqué à la connexion native
|
||||||
|
dans `login_submit`).
|
||||||
|
2. **Correspondance existante** : la session du compte lié est
|
||||||
|
ouverte. Un compte **désactivé** n'ouvre aucune session et
|
||||||
|
n'est jamais contourné (voir § Désactivation).
|
||||||
|
3. **Compte d'amorçage** : s'il n'existe qu'**un seul compte** et
|
||||||
|
que c'est un **admin actif sans liaison**, le premier `sub`
|
||||||
|
valide s'y lie et sa session est ouverte. C'est le cas du
|
||||||
|
compte créé à l'installation depuis l'environnement
|
||||||
|
(`KANBANTE_AUTH_USER` / `KANBANTE_AUTH_PASSWORD`, Bruno) : sa
|
||||||
|
correspondance s'établit au premier passage, sans le verrouiller
|
||||||
|
dehors. Ses autres accès restent inchangés dans tous les cas :
|
||||||
|
connexion native avec le mot de passe du compte, et repli
|
||||||
|
d'urgence par les identifiants d'environnement (formulaire et
|
||||||
|
Basic), qui ne dépendent pas de draco.
|
||||||
|
4. **Création JIT** : sinon, un compte Kanbante est créé pour
|
||||||
|
cette identité (détail ci-dessous) et sa session est ouverte.
|
||||||
|
|
||||||
|
Un `sub` inconnu n'ouvre **jamais** la session de l'opérateur
|
||||||
|
d'environnement ni celle d'un compte existant non lié — y compris
|
||||||
|
si le nom affiché draco ressemble au nom d'un compte local : le
|
||||||
|
JIT crée toujours un compte **nouveau** (nom suffixé `-2`, `-3`…
|
||||||
|
en cas de collision), jamais une adoption.
|
||||||
|
|
||||||
|
## Création JIT (juste-à-temps)
|
||||||
|
|
||||||
|
À la première connexion draco d'une identité sans correspondance :
|
||||||
|
|
||||||
|
- **nom d'utilisateur** : nom affiché des claims slugifié
|
||||||
|
(`Alice Exemple` → `alice-exemple`), libre ou suffixé ;
|
||||||
|
repli `draco-<sub>` si le nom est inexploitable ;
|
||||||
|
- **nom d'affichage** : le `name` des claims ;
|
||||||
|
- **rôle** : `member` (utilisateur standard) — jamais admin ;
|
||||||
|
- **mot de passe local** : secret aléatoire, haché (PBKDF2 comme
|
||||||
|
tous les comptes), **jamais divulgué** — l'accès normal passe
|
||||||
|
par draco. Un administrateur peut ensuite poser un mot de
|
||||||
|
passe local depuis `/admin` (bouton « Réinitialiser ») si un
|
||||||
|
accès local est voulu ;
|
||||||
|
- **espace** : le compte rejoint l'espace Principal comme membre,
|
||||||
|
comme tout utilisateur créé par l'administration ;
|
||||||
|
- le geste est journalisé (`draco.jit` dans le journal
|
||||||
|
d'administration).
|
||||||
|
|
||||||
|
## Liaison par l'administrateur (comptes préexistants)
|
||||||
|
|
||||||
|
Pour associer un compte Kanbante existant à une identité draco
|
||||||
|
sans attendre un premier passage :
|
||||||
|
|
||||||
|
1. Se connecter à Kanbante avec un compte **admin**.
|
||||||
|
2. Ouvrir **Administration** (`/admin`), section **Utilisateurs**.
|
||||||
|
3. Dans la colonne **Draco (sub)** du compte visé, saisir le
|
||||||
|
`sub` draco de l'identité (l'identifiant du compte de suite
|
||||||
|
chez l'émettrice, ObsiGate) et cliquer **Lier**.
|
||||||
|
4. La liaison est immédiate et journalisée (`draco.link.admin`).
|
||||||
|
Le bouton **Délier** de la même colonne la retire
|
||||||
|
(`draco.unlink.admin`).
|
||||||
|
|
||||||
|
Gardes : un `sub` déjà lié à un autre compte est refusé avec un
|
||||||
|
message d'erreur (délier l'autre compte d'abord). L'administrateur
|
||||||
|
peut lier **son propre** compte — c'est la voie manuelle pour le
|
||||||
|
compte d'amorçage si le premier passage ne l'a pas lié.
|
||||||
|
|
||||||
|
Chaque utilisateur peut aussi voir sa propre liaison dans
|
||||||
|
**Mon profil → Liaison draco (SSO)** et la délier lui-même.
|
||||||
|
|
||||||
|
> Le registre matriciel des rôles par application côté Hub
|
||||||
|
> (carte HUB-19) lira cette correspondance ; la présente carte ne
|
||||||
|
> livre que le côté Kanbante, qui est la source de vérité locale.
|
||||||
|
|
||||||
|
## Surfaces voisines
|
||||||
|
|
||||||
|
- **`GET /api/search`** (« Rechercher partout ») : le cookie draco
|
||||||
|
n'y est plus accepté « en tant qu'opérateur ». Il faut que le
|
||||||
|
`sub` désigne un compte (correspondance existante ou compte
|
||||||
|
d'amorçage lié au passage). Aucune création JIT sur cette
|
||||||
|
surface : la création a lieu à la première vraie connexion, par
|
||||||
|
le pont. Les autres modes d'accès à `/api/search` (session,
|
||||||
|
Basic, jeton `kbt_`) sont inchangés.
|
||||||
|
- **Désactivation** : désactiver un compte dans `/admin` coupe
|
||||||
|
tous ses accès — session native, pont draco (la correspondance
|
||||||
|
résout à « refusé ») et jetons `kbt_`. Réactiver le compte
|
||||||
|
rétablit la correspondance telle quelle.
|
||||||
|
|
||||||
|
## Non-régressions garanties
|
||||||
|
|
||||||
|
- **Jetons personnels `kbt_`** : création, usage sur `/mcp` et
|
||||||
|
`/api/`, révocation — inchangés ; un jeton n'ouvre toujours pas
|
||||||
|
l'interface web.
|
||||||
|
- **Sessions propres Kanbante** et **connexion native**
|
||||||
|
(formulaire, mot de passe de la base) : inchangées, y compris
|
||||||
|
la liaison automatique à la première visite doublement
|
||||||
|
connectée.
|
||||||
|
- **Authentification Basic** (identifiants d'environnement, pour
|
||||||
|
les scripts) : inchangée.
|
||||||
|
- **Pont inerte sans `DRACO_SESSION_SECRET`** : sans secret
|
||||||
|
configuré, `/auth/draco` renvoie au login, comme avant.
|
||||||
|
- La réconciliation Kanbante/Gitea par étiquettes (adoption d'une
|
||||||
|
colonne seulement si exactement une étiquette `kanban:*` est
|
||||||
|
reconnue) n'est pas touchée par cette carte.
|
||||||
Reference in New Issue
Block a user