Skip to content

Access Rights & Record Rules

Security in Odoo: Two Levels

  1. Access Rights (ir.model.access) - Can this user group access this model at all?
  2. Record Rules (ir.rule) - Which specific records can they see/edit?

The "Access Denied" Story

You've set up a new salesperson. They log in and click on Sales → Orders... "Access Denied". What went wrong?

Understanding Odoo's two-level security system is essential for troubleshooting and configuring user permissions correctly.

Think of it like a building:

  • Access Rights = Which rooms (models) can you enter?
  • Record Rules = Once inside the room, which items (records) can you see?
mermaid
graph TD
    U[User] --> G[User Groups]
    G --> AR[Access Rights]
    G --> RR[Record Rules]
    AR --> M["Model Access
    Can access sale.order?"]
    RR --> R["Record Filtering
    Which orders can see?"]

Access Rights - Model Level

The Four Permissions: CRUD

PermissionLetterWhat It AllowsExample
CreateCCreate new recordsAdd new sales orders
ReadRView existing recordsSee orders in list/form
UpdateUEdit existing recordsModify order lines
DeleteDDelete recordsRemove cancelled orders

Example: Sales Module Access

GroupModelCRUD
Sales / Usersale.order
Sales / Managersale.order
Sales / Usersale.report
Accounting / Invoicingaccount.move

Where Access Rights Are Defined

Location: Settings → Technical → Security → Access Rights

Each access right record contains:

  • Name: Description of the permission
  • Model: Which model it applies to
  • Group: Which user group gets this permission
  • CRUD checkboxes: Which operations are allowed

Record Rules - Record Level

What Record Rules Do

Record rules use domains to filter which specific records a user can access.

Example: "Sales users can only see orders assigned to them" Domain: [('user_id', '=', user.id)]

Common Record Rule Patterns

Rule NameDomainEffect
Own records only[('user_id', '=', user.id)]See only records you created/own
Same company[('company_id', 'in', company_ids)]See only your company's data
Same team[('team_id', '=', user.sale_team_id.id)]See your sales team's records
Public records`['', ('public', '=', True), ('user_id', '=', user.id)]`
Followers only[('message_partner_ids', 'in', user.partner_id.ids)]Records you follow

Record Rule Operations

Each record rule can apply to different operations:

OperationWhen Applied
ReadViewing records in lists, forms, reports
WriteEditing existing records
CreateCreating new records
UnlinkDeleting records

Global vs Non-Global Rules

  • Global rules (no group assigned): Apply to ALL users, combined with AND
  • Non-global rules (group assigned): Apply only to that group, combined with OR among same group's rules

Groups: How Users Get Permissions

Users don't get permissions directly - they get assigned to groups, and groups have permissions.

Group Hierarchy Example - Sales

LevelGroup NameInherits FromSpecial Access
BasicSales / User: Own Documents-See own quotations/orders only
MediumSales / User: All DocumentsOwn DocumentsSee all team quotations/orders
FullSales / AdministratorAll DocumentsConfiguration + delete access

Each level inherits permissions from the level below it.

How to Check/Assign Groups

  1. Go to Settings → Users & Companies → Users
  2. Select a user
  3. Scroll down to see permission checkboxes organized by app
  4. Check/uncheck to assign/remove groups

Finding a Group's Technical Name

For automation and development, you often need the technical group name:

  1. Settings → Technical → Security → Groups
  2. Search for the group
  3. Look at the External ID (e.g., sales_team.group_sale_manager)

Field-Level Security

Beyond model and record access, individual fields can be restricted:

python
credit_limit = fields.Float(
    groups="account.group_account_manager"  # Only accounting managers see this
)

Common Field-Level Restrictions

Field TypeCommon GroupsWhy Restrict?
Credit Limitaccount.group_account_managerFinancial sensitivity
Cost Pricepurchase.group_purchase_managerMargin protection
Salaryhr.group_hr_managerPrivacy
API Keysbase.group_systemSecurity

Troubleshooting Guide

"Access Denied" or Missing Records

Check in this order:

  1. User groups: Settings → Users → select user → Groups tab Are they in the right groups? Sales/User? Sales/Manager?

  2. Model access rights: Settings → Technical → Security → Access Rights Does their group have Read permission on the model?

  3. Record rules: Settings → Technical → Security → Record Rules Is there a domain restricting which records they can see?

  4. Field groups: Check if specific fields are hidden by groups= attribute

Common Issues and Solutions

ProblemLikely CauseSolution
Menu completely missingNot in any group for that appAssign to Sales/User, Purchase/User, etc.
"Access Denied" errorNo Read permission on modelAdd user to appropriate group
Can see menu but 0 recordsRecord rule filtering all recordsCheck record rules, may need "All Documents" group
Some fields invisibleField has groups= restrictionAdd user to the required group
Can view but can't editNo Update permissionCheck access rights for the group

Where to Configure Access Rights (Without Code)

What You WantWhere to ConfigureExample
Assign user to a groupSettings → Users → user formGive Maria "Sales / Administrator" role
See what a group can accessSettings → Technical → Security → Access RightsWhat can "Sales / User" group do?
Change record-level restrictionsSettings → Technical → Security → Record RulesLet salespeople see all orders
Create custom groupSettings → Technical → Security → GroupsCreate "Sales Viewer" group
See group inheritanceSettings → Technical → Security → GroupsView "Inherited" tab

Real Scenario: New Employee Onboarding

Your company hired a new sales rep, Priya. She needs to:

  • Create and manage her own quotations
  • See (but not edit) products and customers
  • Not see other salespeople's orders

Solution:

  1. Create user for Priya (Settings → Users → Create)
  2. Assign group: Sales / User: Own Documents Only
  3. The record rules automatically limit her to her own records

Done! No coding required for standard permission setups.

Multi-Company Security

In multi-company environments, record rules automatically include company filtering:

python
# Automatic company rule added by Odoo
[('company_id', 'in', company_ids)]

This ensures users only see records from companies they have access to.

Checking Company Access

  1. Settings → Users → select user
  2. Look at Allowed Companies field
  3. User sees records from all allowed companies (combined)

Knowledge Check

Q1: User sees menu but only their own orders. What controls this?

Answer: Record Rules (ir.rule)

Record Rules use domains to filter WHICH records a user can see. A rule like [('user_id', '=', user.id)] restricts users to only their own records.

Q2: User can't see "Credit Limit" field but managers can. Why?

Answer: The field has a groups="..." attribute

Field-level security using groups="account.group_account_manager" restricts visibility to specific user groups.

Q3: New user doesn't see Manufacturing menu. First thing to check?

Answer: Whether they're assigned to a Manufacturing user group

Menus are linked to user groups. No group = no menu visibility. Check Settings → Users → user form → Manufacturing section.

Q4: What's the difference between Access Rights and Record Rules?

Answer: Access Rights control model access; Record Rules filter specific records

Access Rights: "Can this group access sale.order at all?" Record Rules: "Which sale.order records can they see?"

Q5: How do you find a group's technical name for automation?

Answer: Settings → Technical → Security → Groups → check External ID

The External ID (like sales_team.group_sale_manager) is needed for automated actions, domains, and development.