Organisations et rôles
Le cloisonnement entre organisations, les cinq rôles et ce que chacun peut faire, les dérogations par membre, et le fonctionnement réel d'une invitation.
Une organisation est l'unité de cloisonnement. Boutiques, facturation, crédits, conversations et journaux d'audit appartiennent tous à une organisation, et rien ne passe de l'une à l'autre.
Un utilisateur peut appartenir à plusieurs organisations. L'URL indique
dans laquelle vous vous trouvez : /<orgSlug>/... pour l'organisation,
/<orgSlug>/<storeSlug>/... pour l'une de ses boutiques.
Les cinq rôles
| Rôle | Boutiques | Facturation | Membres | IA |
|---|---|---|---|---|
Propriétaire (owner) | lire, créer, modifier, supprimer | lire + gérer | lire, inviter, retirer | lancer, approuver les outils |
Admin (admin) | lire, créer, modifier | lire | lire, inviter | lancer, approuver les outils |
Membre (member) | lire, modifier | lire | lire | lancer, approuver les outils |
Observateur (viewer) | lire | lire | lire | aucun |
Délégué (delegate) | rien par défaut |
Deux lignes méritent qu'on s'y arrête.
L'observateur n'a pas accès à l'IA. C'est le seul rôle sans ai.use,
et c'est toute sa raison d'être : il sert à une partie prenante qui doit
voir les chiffres sans pouvoir dépenser le solde de crédits.
Le délégué part d'un socle vide, par conception. C'est le rôle d'un tiers mandaté : une agence, un freelance qui travaille dans l'organisation d'un client. Il détient exactement ce qu'une autorisation explicite lui accorde, et rien du seul fait d'exister. Un contrôle vérifie chaque entrée du registre sur ce point. La modification tentante consiste en effet à lui ajouter une permission « par cohérence », et c'est précisément celle qui ouvrirait la porte sans bruit.
Dérogations par membre
Le rôle fixe un socle, pas un plafond. OrganizationMember.permissions
contient { allow: [...], deny: [...] } : allow ajoute des permissions
au socle, deny en retire. Un admin les modifie depuis la matrice des
membres.
Les permissions sont des chaînes à points (store.read, billing.manage,
members.invite, agent.run, ai.use, workspace.write), et la liste
reste ouverte : en ajouter une demande une ligne dans le registre, pas
une migration.
Deux familles absentes des socles
studio.* : la production d'images et de vidéos pour la boutique
(voir Images et vidéos). Une organisation qui ne génère
pas de médias n'a pas à confier ce pouvoir, qui dépense des crédits, à
ses membres du seul fait qu'ils sont membres. Aucun socle, hors
propriétaire, ne les inclut donc. Ces permissions arrivent par un profil
de rôle (Stratégie créative, ou Production / QA) ou par un allow
explicite sur un membre. Le propriétaire les conserve : c'est lui qui
détient les marques.
agency.* : deux permissions internes à BoostEcom, qui ne sont pas
vendues aux marchands. C'est la seule famille exclue du
court-circuit propriétaire et absente du socle propriétaire. Il faut
les deux : retirer l'un sans l'autre reste sans effet, et sans le moindre
signal, car un propriétaire privé du court-circuit retomberait sur son
socle et récupérerait la permission.
Invitations
Une invitation est un enregistrement durable, pas un lien que l'on peut fabriquer soi-même.
- L'e-mail contient un jeton à usage unique ; seule son empreinte sha256 est conservée.
- Elle expire au bout de 7 jours.
- Vous pouvez la révoquer instantanément
(
DELETE /api/organizations/invite), ce qui rend le lien inutilisable. - Le jeton ne suffit pas. Pour accepter, il faut une session connectée dont l'adresse e-mail correspond à l'adresse invitée : un lien transféré ne sert donc à personne d'autre que son destinataire.
Réinviter la même adresse met à jour l'enregistrement existant (nouveau jeton, nouvelle échéance, état accepté ou révoqué remis à zéro) au lieu d'empiler les invitations.
La page d'arrivée est /invite, ouverte avec ?token=.
Ce que ce mécanisme remplace
L'ancien système reposait sur un lien ?org=&email= sans jeton.
N'importe qui pouvait en fabriquer un, et il n'existait aucun endpoint
d'acceptation.