Cette page t'a-t-elle aidé ?
Cette page t'a-t-elle aidé ?
Guide
Tu es admin, tu veux donner accès à 3-15 personnes de ton équipe. Une seule UI, un seul email à saisir, Gilbert s'occupe du reste : magic link ou notif Postmark selon que l'invité a déjà un compte ou pas.
Dernière mise à jour : 28 mai 2026
Cette page s'adresse au lead IT qui vient de créer un workspace Gilbert et qui doit y ajouter son équipe, typiquement 3 à 15 personnes (commerciaux, gestionnaires, support, ops). Tu sais déjà ce qu'est un workspace (sinon, lis Workspaces avant) ; tu veux savoir comment leur donner accès proprement, qui peut quoi, et comment éviter de t'auto-éjecter de ton propre workspace.
Si tu cherches à dérouler le déploiement complet pour une équipe (workspace + intégrations + invités + onboarding), lis aussi le tutoriel déploiement équipe.
member, l'API renvoie 403 admin_required et l'UI cache le formulaire.admin ou member). Tu peux changer plus tard, mais autant le poser correctement dès l'invite./console/workspaces/<id>. Section Membres, formulaire Inviter un membre : un champ email, un select rôle, un bouton Inviter.POST /api/console/workspaces/[id]/invite) résout d'abord : est-ce que ce user existe déjà ? via la RPC find_user_by_email.auth.admin.inviteUserByEmail. Supabase envoie un magic link, avec pending_workspace_id et pending_workspace_role embarqués dans son user_metadata. L'UI affiche « Invitation envoyée par email. »gilbert.workspace_members, puis Postmark envoie une notification transactionnelle « X t'a ajouté au workspace Y » avec un bouton vers le workspace. L'UI affiche « Membre ajouté. Notification envoyée par email. »/auth/callback → vérification OTP. Si pending_workspace_id est dans son user_metadata, le callback appelle attachPendingWorkspaceMembership qui INSERT la membership et clear les fields pending_* (idempotent : re-cliquer le lien deux fois ne crée pas de doublon)./console/workspaces/<id>. Il voit le workspace dans son switcher en haut du chat. Il peut commencer à l'utiliser immédiatement.Pour scripter l'invite depuis ton terminal (test ou provisionning) :
curl -X POST https://gilbert.solveholding.com/api/console/workspaces/<workspace-id>/invite \
-H "content-type: application/json" \
-H "cookie: <ta-session-cookie>" \
-d '{ "email": "marie@acme-immo.fr", "role": "member" }'
# 202 Accepted (user inexistant, magic link envoyé)
# { "invited": true, "user_exists": false, "magic_link_sent": true }
# 201 Created (user déjà inscrit, membership ajoutée + notif Postmark)
# { "invited": true, "user_exists": true, "already_member": false,
# "notification_sent": true }Deux rôles seulement en V1, volontairement. Pas de rôles custom, pas de matrice de permissions à 12 colonnes.
| Capacité | member | admin |
|---|---|---|
| Chatter dans le workspace | Oui | Oui |
| Lire les données workspace (chat, routines, runs) | Oui | Oui |
Forwarder un mail (si can_forward) | Oui | Oui |
| Lister les autres membres | Oui | Oui |
| Inviter / retirer un membre | Non | Oui |
| Changer le rôle d'un membre | Non | Oui |
| Gérer les intégrations OAuth, clés LLM, billing | Non | Oui |
| Supprimer le workspace | Non | Oui |
Règle pratique : tu mets admin pour tout copilote IT qui doit pouvoir débloquer / re-provisionner / fix une intégration, et member pour tout le monde qui consomme le produit au quotidien.
Toujours dans /console/workspaces/<id>, le tableau Membres liste tous les utilisateurs du workspace avec leur email, leur rôle, leur date d'arrivée.
PATCH /api/console/workspaces/[id]/members/[userId]. Mise à jour instantanée, le membre voit la nouvelle capacité dès son prochain reload.DELETE /api/console/workspaces/[id]/members/[userId]. Il perd l'accès au workspace immédiatement (mais conserve son compte Gilbert et ses autres workspaces).marie.dupont@gmail.com mais bosse sous marie@acme-immo.fr, invite-la sous son email Gmail, sinon le magic link arrive sur la boîte pro mais ne matche aucun compte. Pour le forward de mails (Postmark inbound), le membre est reconnu depuis l'adresse de son compte ET depuis ses adresses de connexion vérifiées ; une adresse étrangère au compte se déclare dans forward_alias_email côté membership, voir Forward-to-Gilbert.201 avec notification_sent: false. À toi de prévenir le membre manuellement (Slack, SMS, peu importe).unique_violation Postgres (PK (workspace_id, user_id)) et renvoie already_member: true. L'UI affiche « Cette personne est déjà membre. » Aucune action côté DB, aucun mail envoyé.attachPendingWorkspaceMembership ignore les unique_violation et redirige quand même vers le workspace. Idempotent par design.La logique de rôles ne tient pas dans l'UI : tout est vérifié côté serveur via workspaceMemberGuard.ts, qui expose deux helpers que toutes les routes /api/console/workspaces/[id]/* doivent utiliser.
requireWorkspaceMember(workspaceId) : toute personne membre passe (admin ou member). Sinon 401 unauthorized (pas de session) ou 404 not_member_of_workspace (réponse opaque pour ne pas leaker l'existence du workspace).requireWorkspaceAdmin(workspaceId) : seul un admin passe. Un member du même workspace reçoit 403 admin_required.PATCH et DELETE sur /members/[userId] font un count exact des admins avant d'agir. Si l'opération laisserait count == 0, on renvoie 409 last_admin.workspace_id dans le schéma gilbert. Aucun moyen, depuis le workspace A, de lister ou de modifier les membres du workspace B, même si tu connais l'UUID du B.find_user_by_email) et la liste enrichie email-rôle (list_workspace_members_with_email) sont des fonctions SECURITY DEFINER qui appliquent leur propre check d'auth : pas d'accès direct à auth.users depuis le code applicatif.