Iemand in je team opent Odoo en krijgt 'Access Denied'. Of ze kunnen een menu niet vinden dat een collega elke dag gebruikt. Het voelt als een bug, maar dat is het bijna nooit. Het is het rechtensysteem van Odoo dat precies doet wat je het hebt opgedragen.
Het lastige is dat het scherm waarop je toegang uitdeelt het meeste verbergt van wat er echt gebeurt. Je kiest een waarde uit een dropdown, en Odoo herschrijft daaronder stilletjes een web van groepen, regels en filters. Zodra je dat web kunt zien, is toegang geen giswerk meer. Deze gids loopt het hele pad af, van het scherm dat je aanklikt tot de tabellen erachter, voor standaard Odoo, het nieuwe privilege-model in Odoo 19, de optionele User Roles-module, en toegang via API en AI. Elke id en veldnaam hieronder is gecontroleerd tegen een live Odoo 19-database, dus niets is verzonnen.
De korte versie
- Odoo controleert vier lagen, in volgorde: groepen, dan access rights, dan record rules, dan veldrechten. Eén 'nee' stopt de actie.
- Het gebruikersscherm zet maar één ding: in welke groepen de gebruiker zit. Al het andere hangt aan die groepen.
- De per-app dropdowns zijn 'privileges', een nieuw model in Odoo 19. Een privilege is alleen de dropdown. De echte rechten zitten op de groepen erin.
- User Roles (herbruikbare rollen) is een optionele module, geen standaard Odoo.
- Een API-key of AI-login draait als een gebruiker, en volgt dus precies dezelfde vier lagen.
De vier lagen
Voor elke actie, een record lezen, wijzigen, verwijderen, doet Odoo vier controles in volgorde. Zegt één controle nee, dan stopt de actie en krijgt de gebruiker een foutmelding.
- Groepen (
res.groups): in welke groepen zit deze gebruiker? Dit is het enige dat je op het gebruikersscherm instelt. - Access rights (
ir.model.access): mogen die groepen dit soort record überhaupt aanraken? Lezen, schrijven, aanmaken, verwijderen. - Record rules (
ir.rule): welke specifieke records binnen dat soort? Een filter, bijvoorbeeld 'alleen je eigen orders'. - Veldrechten (het
groups-attribuut op een veld): welke velden op het record zijn zichtbaar of bewerkbaar?
Eén regel bindt het geheel en zet bijna iedereen op het verkeerde been: rechten tellen alleen op. Je haalt een recht niet weg door iemand een extra groep te geven. Ziet een gebruiker te veel, haal dan een groep weg, voeg nooit een beperkende groep toe.
Het scherm dat je echt gebruikt
Open een gebruiker onder Instellingen, Gebruikers, en ga naar de tab Toegangsrechten. Bovenaan zie je een Rol-keuze, daaronder grijze kopjes als Sales en Accounting, elk met een dropdown.

Dit is het deel dat de meeste verwarring wegneemt. Alles op dit scherm doet één ding: het bepaalt in welke groepen de gebruiker zit. De Rol-keuze, elke dropdown, elk vinkje verderop, ze schrijven allemaal naar één plek: de groepenlijst van de gebruiker. Geen ervan is een aparte instelling met een eigen kolom in de database.
Dit scherm is dus laag 1, en alleen laag 1. Laag 2, 3 en 4 zie je hier nooit. Die komen mee met de groepen die je kiest, en zijn lang geleden ingesteld door Odoo en door elke app. Je vindt ze pas als je de ontwikkelaarsmodus aanzet en de technische instellingen opent.
Wat 'Rol: User / Administrator' echt doet
De Rol-keuze is het basistype van de gebruiker. In de database is dat het veld res.users.role, een gewone dropdown met twee opties, User en Administrator, en het bewaart zelf niets (Odoo berekent het ter plekke). Een waarde kiezen zet de gebruiker in één basisgroep: User zet de groep Role / User, Administrator zet de groep Role / Administrator.
Het woord Administrator is misleidend, dus wees er precies over. Het betekent 'mag de Instellingen openen en de apps configureren'. Het betekent niet 'beheerder van elke app'. Of iemand alle verkooporders of elk project mag zien, wordt lager bepaald, in de per-app dropdowns. In onze testdatabase trekt de Administrator-basisgroep stil een bundel technische groepen mee en is die gekoppeld aan 127 access-right-records voor configuratiemodellen. Geen daarvan raakt bedrijfsdata als orders of facturen.
Privileges: de per-app dropdowns (nieuw in Odoo 19)
Elk grijs kopje bevat een of meer dropdowns, zoals Sales of Project. In Odoo 19 is zo'n dropdown een privilege, opgeslagen in een nieuw model, res.groups.privilege.

Lees een privilege als een vraag met een vaste lijst antwoorden. Neem Sales:

- De naam is 'Sales', het label naast de dropdown.
- De category wijst naar het grijze kopje, opgeslagen als
ir.module.category. - De groepen zijn de opties erin: User: Own Documents Only, User: All Documents, Administrator.
- De placeholder is de lege optie, meestal 'No'.
Het scherm heeft dus drie niveaus, geen twee. Het grijze kopje is een category. Daaronder zitten een of meer privileges (de dropdowns). Binnen elke privilege zitten de groepen (de opties). Een category bevat privileges, een privilege bevat groepen.
Waarom is Sales één dropdown en geen drie vinkjes? Omdat de opties gerangschikt zijn en elkaar uitsluiten. Administrator bevat al All Documents, dat weer Own Documents bevat. Je kiest een niveau op een ladder, geen losse vinkjes.
Wat je kiest is een groep, niet de privilege
Dit beantwoordt een vraag die veel mensen op het verkeerde been zet: als de dropdown een privilege is, waarom is de privilege dan niet aan de gebruiker gekoppeld?
Omdat wat je echt kiest één optie is, en elke optie een groep. Alleen de groep wordt bij de gebruiker opgeslagen. De privilege is slechts de verpakking. Als Odoo 'deze gebruiker heeft de Sales-privilege' zou opslaan, zou het niet weten of dat Own, All of Administrator betekent, en de privilege draagt sowieso geen eigen rechten. Dus de gebruiker linkt aan de specifieke groep (het antwoord), nooit aan de privilege (de vraag).
Binnen een groep: het scharnier van het systeem
Een groep is waar alles samenkomt. Op zichzelf geeft die niets. Het is een ankerpunt waar de echte regels naar wijzen. Open een groep in ontwikkelaarsmodus (Instellingen, Gebruikers en Bedrijven, Groepen) en de tabs vertellen het verhaal.
Access rights: wat de groep mag doen
De tab Access Rights toont één rij per soort record, met vier vinkjes: lezen, schrijven, aanmaken, verwijderen. Dit is laag 2.
Heeft een groep geen rij die minstens lezen geeft op een model, dan kunnen de leden dat model helemaal niet openen. Dit is de meest voorkomende oorzaak van 'Access Denied' bij een nieuwe gebruiker: ze missen simpelweg de groep die de toegang draagt.
Inherited: implied, implying en disjoint
De tab Inherited is waar de rangorde en de exclusiviteit leven. Er zijn drie lijsten, en alle drie wijzen terug naar andere groepen.

- Implied Groups zijn de groepen die deze groep gratis meegeeft. Geef iemand deze groep en ze krijgen ook alle implied groepen. Dit is waarom Administrator een bundel meetrekt, en waarom een dropdown een ladder is waar hoger het lagere bevat.
- Implying Groups zijn de omgekeerde kant: de groepen die deze insluiten. Dezelfde link, andersom gelezen. Voor Own Documents is de implying group All Documents, want All staat boven Own.
- Disjoint Groups zijn de groepen die je niet tegelijk kunt hebben. Ziet Odoo een set gerangschikte, disjoint groepen, dan toont het die als één dropdown in plaats van losse vinkjes. Daarom is Sales één keuzelijst.
Record rules: welke records
De tab Record Rules versmalt de toegang van 'dit hele model' naar specifieke rijen, met een domein-filter. Dit is laag 3.

Voor de Own Documents-verkoper lezen de regels als [('salesman_id', '=', user.id)], oftewel 'alleen records waar jij de verkoper bent'. Hun manager zit in een groep met een bredere regel en ziet alles.
Hetzelfde, gezien vanaf het model
Je kunt laag 2 en 3 ook van de andere kant lezen, vanaf het soort record in plaats van de groep. Open in ontwikkelaarsmodus een model onder Instellingen, Technisch, Modellen, bijvoorbeeld Contact (res.partner).
Access rights per model
De tab Access Rights op het model toont dezelfde rijen, nu gegroepeerd per groep waartoe ze horen. Deze weergave beantwoordt 'wie mag een contact bewerken?' in plaats van 'wat mag deze groep?'
Veldrechten: welke velden
De tab Fields is laag 4. Elk veld kan beperkt worden tot bepaalde groepen, zodat het voor de rest verborgen of alleen-lezen is.

Zo houdt Odoo een kostprijs of een salarisveld uit het zicht voor de meeste mensen, terwijl een manager het wel ziet. Zelfde record, een paar regels weggelakt.
Record rules: global versus group
De tab Record Rules op het model toont een verschil dat er echt toe doet.

- Een globale regel heeft geen groep. Die geldt voor iedereen en kan door geen enkele andere regel worden versoepeld. Het klassieke voorbeeld is de multi-company-regel,
[('company_id', 'in', company_ids + [False])], die de records van elk bedrijf gescheiden houdt, hoe hoog je ook zit. - Een groep-regel hangt aan een of meer groepen en verruimt wat die groepen kunnen bereiken, maar alleen binnen de globale grens.
In gewone taal: globale regels trekken het buitenhek dat niemand overklimt, en groep-regels delen toegang uit binnen dat hek. In logica: globale regels stapelen met EN, groep-regels combineren met OF.
Voor developers: waarom de dropdown geen databasekolom is
Als je zoekt naar een sales- of project-kolom op res.users, vind je die niet. De Rol-keuze en elke per-app dropdown zijn reified velden. Ze hebben geen kolom. Bij het laden bepaalt Odoo de huidige waarde door te kijken in welke groepen de gebruiker zit, en bij opslaan schrijft het de juiste groep in de groepenlijst van de gebruiker.
roleis een handgeschreven selection-veld (module base, niet opgeslagen).- De per-app dropdowns worden runtime gegenereerd, met namen als
sel_groups_<ids>, en een los vinkje isin_group_<id>. Geen van beide staat inir.model.fields, en daarom levert zoeken daar niets op. - Het enige dat echt wordt opgeslagen is de many-to-many
res.users.groups_id, fysiek de tabelres_groups_users_rel(uid, gid).
Het mentaalmodel is dus kort: de widgets op het gebruikersscherm zijn een vriendelijke voorkant over één groepenlijst. De macht van elke groep zit elders, in ir.model.access, ir.rule, het groups-attribuut op velden, en de eigen implied groepen van de groep.
User Roles: de optionele module
Standaard Odoo laat je toegang per persoon instellen. Voor drie mensen prima. Voor dertig, met verloop, gaat het schuiven, en niemand weet nog waarom iemand iets heeft.
De OCA-module base_user_role lost dat op. Je maakt één keer een rol als bundel van groepen, en wijst die aan mensen toe. Pas de rol aan, en iedereen met die rol wordt in één keer bijgewerkt. Je kunt een rol op datum aan- of uitzetten, handig voor tijdelijke toegang.
Twee dingen om helder te houden. Ten eerste, dit is geen standaard Odoo. De rollenlijst bestaat alleen als je de module installeert, en verwar het niet met de simpele User / Administrator-keuze, die wel standaard is. Ten tweede, onder de motorkap bundelt een rol zijn groepen via een implied_ids-veld, en mensen worden aan rollen gekoppeld via een klein tussenrecord, res.users.role.line, dat een begin- en einddatum kan dragen. Het is hetzelfde implied-groepen-idee, één niveau hoger hergebruikt.
Toegangsrechten, API-keys en AI
Hier betaalt het zich uit voor iedereen die Odoo koppelt aan een API of een AI-assistent.
Een API-key geeft zelf geen rechten. Die zegt alleen 'ik ben deze gebruiker'. Een aanroep met de key draait als die gebruiker en gaat door precies dezelfde vier lagen. Wil je weten wat een key mag? Kijk naar de groepen van de gebruiker erachter, net als bij een persoon.
De key zit in res.users.apikeys. Elke key hoort bij één gebruiker (user_id), heeft een scope en een expiration_date, en het geheim wordt gehasht opgeslagen, dus je kunt het na aanmaken nooit meer teruglezen. Een governance-module kan een beperkte rol aan een key hangen, zodat die minder mag dan de volledige gebruiker, iets wat standaard Odoo niet kan. De praktische les: om te sturen wat de assistent mag, pas je de groepen of rol van de gebruiker in Odoo aan, net zoals je een zorgvuldige nieuwe collega zou inwerken.
Wanneer gebruik je wat
- Een klein, stabiel team: het standaard gebruikersscherm is genoeg.
- Meerdere mensen in dezelfde functie, een groeiend team, of audit- en compliance-eisen: gebruik User Roles zodat rollen herbruikbaar en makkelijk te controleren zijn.
- Een AI of API toegang geven: combineer een beperkte rol met een beperkte API-key, en houd de onderliggende gebruiker strak.
FAQ
Wat is het verschil tussen een groep en een rol in Odoo?
Een groep is de ingebouwde eenheid die de rechten echt draagt. Een rol in de dagelijkse zin is óf het simpele User / Administrator-basistype, óf, als je de OCA-module installeert, een herbruikbare bundel groepen die je aan veel gebruikers kunt geven.
Access rights versus record rules?
Access rights bepalen wat je met een heel soort record mag (lezen, schrijven, aanmaken, verwijderen). Record rules bepalen met welke specifieke records, via een filter.
Wat is een privilege in Odoo 19?
Het is één per-app dropdown op het gebruikersscherm, een benoemde set gerangschikte opties. Het ordent het scherm, het geeft zelf niets. De rechten zitten op de groepen erin.
Kan ik een recht weghalen door een groep toe te voegen?
Nee. Rechten tellen alleen op. Om toegang te verminderen haal je een groep weg, je voegt er geen toe.
Heb ik de OCA User Roles-module nodig?
Alleen als toegang per persoon beheren een klus is geworden, of als je herbruikbare, controleerbare rollen nodig hebt. Kleine teams redden zich prima zonder.
Hoe raken toegangsrechten een AI- of MCP-verbinding?
De verbinding logt in als een gebruiker via een API-key en volgt dezelfde vier lagen. Je regelt toegang door de groepen of rol van die gebruiker aan te passen.
Naslag: welk veld regelt wat
| Wat je ziet | Model | Veld | Wat het regelt |
|---|---|---|---|
| Hele tab Toegangsrechten | res.users | groups_id (m2m naar res.groups) | in welke groepen de gebruiker zit |
| Rol: User / Administrator | res.users | role (selection, niet opgeslagen) | basisgroep User of Administrator |
| Per-app dropdown | res.users | sel_groups_<ids> (runtime) | lidmaatschap in die app-groep |
| Extra Rights-vinkje | res.users | in_group_<id> (runtime) | één groep aan of uit |
| Grijs kopje en groepering | res.groups | privilege_id naar res.groups.privilege (heeft category_id naar ir.module.category) | schermindeling (Odoo 19) |
| Rangorde in een dropdown | res.groups | implied_ids | welke groepen meekomen |
| Wat een groep mag doen | ir.model.access | group_id, model_id, perm_read/write/create/unlink | CRUD per model |
| Welke records | ir.rule | groups, model_id, domain_force, global | rij-filter |
| Welke velden | ir.model.fields | groups | veld zichtbaar of bewerkbaar |
| Het beschermde ding | ir.model | model (bijvoorbeeld project.task) | doel van de rechten |
| Een API-key | res.users.apikeys | user_id, scope, expiration_date | authenticeert als een gebruiker |