From antigravity-awesome-skills
Generates Odoo access controls: ir.model.access.csv for models, ir.rule domains for records, groups, multi-company rules. Debugs access denied errors.
npx claudepluginhub absjaded/antigravity-awesome-skillsThis skill uses the workspace's default tool permissions.
Security in Odoo is managed at two levels: **model-level access** (who can read/write which models) and **record-level rules** (which records a user can see). This skill helps you write correct `ir.model.access.csv` entries and `ir.rule` domain-based record rules.
Verifies tests pass on completed feature branch, presents options to merge locally, create GitHub PR, keep as-is or discard; executes choice and cleans up worktree.
Guides root cause investigation for bugs, test failures, unexpected behavior, performance issues, and build failures before proposing fixes.
Writes implementation plans from specs for multi-step tasks, mapping files and breaking into TDD bite-sized steps before coding.
Security in Odoo is managed at two levels: model-level access (who can read/write which models) and record-level rules (which records a user can see). This skill helps you write correct ir.model.access.csv entries and ir.rule domain-based record rules.
@odoo-security-rules and describe the access scenario.id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hospital_patient_user,hospital.patient.user,model_hospital_patient,base.group_user,1,0,0,0
access_hospital_patient_manager,hospital.patient.manager,model_hospital_patient,base.group_erp_manager,1,1,1,1
Note: Use
base.group_erp_managerfor ERP managers, notbase.group_system— that group is reserved for Odoo's technical superusers. Always create a custom group for module-specific manager roles:<record id="group_hospital_manager" model="res.groups"> <field name="name">Hospital Manager</field> <field name="category_id" ref="base.module_category_hidden"/> </record>
<record id="rule_hospital_patient_own" model="ir.rule">
<field name="name">Hospital Patient: Own Records Only</field>
<field name="model_id" ref="model_hospital_patient"/>
<field name="domain_force">[('create_uid', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="False"/>
</record>
Important: If you omit
<field name="groups">, the rule becomes global and applies to ALL users, including admins. Always assign a group unless you explicitly intend a global restriction.
<record id="rule_hospital_patient_company" model="ir.rule">
<field name="name">Hospital Patient: Multi-Company</field>
<field name="model_id" ref="model_hospital_patient"/>
<field name="domain_force">
['|', ('company_id', '=', False),
('company_id', 'in', company_ids)]
</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
company_ids (plural) in multi-company rules — it includes all companies the user belongs to.sudo() bypasses all record rules entirely.perm_unlink = 1 to regular users unless deletion is explicitly required by the business process.group_id blank in ir.model.access.csv unless you intend to grant public (unauthenticated) access.base.group_system for module managers — that grants full technical access including server configurations.ir.model.fields read/write restrictions) — those require custom OWL or Python overrides.base.group_portal.sudo() — any code running in superuser context ignores all ir.rule entries.