[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"doc-\u002Fen\u002Fdocs\u002Fsecurite\u002Fmulti-tenant":3,"docs-nav-en":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},"\u002Fen\u002Fdocs\u002Fsecurite\u002Fmulti-tenant","securite",false,"","Strict multi-tenancy","How betool isolates your data, secrets and executions from other 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","Isolation between organisations is the foundational invariant of betool. Here is how it is enforced, layer by layer.",{"type":14,"tag":22,"props":23,"children":25},"h2",{"id":24},"at-the-database-level",[26],{"type":19,"value":27},"At the database level",{"type":14,"tag":15,"props":29,"children":30},{},[31,33,40,42,48],{"type":19,"value":32},"Business tables carry an ",{"type":14,"tag":34,"props":35,"children":37},"code",{"className":36},[],[38],{"type":19,"value":39},"org_id",{"type":19,"value":41}," column that ties each row to its organisation (most often constrained by a foreign key to ",{"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},"All server-side queries go through ",{"type":14,"tag":56,"props":57,"children":58},"strong",{},[59],{"type":19,"value":60},"store methods",{"type":19,"value":62}," that systematically filter by the ",{"type":14,"tag":34,"props":64,"children":66},{"className":65},[],[67],{"type":19,"value":39},{"type":19,"value":69}," of the current session. No code path exposes an arbitrary query; no client can force a different ",{"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},"For the small number of resources that can be shared across organisations (typically platform-level shared LLM accounts), an ",{"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}," column enables explicit opt-in. Rules:",{"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},"Any read is authorised with ",{"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},"Any mutation of an ",{"type":14,"tag":34,"props":113,"children":115},{"className":114},[],[116],{"type":19,"value":117},"is_shared = TRUE",{"type":19,"value":119}," row requires the hyperadmin role (platform operator).",{"type":14,"tag":95,"props":121,"children":122},{},[123,125,130],{"type":19,"value":124},"Any mutation invalidates the cache ",{"type":14,"tag":56,"props":126,"children":127},{},[128],{"type":19,"value":129},"globally",{"type":19,"value":131}," — no per-org divergence.",{"type":14,"tag":22,"props":133,"children":135},{"id":134},"at-the-file-storage-level",[136],{"type":19,"value":137},"At the file storage level",{"type":14,"tag":15,"props":139,"children":140},{},[141],{"type":19,"value":142},"Files are kept in object storage (local disk or cloud bucket depending on the deployment), under a space dedicated to each organisation:",{"type":14,"tag":144,"props":145,"children":147},"pre",{"code":146},"orgs\u002F\n└── \u003Corg_id>\u002F\n    ├── files\u002F\u003Cchannel>\u002F\u003Cexchange_id>\u002F\u003Cfile>    ← files received by the channels\n    └── fixtures\u002F                               ← benchmark fixtures\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},"Keys are built server-side (sanitised file name, anti path-traversal). Any read of a file on behalf of a user, a tool or an agent goes through a validation that ",{"type":14,"tag":56,"props":158,"children":159},{},[160],{"type":19,"value":161},"refuses",{"type":19,"value":163}," a key outside the current organisation's ",{"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}," space.",{"type":14,"tag":22,"props":173,"children":175},{"id":174},"at-the-cache-level",[176],{"type":19,"value":177},"At the cache level",{"type":14,"tag":15,"props":179,"children":180},{},[181,183,188,190,195,197,201],{"type":19,"value":182},"Application caches (for example LLM provider resolution) are ",{"type":14,"tag":56,"props":184,"children":185},{},[186],{"type":19,"value":187},"keyed by organisation",{"type":19,"value":189},". When an ",{"type":14,"tag":34,"props":191,"children":193},{"className":192},[],[194],{"type":19,"value":117},{"type":19,"value":196}," resource is mutated, the cache is invalidated ",{"type":14,"tag":56,"props":198,"children":199},{},[200],{"type":19,"value":129},{"type":19,"value":202}," — there is no window during which an org could see a stale value.",{"type":14,"tag":22,"props":204,"children":206},{"id":205},"at-the-secrets-level",[207],{"type":19,"value":208},"At the secrets level",{"type":14,"tag":15,"props":210,"children":211},{},[212,214,219,221,227],{"type":19,"value":213},"Credentials (LLM keys, operator auth tokens, webhook secrets) are stored server-side, attached to each org. They are ",{"type":14,"tag":56,"props":215,"children":216},{},[217],{"type":19,"value":218},"never returned in plaintext",{"type":19,"value":220}," by the API: GET routes only indicate whether they are present (for example ",{"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},"at-the-execution-level",[232],{"type":19,"value":233},"At the execution level",{"type":14,"tag":15,"props":235,"children":236},{},[237],{"type":19,"value":238},"When a pipeline runs:",{"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},"Operators only have access to the ",{"type":14,"tag":56,"props":248,"children":249},{},[250],{"type":19,"value":251},"external accounts",{"type":19,"value":253}," declared within their org.",{"type":14,"tag":95,"props":255,"children":256},{},[257,259,265],{"type":19,"value":258},"LLM models are resolved in the order ",{"type":14,"tag":34,"props":260,"children":262},{"className":261},[],[263],{"type":19,"value":264},"own > shared (auto fallback)",{"type":19,"value":266}," — always.",{"type":14,"tag":95,"props":268,"children":269},{},[270],{"type":19,"value":271},"Attached files are only readable within the current org's storage space.",{"type":14,"tag":15,"props":273,"children":274},{},[275],{"type":19,"value":276},"If an operator attempts to access a resource outside its scope, the access is refused with an explicit error — not a silent timeout.",{"type":14,"tag":22,"props":278,"children":280},{"id":279},"practical-checklist",[281],{"type":19,"value":282},"Practical checklist",{"type":14,"tag":15,"props":284,"children":285},{},[286],{"type":19,"value":287},"Whenever a new shareable resource is added, the team answers these 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},"If a second backoffice org appears, does my code behave correctly?",{"type":14,"tag":95,"props":298,"children":299},{},[300],{"type":19,"value":301},"If I mutate a shared row, are all per-org caches invalidated?",{"type":14,"tag":95,"props":303,"children":304},{},[305],{"type":19,"value":306},"Do my secrets remain strictly server-side?",{"type":14,"tag":95,"props":308,"children":309},{},[310],{"type":19,"value":311},"Does my GET allow other orgs' pickers to list the resource without exposing the secret?",{"type":14,"tag":15,"props":313,"children":314},{},[315],{"type":19,"value":316},"If any answer is no, the resource is not shipped.",{"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:en:docs:5.securite:2.multi-tenant.md","content","en\u002Fdocs\u002F5.securite\u002F2.multi-tenant.md","en\u002Fdocs\u002F5.securite\u002F2.multi-tenant","md",[333],{"title":334,"_path":335,"children":336},"En","\u002Fen",[337],{"title":338,"_path":339,"children":340},"Docs","\u002Fen\u002Fdocs",[341,354,382,410,423,437,450,511],{"title":342,"_path":343,"children":344},"Getting started","\u002Fen\u002Fdocs\u002Fdemarrer",[345,348,351],{"title":346,"_path":347},"Welcome","\u002Fen\u002Fdocs\u002Fdemarrer\u002Fbienvenue",{"title":349,"_path":350},"Create an account","\u002Fen\u002Fdocs\u002Fdemarrer\u002Fcreer-un-compte",{"title":352,"_path":353},"Connect an LLM key","\u002Fen\u002Fdocs\u002Fdemarrer\u002Fbrancher-llm",{"title":355,"_path":356,"children":357},"Channels","\u002Fen\u002Fdocs\u002Fcanaux",[358,361,364,367,370,373,376,379],{"title":359,"_path":360},"Channels overview","\u002Fen\u002Fdocs\u002Fcanaux\u002Fvue-densemble",{"title":362,"_path":363},"Real-time telephony","\u002Fen\u002Fdocs\u002Fcanaux\u002Ftelephone",{"title":365,"_path":366},"Email","\u002Fen\u002Fdocs\u002Fcanaux\u002Femail",{"title":368,"_path":369},"Web chat widget","\u002Fen\u002Fdocs\u002Fcanaux\u002Fchat-widget",{"title":371,"_path":372},"HTTP Webhook","\u002Fen\u002Fdocs\u002Fcanaux\u002Fwebhook",{"title":374,"_path":375},"Messaging (WhatsApp, Messenger, Telegram, Mattermost)","\u002Fen\u002Fdocs\u002Fcanaux\u002Fmessageries",{"title":377,"_path":378},"Meta Lead Ads","\u002Fen\u002Fdocs\u002Fcanaux\u002Ffacebook-leads",{"title":380,"_path":381},"Schedule (cron)","\u002Fen\u002Fdocs\u002Fcanaux\u002Fschedule",{"title":383,"_path":384,"children":385},"Pipelines","\u002Fen\u002Fdocs\u002Fpipelines",[386,389,392,395,398,401,404,407],{"title":387,"_path":388},"The Visual Editor","\u002Fen\u002Fdocs\u002Fpipelines\u002Fediteur-visuel",{"title":390,"_path":391},"AI Agents","\u002Fen\u002Fdocs\u002Fpipelines\u002Fagents",{"title":393,"_path":394},"Deterministic Operators","\u002Fen\u002Fdocs\u002Fpipelines\u002Foperateurs",{"title":396,"_path":397},"Flow Control","\u002Fen\u002Fdocs\u002Fpipelines\u002Fcontrole-flux",{"title":399,"_path":400},"Code Steps","\u002Fen\u002Fdocs\u002Fpipelines\u002Fcode-step",{"title":402,"_path":403},"Sub-pipelines","\u002Fen\u002Fdocs\u002Fpipelines\u002Fsous-pipelines",{"title":405,"_path":406},"No-code actions","\u002Fen\u002Fdocs\u002Fpipelines\u002Factions-no-code",{"title":408,"_path":409},"Knowledge base","\u002Fen\u002Fdocs\u002Fpipelines\u002Fbase-de-connaissances",{"title":411,"_path":412,"children":413},"Supervision","\u002Fen\u002Fdocs\u002Fsupervision",[414,417,420],{"title":415,"_path":416},"Execution History","\u002Fen\u002Fdocs\u002Fsupervision\u002Fexecutions",{"title":418,"_path":419},"Credits & Metering","\u002Fen\u002Fdocs\u002Fsupervision\u002Fcredits-metering",{"title":421,"_path":422},"Benchmarks","\u002Fen\u002Fdocs\u002Fsupervision\u002Fbenchmarks",{"title":424,"_path":425,"children":426},"Security","\u002Fen\u002Fdocs\u002Fsecurite",[427,430,431,434],{"title":428,"_path":429},"Security principles","\u002Fen\u002Fdocs\u002Fsecurite\u002Fprincipes",{"title":8,"_path":4},{"title":432,"_path":433},"GDPR audit & access log","\u002Fen\u002Fdocs\u002Fsecurite\u002Faudit-rgpd",{"title":435,"_path":436},"Sovereign deployment","\u002Fen\u002Fdocs\u002Fsecurite\u002Fdeploiement-souverain",{"title":438,"_path":439,"children":440},"Developers","\u002Fen\u002Fdocs\u002Fdeveloppeurs",[441,444,447],{"title":442,"_path":443},"Admin API","\u002Fen\u002Fdocs\u002Fdeveloppeurs\u002Fapi-admin",{"title":445,"_path":446},"Outbound webhooks","\u002Fen\u002Fdocs\u002Fdeveloppeurs\u002Fwebhooks-sortants",{"title":448,"_path":449},"Drive betool from Claude (MCP)","\u002Fen\u002Fdocs\u002Fdeveloppeurs\u002Fmcp",{"title":451,"_path":452,"children":453},"Integrations","\u002Fen\u002Fdocs\u002Fintegrations",[454,457,460,463,466,469,472,475,478,481,484,487,490,493,496,499,502,505,508],{"title":455,"_path":456},"Integrations overview","\u002Fen\u002Fdocs\u002Fintegrations\u002Fvue-densemble",{"title":458,"_path":459},"Stripe","\u002Fen\u002Fdocs\u002Fintegrations\u002Fstripe",{"title":461,"_path":462},"GitHub","\u002Fen\u002Fdocs\u002Fintegrations\u002Fgithub",{"title":464,"_path":465},"Google","\u002Fen\u002Fdocs\u002Fintegrations\u002Fgoogle",{"title":467,"_path":468},"LinkedIn Ads","\u002Fen\u002Fdocs\u002Fintegrations\u002Flinkedin-ads",{"title":470,"_path":471},"Kavkom","\u002Fen\u002Fdocs\u002Fintegrations\u002Fkavkom",{"title":473,"_path":474},"Jira","\u002Fen\u002Fdocs\u002Fintegrations\u002Fjira",{"title":476,"_path":477},"Slack","\u002Fen\u002Fdocs\u002Fintegrations\u002Fslack",{"title":479,"_path":480},"SMS","\u002Fen\u002Fdocs\u002Fintegrations\u002Fsms",{"title":482,"_path":483},"Enable Banking (open banking)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fenable-banking",{"title":485,"_path":486},"CRM, marketing & productivity","\u002Fen\u002Fdocs\u002Fintegrations\u002Fcrm-marketing",{"title":488,"_path":489},"HeyGen (video)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fheygen",{"title":491,"_path":492},"La Poste","\u002Fen\u002Fdocs\u002Fintegrations\u002Fla-poste",{"title":494,"_path":495},"Industry CRM (beTool Application, Qhare)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fcrm-metier",{"title":497,"_path":498},"Mitti (field inspections)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fmitti",{"title":500,"_path":501},"Meta (Messenger, Pages, Meta Ads)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fmeta",{"title":503,"_path":504},"Onoff Business (Beta)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fonoff",{"title":506,"_path":507},"Smart Life \u002F Tuya (connected devices)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fsmart-life",{"title":509,"_path":510},"beTool products (Desktop, Kiosk, Terminal)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fproduits-betool",{"title":512,"_path":513,"children":514},"Use cases","\u002Fen\u002Fdocs\u002Fcas-usage",[515,518,521,524,527,530],{"title":516,"_path":517},"Typical business agents","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fvue-densemble",{"title":519,"_path":520},"CFO IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fcfo-ia",{"title":522,"_path":523},"COO IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fcoo-ia",{"title":525,"_path":526},"CTO IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fcto-ia",{"title":528,"_path":529},"Product Manager IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fproduct-manager-ia",{"title":531,"_path":532},"Personal assistant","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fassistant-personnel"]