Of een gebruiker iets wel of niet kan zien in Odoo wordt in twee lagen bepaald: toegangsrechten bepalen of ze een model überhaupt mogen aanraken, record rules bepalen welke rijen erin ze krijgen. Een verkoper die elke order in het bedrijf ziet, en een inkoper die tegen "u mag dit document niet openen" aanloopt, zijn hetzelfde probleem in verschillende lagen. Odoo bepaalt wat een gebruiker kan doen in twee lagen, en ze beantwoorden verschillende vragen. Toegangsrechten bepalen of een gebruiker een model überhaupt mag aanraken (mag je verkooporders lezen, ja of nee). Record rules bepalen welke rijen binnen dat model de gebruiker te zien krijgt (alleen je eigen orders, of allemaal). Als iets verborgen of te veel blootgelegd is, klopt een van deze twee lagen niet, en de oplossing is weten welke. Deze post legt beide lagen uit, waar groepen passen, hoe ze combineren, en hoe je het debugt in developer mode zonder te gokken.
Het probleemscenario
Je voegt een nieuwe gebruiker toe, zet ze in de Sales / User-groep, en ze bellen je. Ze kunnen de hele pipeline zien, de orders van elke klant, niet alleen hun eigen. Je verwachtte dat Odoo ze tot hun eigen team zou afbakenen. Niets wat je in het gebruikersformulier klikt lijkt het te veranderen.
Een week later is het andersom. Iemand bij de boekhouding klikt op een leveranciersfactuur en krijgt een harde fout: toegang geweigerd, u mag geen "Leveranciersfactuur"-records openen. Ze zitten in de juiste afdeling, ze deden dit gisteren nog, en nu kunnen ze het niet. Je staart naar de groepen van de gebruiker en die zien er prima uit. De waarheid is dat "ziet er prima uit" niet genoeg is, want wat een gebruiker ziet is het resultaat van twee aparte systemen die op elkaar gestapeld zijn, en je moet ze allebei lezen.
Waarom het gebeurt
Odoo verleent nooit rechtstreeks toegang aan een gebruiker. Het verleent toegang aan groepen, en een gebruiker erft alles van de groepen waarin hij zit. De app-pagina's die je in Instellingen ziet (Sales: User, Sales: Administrator, Accounting: Billing, enzovoort) zijn vriendelijke voorkanten voor die groepen. Achter elke groep zitten twee verschillende soorten rechten, en ze doen twee verschillende dingen.
Toegangsrechten zitten op modelniveau. Zij vormen de poort. Een toegangsrecht (technisch een ir.model.access-record) zegt: deze groep mag records van dit model lezen, schrijven, aanmaken of verwijderen. Het is een ja of nee per model, per bewerking. Als een groep geen toegangsrechtenregel voor een model heeft, kunnen de gebruikers daarin dat model helemaal niet aanraken. Dit is de laag die de harde "u mag dit document niet openen"-fout geeft. De poort zit dicht.
Record rules zitten op rijniveau. Zij vormen het filter. Een record rule (een ir.rule-record) draait pas nadat de poort open is. Hij zegt: van de records in dit model die je mag aanraken, mag je alleen die zien die aan deze voorwaarde voldoen. "Alleen orders waarbij jij de verkoper bent." "Alleen records in je eigen bedrijf." Een record rule opent nooit een poort die toegangsrechten hebben gesloten. Hij kan alleen versmallen wat erdoor komt. Dit is de laag die bepaalt of iemand zijn eigen orders ziet of die van iedereen.
Dus de twee beantwoorden verschillende vragen. Toegangsrechten: *mag deze gebruiker dit model aanraken?* Record rules: *welke rijen van dat model?* Bijna elke "waarom kan deze persoon X wel of niet zien" komt neer op uitvogelen welke van die twee vragen het verkeerde antwoord heeft.
Er is nog één ding dat mensen struikelen, en het is de belangrijkste regel in dit hele onderwerp: record rules combineren anders, afhankelijk van of ze globaal of aan een groep gebonden zijn.
- Een groepsregel is optellend. Als een gebruiker in twee groepen zit die elk een record rule toevoegen, ziet de gebruiker rijen die voldoen aan regel A *of* regel B. Een groepsregel toevoegen kan verruimen wat iemand ziet.
- Een globale regel (een regel zonder ingestelde groep) is aftrekkend. Hij geldt voor iedereen, en aan elke globale regel moet tegelijkertijd worden voldaan. Globale regels combineren met *en*. Een globale regel toevoegen beperkt altijd verder, en kan nooit verruimd worden door een groepsregel.
De samenvatting past op één regel: globale regels zijn *en*, groepsregels zijn *of*, en een groepsregel kan nooit ontsnappen aan een globale regel. Daarom kan een multi-company-beperking (een globale regel) niet ongedaan worden gemaakt door iemand aan een andere groep toe te voegen, en daarom kan iemand een extra groep geven hen ineens veel meer tonen dan je bedoelde.
De oplossing, in genummerde stappen
Zet eerst developer mode aan.
Je kunt security niet debuggen vanuit de normale Instellingen-schermen, ze zijn te versimpeld. Ga naar Instellingen, scroll naar de onderkant van de pagina Algemene instellingen, en klik op Developer mode activeren. Nu toont het Instellingen-menu een Technisch-sectie, en daar leven de echte toegangsrechten en record rules. Alles hieronder vereist dat developer mode aan staat.
Lees de groepen van de gebruiker, niet alleen de app-checkboxes.
Open Instellingen > Gebruikers & Bedrijven > Gebruikers, open de gebruiker, en kijk naar het tabblad Toegangsrechten. De app-dropdowns (Sales, Inventory, Accounting) zijn handig, maar ze verbergen de volledige lijst. Met developer mode aan krijg je ook een Groepen-weergave die elke technische groep toont die de gebruiker daadwerkelijk heeft, inclusief de groepen die indirect door andere apps zijn toegevoegd. Een gebruiker heeft bijna altijd meer groepen dan de app-dropdowns suggereren, omdat het selecteren van één app-groep stilletjes verschillende basisgroepen impliceert.
Bepaal welk symptoom je hebt.
Als de gebruiker een harde "u mag dit document niet openen"-fout krijgt, is het een toegangsrechten-probleem (modelniveau): een poort zit dicht. Als de gebruiker het model prima kan openen maar te veel of te weinig records ziet, is het een record-rule-probleem (rijniveau): het filter klopt niet. Benoem het symptoom voordat je iets aanraakt. De twee hebben verschillende oplossingen en je wilt geen toegangsrechten verruimen terwijl het echte probleem een record rule is.
Controleer bij een "geweigerd"-fout de toegangsrechten op dat model.
Ga naar Instellingen > Technisch > Beveiliging > Toegangsrechten. Filter op het model in de fout (bijvoorbeeld account.move voor facturen en boekingen). Je ziet één regel per groep, met checkboxes voor lezen, schrijven, aanmaken en verwijderen. Bevestig dat een van de groepen van de gebruiker de toegang heeft die nodig is voor de bewerking die ze deden. Leestoegang laat ze het openen; schrijven, aanmaken en verwijderen staan los. Een gebruiker die een boeking kan lezen maar niet kan boeken mist simpelweg misschien schrijfrechten op dat model via hun groep.
Controleer bij een "ziet te veel of te weinig"-probleem de record rules.
Ga naar Instellingen > Technisch > Beveiliging > Record Rules en filter op hetzelfde model. Kijk per regel naar drie dingen: het domein (de voorwaarde, geschreven als een Odoo-domein zoals [('user_id','=',user.id)]), of het globaal of aan een groep gebonden is, en op welke bewerkingen het van toepassing is (lezen, schrijven, aanmaken, verwijderen kunnen onafhankelijk worden ingesteld). Een regel die verkopers afbakent tot hun eigen orders is een groepsregel met een domein in de stijl van user_id = user.id. Als die ontbreekt, ziet iedereen alles. Als hij globaal is terwijl het een groepsregel zou moeten zijn, sluit hij iedereen te hard buiten.
Test als de gebruiker, ga niet uit van aannames.
Developer mode voegt in veel edities een Impersonate / Inloggen als-optie toe op het gebruikersformulier, en op zijn minst kun je een testgebruiker in precies die groepen aanmaken en inloggen. Reproduceer de exacte klik die misging. Securitybugs zijn berucht moeilijk om op papier te beredeneren vanwege de en/of-combinatie van regels, dus de snelste betrouwbare test is om daadwerkelijk die gebruiker te zijn en het te proberen.
Wijzig de groep, nooit de gebruiker, en test opnieuw.
Zodra je weet of het een toegangsrecht of een record rule is, los je het op op groeps- of regelniveau, niet door een eenmalig recht op één gebruiker te plakken. Test daarna opnieuw als de gebruiker. Als je toegangsrechten hebt verruimd, controleer dan dubbel dat je niet ook andere modellen hebt blootgelegd die dezelfde groep delen. Als je een record rule hebt gewijzigd, onthoud dan de en/of-regel van hierboven en controleer wie er nog meer in die groep zit.
Het stuk waar mensen over struikelen
Een paar dingen overkomen vrijwel iedereen
Toegangsrechten openen een model, record rules filteren de rijen. Ze zijn niet uitwisselbaar. Als iemand volledig geweigerd wordt, begin dan niet met het bewerken van record rules: de poort zit dicht op de toegangsrechtenlaag en geen enkele record rule opent die. Als iemand andermans data ziet, begin dan niet met het bewerken van toegangsrechten: de poort is prima en het filter ontbreekt. Deze twee door elkaar halen is verreweg de grootste tijdvreter in Odoo-security.
Globale regels winnen, altijd. Een regel zonder ingestelde groep geldt voor iedereen en combineert met elke andere globale regel via *en*. Het klassieke voorbeeld is multi-company: de "records van je eigen bedrijf"-regel is globaal, dus je kunt die niet ongedaan maken door een gebruiker aan een andere groep toe te voegen. Als een record koppig verborgen blijft, ongeacht welke groepen je toevoegt, verdenk dan een globale regel, vooral een multi-company-regel.
Groepsregels tellen op, wat onopgemerkt te veel kan blootleggen. Omdat groepsregels met *of* combineren, kan het toevoegen van een gebruiker aan een extra groep om één scherm te repareren stilletjes verruimen wat ze zien op een ander model dat diezelfde groep ook raakt. Vraag je altijd af wat een groep nog meer toekent voordat je iemand eraan toevoegt. "Ik heb ze gewoon nog één groep gegeven" is hoe data uiteindelijk te veel wordt blootgelegd.
De app-checkboxes verbergen geïmpliceerde groepen. Het selecteren van "Sales: Administrator" voegt niet alleen die ene groep toe, het impliceert de gebruikersgroep eronder en vaak ook basisgroepen. Zo kan een gebruiker eindigen met toegang die je nooit bewust hebt gegeven. Lees bij twijfel de technische groepenlijst in developer mode, niet de vriendelijke app-dropdown.
De superuser omzeilt alles, dus is het een slechte test. Het Administrator- / superuser-account negeert record rules en de meeste toegangscontroles van nature. Als je een rechtenprobleem als admin test werkt het altijd, wat je niets vertelt. Test als de getroffen gebruiker of een kopie daarvan, nooit als admin.
Lezen, schrijven, aanmaken en verwijderen staan los, op beide lagen. Een gebruiker mag misschien facturen lezen maar niet aanmaken, of een record zien onder een leesregel maar door een andere schrijfregel geblokkeerd worden van bewerken. Als iets half werkt (ik kan het openen maar niet opslaan), controleer dan de specifieke bewerking, niet alleen "toegang" in het algemeen.
Verborgen menu's hielden op een securitygrens te zijn op de dag dat AI verbinding maakte. Soms heeft een gebruiker lees- en schrijfrechten op een model nodig puur zodat hun workflow niet crasht, terwijl je ze de data liever niet zou geven. De klassieke oplossing is het menu verbergen: de rechten blijven, de schermen verdwijnen, en jarenlang hield dat prima stand. AI-assistenten en MCP-integraties braken de aanname eronder. Een assistent die als die gebruiker handelt controleert de toegangsrechten, niet de menu's, dus die leest vrolijk alles wat het verborgen menu afdekte. Als AI-tools verbinding maken met je Odoo, doe dan de echte scoping per model, beslist als "mag zien" en "mag schrijven" in groepen en record rules, en behandel een verborgen menu als cosmetica.
Snelle checklist
- Developer mode staat aan voordat je iets debugt dat met security te maken heeft.
- Je benoemde het symptoom: harde "toegang geweigerd"-fout (toegangsrechten) versus ziet te veel of te weinig (record rules).
- Je las de volledige technische groepen van de gebruiker, niet alleen de app-dropdowns.
- Bij een geweigerde foutmelding controleerde je de Toegangsrechten op het exacte model voor de exacte bewerking.
- Bij een zichtbaarheidsprobleem controleerde je de Record Rules: domein, globaal versus groep, en welke bewerkingen.
- Je herinnerde je de regel: globale regels combineren met *en* (beperken), groepsregels met *of* (verruimen), en een groepsregel kan niet ontsnappen aan een globale regel.
- Je testte als de getroffen gebruiker (of een kopie), nooit als admin.
- Je loste het op groeps- of regelniveau op en testte opnieuw, en controleerde daarna wie die wijziging nog meer raakt.
Hoe de twee lagen daadwerkelijk stapelen
Lees het als twee poorten op een rij. Eerste poort, toegangsrechten: staat een groep waarin deze gebruiker zit deze bewerking op dit model toe? Zo nee, dan wordt de gebruiker ronduit geweigerd, met de harde fout, en draait er niets verder. Zo ja, dan gaat het verzoek door naar de tweede poort. Tweede poort, record rules: van de records in dit model, welke voldoen aan de regels die voor deze gebruiker gelden? Aan alle globale regels moet worden voldaan (ze combineren met *en*), en aan minstens één groepsregel moet worden voldaan als er groepsregels bestaan (ze combineren met *of*). Alleen de rijen die beide poorten overleven komen terug. Dus een gebruiker kan perfecte toegangsrechten hebben en toch niets zien, omdat een record rule alles eruit filterde, en een gebruiker kan een ruime record rule hebben en toch geweigerd worden, omdat de toegangsrechten-poort dicht zat. Lees ze altijd in die volgorde: poort eerst, filter daarna.
FAQ
Wat is het verschil tussen toegangsrechten en record rules in Odoo?
Toegangsrechten werken op modelniveau en bepalen of een gebruiker een heel model überhaupt mag lezen, schrijven, aanmaken of verwijderen. Record rules werken op rijniveau en bepalen welke records binnen dat model de gebruiker mag zien, bijvoorbeeld alleen zijn eigen orders. Toegangsrechten zijn de poort; record rules zijn het filter dat draait nadat de poort open is. Een record rule kan nooit toegang verlenen die toegangsrechten weigeren.
Waarom ziet een gebruiker alle records terwijl ze alleen hun eigen zouden moeten zien in Odoo?
Omdat de record rule die ze afbakent ontbreekt, uitgeschakeld is, of aan de verkeerde groep hangt. Toegangsrechten openden het model, maar geen filter op rijniveau versmalt het. Ga naar Instellingen > Technisch > Beveiliging > Record Rules (developer mode aan), filter op het model, en zoek naar een groepsregel met een domein zoals [('user_id','=',user.id)]. Als die ontbreekt, ziet iedereen met modeltoegang alles.
Waarom krijgt een gebruiker "u mag dit document niet openen" in Odoo?
Omdat de toegangsrechten-poort dicht zit voor dat model en die bewerking. Geen van de groepen van de gebruiker verleent het lezen, schrijven, aanmaken of verwijderen dat de actie nodig heeft. Dit is een probleem op modelniveau, niet op record-rule-niveau, dus record rules bewerken helpt niet. Controleer Instellingen > Technisch > Beveiliging > Toegangsrechten, filter op het model in de fout, en bevestig dat een van de groepen van de gebruiker de juiste bewerking aangevinkt heeft.
Hoe verschillen globale record rules van groeps-record rules in Odoo?
Globale regels (geen groep ingesteld) gelden voor iedereen en combineren met *en*: aan elke globale regel moet worden voldaan, dus ze beperken alleen ooit de toegang, en een groepsregel kan ze niet overrulen. Groepsregels combineren met *of*: als een gebruiker in meerdere groepen met regels zit, is het voldoen aan één ervan genoeg, dus een groep toevoegen kan verruimen wat ze zien. Kortom, globale regels trekken af en groepsregels tellen op, binnen de grenzen die de globale regels toestaan.
Hoe debug ik Odoo-rechten in developer mode?
Zet developer mode aan in Instellingen, open dan Instellingen > Technisch > Beveiliging, wat Toegangsrechten en Record Rules blootlegt. Lees de volledige technische groepen van de getroffen gebruiker, bepaal of het symptoom een harde "toegang geweigerd"-fout is (toegangsrechten) of een zichtbaarheidsprobleem (record rules), controleer de bijbehorende laag voor dat exacte model en die bewerking, en test ten slotte als die gebruiker of een kopie daarvan, nooit als de admin, want de superuser omzeilt deze controles.