[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"doc-\u002Fdocs\u002Fsecurite\u002Fmulti-tenant":3,"docs-nav-fr":332},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"body":10,"_type":326,"_id":327,"_source":328,"_file":329,"_stem":330,"_extension":331},"\u002Fdocs\u002Fsecurite\u002Fmulti-tenant","securite",false,"","Multi-tenant strict","Comment betool isole vos données, vos secrets et vos exécutions des autres organisations.",{"type":11,"children":12,"toc":317},"root",[13,21,28,50,77,90,132,138,143,152,172,178,203,209,228,234,239,272,277,283,288,312],{"type":14,"tag":15,"props":16,"children":17},"element","p",{},[18],{"type":19,"value":20},"text","L'isolation entre organisations est l'invariant structurant de betool. Voici comment il est appliqué, couche par couche.",{"type":14,"tag":22,"props":23,"children":25},"h2",{"id":24},"au-niveau-de-la-base-de-données",[26],{"type":19,"value":27},"Au niveau de la base de données",{"type":14,"tag":15,"props":29,"children":30},{},[31,33,40,42,48],{"type":19,"value":32},"Les tables métier portent une colonne ",{"type":14,"tag":34,"props":35,"children":37},"code",{"className":36},[],[38],{"type":19,"value":39},"org_id",{"type":19,"value":41}," qui rattache chaque ligne à son organisation (le plus souvent contrainte par clé étrangère vers ",{"type":14,"tag":34,"props":43,"children":45},{"className":44},[],[46],{"type":19,"value":47},"organisation(id)",{"type":19,"value":49},").",{"type":14,"tag":15,"props":51,"children":52},{},[53,55,61,63,68,70,75],{"type":19,"value":54},"Toutes les requêtes serveur passent par des ",{"type":14,"tag":56,"props":57,"children":58},"strong",{},[59],{"type":19,"value":60},"store methods",{"type":19,"value":62}," qui filtrent systématiquement par l'",{"type":14,"tag":34,"props":64,"children":66},{"className":65},[],[67],{"type":19,"value":39},{"type":19,"value":69}," de la session courante. Aucun chemin n'expose une requête arbitraire ; aucun client ne peut forcer un autre ",{"type":14,"tag":34,"props":71,"children":73},{"className":72},[],[74],{"type":19,"value":39},{"type":19,"value":76},".",{"type":14,"tag":15,"props":78,"children":79},{},[80,82,88],{"type":19,"value":81},"Pour les ressources rares mutualisables (typiquement les comptes LLM partagés au niveau plateforme), une colonne ",{"type":14,"tag":34,"props":83,"children":85},{"className":84},[],[86],{"type":19,"value":87},"is_shared BOOLEAN NOT NULL DEFAULT FALSE",{"type":19,"value":89}," permet l'opt-in explicite. Règles :",{"type":14,"tag":91,"props":92,"children":93},"ul",{},[94,107,120],{"type":14,"tag":95,"props":96,"children":97},"li",{},[98,100,106],{"type":19,"value":99},"Toute lecture autorisée à ",{"type":14,"tag":34,"props":101,"children":103},{"className":102},[],[104],{"type":19,"value":105},"WHERE org_id = %s OR is_shared = TRUE",{"type":19,"value":76},{"type":14,"tag":95,"props":108,"children":109},{},[110,112,118],{"type":19,"value":111},"Toute mutation d'une row ",{"type":14,"tag":34,"props":113,"children":115},{"className":114},[],[116],{"type":19,"value":117},"is_shared = TRUE",{"type":19,"value":119}," exige le rôle hyperadmin (opérateur plateforme).",{"type":14,"tag":95,"props":121,"children":122},{},[123,125,130],{"type":19,"value":124},"Toute mutation invalide le cache ",{"type":14,"tag":56,"props":126,"children":127},{},[128],{"type":19,"value":129},"globalement",{"type":19,"value":131}," — pas de divergence per-org.",{"type":14,"tag":22,"props":133,"children":135},{"id":134},"au-niveau-du-stockage-de-fichiers",[136],{"type":19,"value":137},"Au niveau du stockage de fichiers",{"type":14,"tag":15,"props":139,"children":140},{},[141],{"type":19,"value":142},"Les fichiers sont rangés dans un stockage objet (disque local ou bucket cloud selon le déploiement), sous un espace propre à chaque organisation :",{"type":14,"tag":144,"props":145,"children":147},"pre",{"code":146},"orgs\u002F\n└── \u003Corg_id>\u002F\n    ├── files\u002F\u003Ccanal>\u002F\u003Cexchange_id>\u002F\u003Cfichier>   ← fichiers reçus par les canaux\n    └── fixtures\u002F                               ← fixtures de benchmark\n",[148],{"type":14,"tag":34,"props":149,"children":150},{"__ignoreMap":7},[151],{"type":19,"value":146},{"type":14,"tag":15,"props":153,"children":154},{},[155,157,162,164,170],{"type":19,"value":156},"Les clés sont construites côté serveur (nom de fichier assaini, anti path-traversal). Toute lecture d'un fichier au nom d'un utilisateur, d'un tool ou d'un agent passe par une validation qui ",{"type":14,"tag":56,"props":158,"children":159},{},[160],{"type":19,"value":161},"refuse",{"type":19,"value":163}," une clé hors de l'espace ",{"type":14,"tag":34,"props":165,"children":167},{"className":166},[],[168],{"type":19,"value":169},"orgs\u002F\u003Corg_id>\u002Ffiles\u002F",{"type":19,"value":171}," de l'organisation courante.",{"type":14,"tag":22,"props":173,"children":175},{"id":174},"au-niveau-des-caches",[176],{"type":19,"value":177},"Au niveau des caches",{"type":14,"tag":15,"props":179,"children":180},{},[181,183,188,190,195,197,201],{"type":19,"value":182},"Les caches applicatifs (par exemple la résolution des providers LLM) sont ",{"type":14,"tag":56,"props":184,"children":185},{},[186],{"type":19,"value":187},"indexés par organisation",{"type":19,"value":189},". Quand une ressource ",{"type":14,"tag":34,"props":191,"children":193},{"className":192},[],[194],{"type":19,"value":117},{"type":19,"value":196}," est mutée, le cache est invalidé ",{"type":14,"tag":56,"props":198,"children":199},{},[200],{"type":19,"value":129},{"type":19,"value":202}," — pas de fenêtre où une org verrait l'ancienne valeur.",{"type":14,"tag":22,"props":204,"children":206},{"id":205},"au-niveau-des-secrets",[207],{"type":19,"value":208},"Au niveau des secrets",{"type":14,"tag":15,"props":210,"children":211},{},[212,214,219,221,227],{"type":19,"value":213},"Les credentials (clés LLM, tokens d'auth opérateur, secrets webhook) sont stockés côté serveur, rattachés à chaque org. Ils ne sont ",{"type":14,"tag":56,"props":215,"children":216},{},[217],{"type":19,"value":218},"jamais retournés en clair",{"type":19,"value":220}," par l'API : les routes GET n'indiquent que leur présence (par exemple ",{"type":14,"tag":34,"props":222,"children":224},{"className":223},[],[225],{"type":19,"value":226},"has_api_key: bool",{"type":19,"value":49},{"type":14,"tag":22,"props":229,"children":231},{"id":230},"au-niveau-de-lexécution",[232],{"type":19,"value":233},"Au niveau de l'exécution",{"type":14,"tag":15,"props":235,"children":236},{},[237],{"type":19,"value":238},"Quand un pipeline s'exécute :",{"type":14,"tag":91,"props":240,"children":241},{},[242,254,267],{"type":14,"tag":95,"props":243,"children":244},{},[245,247,252],{"type":19,"value":246},"Les opérateurs n'ont accès qu'aux ",{"type":14,"tag":56,"props":248,"children":249},{},[250],{"type":19,"value":251},"comptes externes",{"type":19,"value":253}," déclarés dans l'org.",{"type":14,"tag":95,"props":255,"children":256},{},[257,259,265],{"type":19,"value":258},"Les modèles LLM utilisés sont résolus dans l'ordre ",{"type":14,"tag":34,"props":260,"children":262},{"className":261},[],[263],{"type":19,"value":264},"own > shared (fallback auto)",{"type":19,"value":266}," — toujours.",{"type":14,"tag":95,"props":268,"children":269},{},[270],{"type":19,"value":271},"Les fichiers attachés ne sont lisibles que dans l'espace de stockage de l'org courante.",{"type":14,"tag":15,"props":273,"children":274},{},[275],{"type":19,"value":276},"Si un opérateur tente d'accéder à une ressource hors-périmètre, l'accès est refusé avec une erreur explicite — pas un timeout silencieux.",{"type":14,"tag":22,"props":278,"children":280},{"id":279},"test-pratique",[281],{"type":19,"value":282},"Test pratique",{"type":14,"tag":15,"props":284,"children":285},{},[286],{"type":19,"value":287},"À chaque ajout d'une nouvelle ressource mutualisable, l'équipe répond aux 4 questions :",{"type":14,"tag":289,"props":290,"children":291},"ol",{},[292,297,302,307],{"type":14,"tag":95,"props":293,"children":294},{},[295],{"type":19,"value":296},"Si une 2ᵉ org backoffice apparaît, mon code se comporte-t-il bien ?",{"type":14,"tag":95,"props":298,"children":299},{},[300],{"type":19,"value":301},"Si je modifie une row shared, tous les caches per-org sont-ils invalidés ?",{"type":14,"tag":95,"props":303,"children":304},{},[305],{"type":19,"value":306},"Mes secrets restent strictement serveur-side ?",{"type":14,"tag":95,"props":308,"children":309},{},[310],{"type":19,"value":311},"Mon GET permet-il aux pickers d'autres orgs de lister la ressource, sans exposer le secret ?",{"type":14,"tag":15,"props":313,"children":314},{},[315],{"type":19,"value":316},"Si une réponse est non, la ressource n'est pas livrée.",{"title":7,"searchDepth":318,"depth":318,"links":319},2,[320,321,322,323,324,325],{"id":24,"depth":318,"text":27},{"id":134,"depth":318,"text":137},{"id":174,"depth":318,"text":177},{"id":205,"depth":318,"text":208},{"id":230,"depth":318,"text":233},{"id":279,"depth":318,"text":282},"markdown","content:docs:5.securite:2.multi-tenant.md","content","docs\u002F5.securite\u002F2.multi-tenant.md","docs\u002F5.securite\u002F2.multi-tenant","md",[333],{"title":334,"_path":335,"children":336},"Docs","\u002Fdocs",[337,350,378,406,419,433,446,507],{"title":338,"_path":339,"children":340},"Démarrer","\u002Fdocs\u002Fdemarrer",[341,344,347],{"title":342,"_path":343},"Bienvenue","\u002Fdocs\u002Fdemarrer\u002Fbienvenue",{"title":345,"_path":346},"Créer un compte","\u002Fdocs\u002Fdemarrer\u002Fcreer-un-compte",{"title":348,"_path":349},"Brancher une clé LLM","\u002Fdocs\u002Fdemarrer\u002Fbrancher-llm",{"title":351,"_path":352,"children":353},"Canaux","\u002Fdocs\u002Fcanaux",[354,357,360,363,366,369,372,375],{"title":355,"_path":356},"Vue d'ensemble des canaux","\u002Fdocs\u002Fcanaux\u002Fvue-densemble",{"title":358,"_path":359},"Téléphonie temps réel","\u002Fdocs\u002Fcanaux\u002Ftelephone",{"title":361,"_path":362},"Email","\u002Fdocs\u002Fcanaux\u002Femail",{"title":364,"_path":365},"Chat widget web","\u002Fdocs\u002Fcanaux\u002Fchat-widget",{"title":367,"_path":368},"Webhook HTTP","\u002Fdocs\u002Fcanaux\u002Fwebhook",{"title":370,"_path":371},"Messageries (WhatsApp, Messenger, Telegram, Mattermost)","\u002Fdocs\u002Fcanaux\u002Fmessageries",{"title":373,"_path":374},"Meta Lead Ads","\u002Fdocs\u002Fcanaux\u002Ffacebook-leads",{"title":376,"_path":377},"Planification (cron)","\u002Fdocs\u002Fcanaux\u002Fschedule",{"title":379,"_path":380,"children":381},"Pipelines","\u002Fdocs\u002Fpipelines",[382,385,388,391,394,397,400,403],{"title":383,"_path":384},"L'éditeur visuel","\u002Fdocs\u002Fpipelines\u002Fediteur-visuel",{"title":386,"_path":387},"Agents IA","\u002Fdocs\u002Fpipelines\u002Fagents",{"title":389,"_path":390},"Opérateurs déterministes","\u002Fdocs\u002Fpipelines\u002Foperateurs",{"title":392,"_path":393},"Contrôle de flux","\u002Fdocs\u002Fpipelines\u002Fcontrole-flux",{"title":395,"_path":396},"Étapes de code","\u002Fdocs\u002Fpipelines\u002Fcode-step",{"title":398,"_path":399},"Sous-pipelines","\u002Fdocs\u002Fpipelines\u002Fsous-pipelines",{"title":401,"_path":402},"Actions sans code","\u002Fdocs\u002Fpipelines\u002Factions-no-code",{"title":404,"_path":405},"Base de connaissances","\u002Fdocs\u002Fpipelines\u002Fbase-de-connaissances",{"title":407,"_path":408,"children":409},"Supervision","\u002Fdocs\u002Fsupervision",[410,413,416],{"title":411,"_path":412},"Historique d'exécutions","\u002Fdocs\u002Fsupervision\u002Fexecutions",{"title":414,"_path":415},"Crédits & metering","\u002Fdocs\u002Fsupervision\u002Fcredits-metering",{"title":417,"_path":418},"Benchmarks","\u002Fdocs\u002Fsupervision\u002Fbenchmarks",{"title":420,"_path":421,"children":422},"Sécurité","\u002Fdocs\u002Fsecurite",[423,426,427,430],{"title":424,"_path":425},"Principes de sécurité","\u002Fdocs\u002Fsecurite\u002Fprincipes",{"title":8,"_path":4},{"title":428,"_path":429},"Audit RGPD & journal d'accès","\u002Fdocs\u002Fsecurite\u002Faudit-rgpd",{"title":431,"_path":432},"Déploiement souverain","\u002Fdocs\u002Fsecurite\u002Fdeploiement-souverain",{"title":434,"_path":435,"children":436},"Développeurs","\u002Fdocs\u002Fdeveloppeurs",[437,440,443],{"title":438,"_path":439},"API admin","\u002Fdocs\u002Fdeveloppeurs\u002Fapi-admin",{"title":441,"_path":442},"Webhooks sortants","\u002Fdocs\u002Fdeveloppeurs\u002Fwebhooks-sortants",{"title":444,"_path":445},"Piloter betool depuis Claude (MCP)","\u002Fdocs\u002Fdeveloppeurs\u002Fmcp",{"title":447,"_path":448,"children":449},"Intégrations","\u002Fdocs\u002Fintegrations",[450,453,456,459,462,465,468,471,474,477,480,483,486,489,492,495,498,501,504],{"title":451,"_path":452},"Vue d'ensemble des intégrations","\u002Fdocs\u002Fintegrations\u002Fvue-densemble",{"title":454,"_path":455},"Stripe","\u002Fdocs\u002Fintegrations\u002Fstripe",{"title":457,"_path":458},"GitHub","\u002Fdocs\u002Fintegrations\u002Fgithub",{"title":460,"_path":461},"Google","\u002Fdocs\u002Fintegrations\u002Fgoogle",{"title":463,"_path":464},"LinkedIn Ads","\u002Fdocs\u002Fintegrations\u002Flinkedin-ads",{"title":466,"_path":467},"Kavkom","\u002Fdocs\u002Fintegrations\u002Fkavkom",{"title":469,"_path":470},"Jira","\u002Fdocs\u002Fintegrations\u002Fjira",{"title":472,"_path":473},"Slack","\u002Fdocs\u002Fintegrations\u002Fslack",{"title":475,"_path":476},"SMS","\u002Fdocs\u002Fintegrations\u002Fsms",{"title":478,"_path":479},"Enable Banking (open banking)","\u002Fdocs\u002Fintegrations\u002Fenable-banking",{"title":481,"_path":482},"CRM, marketing & productivité","\u002Fdocs\u002Fintegrations\u002Fcrm-marketing",{"title":484,"_path":485},"HeyGen (vidéo)","\u002Fdocs\u002Fintegrations\u002Fheygen",{"title":487,"_path":488},"La Poste","\u002Fdocs\u002Fintegrations\u002Fla-poste",{"title":490,"_path":491},"CRM métier (beTool Application, Qhare)","\u002Fdocs\u002Fintegrations\u002Fcrm-metier",{"title":493,"_path":494},"Mitti (inspections terrain)","\u002Fdocs\u002Fintegrations\u002Fmitti",{"title":496,"_path":497},"Meta (Messenger, Pages, Meta Ads)","\u002Fdocs\u002Fintegrations\u002Fmeta",{"title":499,"_path":500},"Onoff Business (Beta)","\u002Fdocs\u002Fintegrations\u002Fonoff",{"title":502,"_path":503},"Smart Life \u002F Tuya (objets connectés)","\u002Fdocs\u002Fintegrations\u002Fsmart-life",{"title":505,"_path":506},"Produits beTool (Desktop, Kiosk, Terminal)","\u002Fdocs\u002Fintegrations\u002Fproduits-betool",{"title":508,"_path":509,"children":510},"Cas d'usage","\u002Fdocs\u002Fcas-usage",[511,514,517,520,523,526],{"title":512,"_path":513},"Agents métier types","\u002Fdocs\u002Fcas-usage\u002Fvue-densemble",{"title":515,"_path":516},"CFO IA","\u002Fdocs\u002Fcas-usage\u002Fcfo-ia",{"title":518,"_path":519},"COO IA","\u002Fdocs\u002Fcas-usage\u002Fcoo-ia",{"title":521,"_path":522},"CTO IA","\u002Fdocs\u002Fcas-usage\u002Fcto-ia",{"title":524,"_path":525},"Product Manager IA","\u002Fdocs\u002Fcas-usage\u002Fproduct-manager-ia",{"title":527,"_path":528},"Assistant personnel","\u002Fdocs\u002Fcas-usage\u002Fassistant-personnel"]