Configuration
Every setting in Restrict Delete & Export, and what each one changes.
Everything here lives in Settings → General Settings → Access Restrictions, except the rules themselves, which are at Settings → Access Restrictions.
Global switches
| Setting | Default | What it does |
|---|---|---|
| Enabled | on | The master switch. Off means no rule is enforced anywhere — useful during an incident, and faster than disabling rules one at a time. |
| Settings users bypass | on | Users in Odoo's Settings group are not restricted. Turn it off deliberately, once you are confident the rules are right. |
| Log blocked attempts | on | Records who was refused, when, on which model and how many records. Can also be turned off per rule. |
| Keep attempts for (days) | 180 | Retention for the blocked-attempts log. 0 keeps everything. A cron prunes anything older. |
The four map to ir.config_parameter entries, so they can be set from a shell or a deployment script as well as from the interface.
A rule
Settings → Access Restrictions → Restriction Rules → New.
| Field | Notes |
|---|---|
| Model | The model to protect. Some are refused — see below. |
| Delete / Export / Print / Archive / Duplicate | Tick the operations to control. At least one is required; a rule that restricts nothing is rejected rather than silently ignored. |
| Allowed groups | Groups that keep the permission. |
| Allowed users | Individual accounts that keep it, for the exception that does not deserve a group. |
| Message | What everyone else sees. Write it as an instruction, not a refusal — see below. |
| Log attempts | Per-rule override of the global setting. |
| Notes | Why this rule exists. The field costs nothing and answers the question a year from now. |
| Active | Archive a rule instead of deleting it, so the history is preserved. |
One rule per model. A database constraint enforces it, so restrictions on a model are always readable in one place rather than assembled from several rows.
Allow-list, not deny-list
Once a rule restricts an operation, only the listed groups and users may perform it. Everyone else is refused.
This is deliberate. A deny-list stops being verifiable the moment a user belongs to several groups: you can no longer answer "who can delete invoices" by reading the rule, because the answer depends on every group the person is not in. An allow-list is the same question in one direction.
The refusal message is the whole user experience
The default message is generic. Replace it. Compare:
Access Denied
with
Archive the contact instead, or ask a Contact Manager if it really has to go.
The second generates no support ticket. The first generates one every time.
Models that cannot be restricted
Refused by the form, as Python-level guarantees rather than settings, because an administrator must not be able to configure the database into a state nobody can undo.
The module's own models — access.restriction.rule and access.restriction.attempt. Restricting these would let an administrator remove their own ability to lift a restriction.
Odoo's own management models, 25 of them, including res.users, res.groups, res.company, ir.model, ir.model.access, ir.rule, ir.module.module, ir.config_parameter, ir.cron, ir.attachment, ir.ui.view, ir.ui.menu, the ir.actions.* family, ir.model.data, mail.message and res.config.settings.
Restricting any of those would break Odoo itself or make the database unmanageable.
What cannot be switched off
| Guarantee | Why |
|---|---|
| The superuser always bypasses | So a rule can always be undone. This is not a setting. |
| It fails open | If the configuration cannot be read, the operation proceeds. A monitoring bug must not become a business outage. |
| Reads and ordinary edits are never touched | The module only runs on delete, copy, archiving writes, export and print. |
Suggested first rules
Start with two, not twenty. A restriction people hit every day and cannot explain gets the whole module switched off.
- account.move — delete only, allowed group Billing Manager. Message: "Posted entries are reversed, not deleted. Use Add Credit Note."
- res.partner — delete and export, allowed group Contact Manager. Message: "Archive the contact instead. To export, ask a Contact Manager."
Then read the blocked-attempts log for a fortnight before adding more — see USER_GUIDE.md.