Field and relationship permissions
Enforces access based on ownership and team relationships, including different visible or editable fields on one record.
field-relationship-permissions
See how it helpsWhen is it useful?
Use when colleagues may share a record but must see different information.
What does it help you do?
- Translates ownership and department rules into scoped queries and record checks.
- Removes protected fields on the server before responses reach the browser.
- Defines access changes after reassignment and validates restricted field updates.
Try asking this
Let sales staff view orders without supplier margins, and define what former owners retain after an account reassignment.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Field & Relationship Permissions
When to Use
Use when access depends on who owns a record, which department/team/territory/project it belongs to, or when different roles may view or edit only a subset of fields on the same entity.
1. Relationship- & Ownership-Based Access (ReBAC / ABAC)
Translate business phrases directly into explicit relational predicates enforced in both single-item checks and SQL query scopes:
- "Can edit own accounts":
account.owner_user_id = :actorId - "Can view accounts in own department or sub-teams":
account.department_id IN (:actorDepartmentHierarchyIds) - "Account team members can view; only lead can edit pricing": Join
account_team_members(account_id, user_id, access_level)scoped bytenant_id. - Ownership Transfer & Historical Access:
- Explicitly define what happens when an account or opportunity is reassigned from Rep A to Rep B: Rep A immediately loses edit access unless retained as a collaborator in
account_team_members.
- Explicitly define what happens when an account or opportunity is reassigned from Rep A to Rep B: Rep A immediately loses edit access unless retained as a collaborator in
2. Field-Level Read Redaction (Projection / Serialization Security)
Even when two users can both view the same Order or Employee record, they often must not see the same columns:
- Example: A
sales_reporwarehouse_pickercan vieworder.itemsandshipping_address, but onlyfinanceandsales_managercan viewunit_cost,supplier_margin,commission_rate, ortax_id. - Server-Side Serializer / DTO Projection:
- Never send the full database row to the browser and hide sensitive columns in CSS/JS (
v-if/{isManager && ...})—anyone opening DevTools Network tab sees the raw JSON! - Strip unauthorized fields in the backend serializer/mapper (
projectVisibleFields(actor, resource)) before returning API responses, GraphQL fields, webhook payloads, or CSV exports.
- Never send the full database row to the browser and hide sensitive columns in CSS/JS (
3. Field-Level Write Protection (Preventing Mass Assignment)
Different roles or resource states permit editing different subsets of fields on the same endpoint (PATCH /orders/:id):
- A
sales_repon adraftquote may updatecustomer_notesandquantities, while only asales_managermay updatemanual_discount_override, and no user may directlyPATCHstatus: 'approved'orapproved_by_id(which must only change via the dedicated approval state transition). - Explicit Per-Role & Per-State Allowlists:
- Validate incoming update payloads against the intersection of
writableFieldsForRole(actor.role)andwritableFieldsInState(resource.status). - Reject (
403 Forbiddenor422) when a caller attempts to mutate a restricted field, rather than silently ignoring security-sensitive fields.
- Validate incoming update payloads against the intersection of
Included files 1
SKILL.md
