ACC · Access
A person logs in as a profile and joins an organization through a membership. Roles sit on the membership, each for one pool or for all pools; grant and deny overrides adjust one permission at a time. Row-level security applies the result on every query. Code ACC.
Not yet a rule
Section titled “Not yet a rule”These questions are open in #72. Each gets a rule with a new ID once it is answered.
- ACC open 1 · Rental-company filter
- ACC open 3 · Deleting a profile (DOC-Q14)
- Who sees NIK, phone, company_amount and margin: OQ9 (#35)
Answered questions
Section titled “Answered questions”- DOC-Q12 (who reads the permission catalogue): every signed-in user. A new rule, R-ACC-33.
- DOC-Q13 (a member's rental companies): yes, as pack C does it: read with user:read (new rule R-ACC-34), add with user:write (R-ACC-17), remove with user:delete (R-ACC-18).
- DOC-Q14 (deleting a profile) is open in the issue above, with a proposal.
R-ACC-01 · Every table in the public schema has row-level security on
Section titled “R-ACC-01 · Every table in the public schema has row-level security on”- Status: planned
- Example: given the migrations have run, when the catalog lists public tables with row-level security off, then the list is empty.
- Refusal: none: this describes the schema; the RLS migration fails if a table lacks it.
- Who: every table.
- Source: D9 (P7); [Ref] Roles, The RLS pattern.
R-ACC-02 · Signed-out requests (anon) can't read or write any table
Section titled “R-ACC-02 · Signed-out requests (anon) can't read or write any table”- Status: planned
- Example: given a request with only the publishable key, when it reads drivers, then no row comes back, and an insert is refused.
- Refusal: none: hidden on read; insufficient_privilege (42501) on write.
- Who: the anon role.
- Source: [Ref] Roles, The RLS pattern; the M0 acceptance checks.
R-ACC-03 · A role held at a pool gives its permissions at that pool only
Section titled “R-ACC-03 · A role held at a pool gives its permissions at that pool only”- Status: planned
- Example: given Deka holds checker at pool PML only, when Deka reads inspections, then PML's come back and pool SBY's don't.
- Refusal: none: hidden.
- Who: every member with a pool-scoped role.
- Source: [Ref] Roles, How one question is answered.
R-ACC-04 · A role or override with no pool applies at every pool of the organization
Section titled “R-ACC-04 · A role or override with no pool applies at every pool of the organization”- Status: planned
- Example: given Rina holds finance with no pool, when the organization opens pool SBY, then Rina has finance's permissions at SBY without any change.
- Refusal: none.
- Who: every member with an all-pools role or override.
- Source: [Ref] Roles; [Ref] Data model V13: member_roles (empty pool = all pools).
R-ACC-05 · A grant override gives its permission even when no role includes it
Section titled “R-ACC-05 · A grant override gives its permission even when no role includes it”- Status: planned
- Example: given a satpam with a grant override for vehicle:read at PML, when he reads vehicles, then PML's cars come back.
- Refusal: none.
- Who: every member with a grant override.
- Source: [Ref] Roles, How one question is answered.
R-ACC-06 · A deny override removes its permission, whatever roles and grants give
Section titled “R-ACC-06 · A deny override removes its permission, whatever roles and grants give”- Status: planned
- Example: given an admin with a deny override for payment:read at PML, when she reads payments, then no payment of a PML driver comes back, though her role includes payment:read.
- Refusal: none: hidden.
- Who: every member with a deny override.
- Source: [Ref] Roles (denies always win); the M0 acceptance checks.
R-ACC-07 · A suspended membership gives no permissions
Section titled “R-ACC-07 · A suspended membership gives no permissions”- Status: planned
- Example: given Deka's membership is suspended, when Deka reads vehicles, then no row comes back, whatever roles the membership holds.
- Refusal: none: hidden.
- Who: every member whose membership is suspended.
- Source: [Ref] Roles, The RLS pattern (active memberships only).
R-ACC-08 · A change to a user's roles or overrides applies from their next query, because permissions are never read from the login token
Section titled “R-ACC-08 · A change to a user's roles or overrides applies from their next query, because permissions are never read from the login token”- Status: planned
- Example: given Deka is signed in as checker, when an admin removes the role, then Deka's next query returns no inspections, without signing out.
- Refusal: none.
- Who: every member.
- Source: [Ref] Roles; D13.
R-ACC-09 · A pool-scoped row is visible only to users holding one of its table's read permissions at that row's pool
Section titled “R-ACC-09 · A pool-scoped row is visible only to users holding one of its table's read permissions at that row's pool”- Status: planned
- Example: given a work order at PML, when a maintenance user scoped to SBY reads work orders, then it doesn't come back; a maintenance user scoped to PML sees it.
- Refusal: none: hidden.
- Who: every member. Each table's read permissions are on its domain's page.
- Source: [Ref] Roles, The RLS pattern and policy matrix; the M0 acceptance checks.
R-ACC-10 · Inserting or updating a pool-scoped row needs its table's write permission at the row's pool, both before and after the change
Section titled “R-ACC-10 · Inserting or updating a pool-scoped row needs its table's write permission at the row's pool, both before and after the change”- Status: planned
- Example: given an admin_fleet scoped to PML, when he moves a car's home pool to SBY by update, then it is refused, because he holds vehicle:write at PML only.
- Refusal: none: insufficient_privilege (42501) on the new values; no effect when the old row isn't writable.
- Who: every member. Each table's write permissions are on its domain's page.
- Source: [Ref] Roles, The RLS pattern (using and with check).
R-ACC-11 · A child row (photo, item, event) is scoped by its parent's pool
Section titled “R-ACC-11 · A child row (photo, item, event) is scoped by its parent's pool”- Status: planned
- Example: given an inspection at PML, when a checker scoped to SBY reads inspection_photos, then that inspection's photos don't come back.
- Refusal: none: hidden.
- Who: every member.
- Source: [Ref] Roles, The RLS pattern (child tables and their resolver helpers).
R-ACC-12 · Every view applies the reader's own row-level security
Section titled “R-ACC-12 · Every view applies the reader's own row-level security”- Status: planned
- Example: given a finance user scoped to PML, when she reads v_driver_balance, then only PML drivers' balances come back.
- Refusal: none: hidden.
- Who: every view (security_invoker).
- Source: [Ref] Database rules and conventions, Views.
R-ACC-13 · Every new login gets a profile, created by the database
Section titled “R-ACC-13 · Every new login gets a profile, created by the database”- Status: planned
- Example: given an admin invites rina@example.test, when the login is created, then a profiles row with the same id exists.
- Refusal: none.
- Who: every login.
- Source: [Ref] Data model V13: profiles ↔ auth.users.
R-ACC-14 · A person has at most one membership per organization
Section titled “R-ACC-14 · A person has at most one membership per organization”- Status: planned
- Example: given Rina is a member of organization A, when a second membership for her in A is saved, then it is refused.
- Refusal: none: unique_violation (23505).
- Who: every writer.
- Source: [Ref] Data model V13: memberships.
R-ACC-15 · A user can always read their own profile
Section titled “R-ACC-15 · A user can always read their own profile”- Status: planned
- Example: given a satpam without user:read, when he reads profiles, then his own profile comes back.
- Refusal: none.
- Who: every signed-in user.
- Source: [Ref] Roles, policy matrix.
R-ACC-16 · Reading other members' profiles, memberships, roles and overrides needs user:read
Section titled “R-ACC-16 · Reading other members' profiles, memberships, roles and overrides needs user:read”- Status: planned
- Example: given an admin, when he reads member_roles, then no row comes back; a super_admin sees them.
- Refusal: none: hidden.
- Who: super_admin holds user:read.
- Source: [Ref] Roles, policy matrix.
R-ACC-17 · Adding or changing a membership, a profile, a member's role, an override or a member's rental companies needs user:write
Section titled “R-ACC-17 · Adding or changing a membership, a profile, a member's role, an override or a member's rental companies needs user:write”- Status: planned
- Example: given an admin, when he gives Deka the checker role, then it is refused; a super_admin's grant goes through.
- Refusal: none: insufficient_privilege (42501) on insert; no effect on update.
- Who: super_admin holds user:write.
- Source: [Ref] Roles, policy matrix.
R-ACC-18 · Deleting a membership, a profile or a member's rental-company link needs user:delete
Section titled “R-ACC-18 · Deleting a membership, a profile or a member's rental-company link needs user:delete”- Status: planned
- Example: given an admin, when she deletes a membership, then nothing is deleted; a super_admin's delete goes through.
- Refusal: none: no effect.
- Who: super_admin holds user:delete.
- Source: [Ref] Roles, policy matrix.
R-ACC-19 · Removing a member's role or override needs user:write
Section titled “R-ACC-19 · Removing a member's role or override needs user:write”- Status: planned
- Example: given a super_admin, when she removes Deka's checker role, then the member_roles row is deleted.
- Refusal: none: no effect without user:write.
- Who: super_admin holds user:write.
- Source: [Ref] Roles, policy matrix (member roles and overrides: delete needs user:write).
R-ACC-20 · Adding, changing or deleting an organization's own roles needs user:write
Section titled “R-ACC-20 · Adding, changing or deleting an organization's own roles needs user:write”- Status: planned
- Example: given a super_admin, when she adds a role "Supervisor PML" for her organization, then it is saved; an admin's attempt is refused.
- Refusal: none: insufficient_privilege (42501) on insert; no effect on update or delete.
- Who: super_admin holds user:write.
- Source: [Ref] Roles, policy matrix.
R-ACC-21 · System roles and their permissions can't be changed from the app
Section titled “R-ACC-21 · System roles and their permissions can't be changed from the app”- Status: planned
- Example: given a super_admin, when she adds payment:read to the system role satpam, then nothing changes.
- Refusal: none: no effect.
- Who: every app user, super_admin included. Only a migration changes them.
- Source: [Ref] Roles, policy matrix (system roles locked); [Ref] Data model V13, lookup tables.
R-ACC-22 · A member holds the same role at the same pool at most once, all pools counting as one pool
Section titled “R-ACC-22 · A member holds the same role at the same pool at most once, all pools counting as one pool”- Status: planned
- Example: given Deka holds checker for all pools, when checker for all pools is granted again, then it is refused.
- Refusal: none: unique_violation (23505), nulls not distinct.
- Who: every writer.
- Source: D9 (P4).
R-ACC-23 · A member has the same override (permission, effect, pool) at most once
Section titled “R-ACC-23 · A member has the same override (permission, effect, pool) at most once”- Status: planned
- Example: given Rina has a deny for payment:read at PML, when the same deny is saved again, then it is refused.
- Refusal: none: unique_violation (23505), nulls not distinct.
- Who: every writer.
- Source: [Ref] Data model V13: member_permission_overrides.
R-ACC-24 · A permission code has the form feature:action, in lower case
Section titled “R-ACC-24 · A permission code has the form feature:action, in lower case”- Status: planned
- Example: given the permissions table, when a code Vehicle:Read or vehicle-read is saved, then it is refused; vehicle:read is accepted.
- Refusal: none: check_violation (23514).
- Who: every writer.
- Source: [Ref] Data model V13: permissions.
R-ACC-25 · The permission catalogue holds exactly the 45 codes listed in [Ref] Roles
Section titled “R-ACC-25 · The permission catalogue holds exactly the 45 codes listed in [Ref] Roles”- Status: planned
- Example: given the seed has run, when the permission codes are listed, then there are 45 and they match the catalogue, from dashboard:read to transfer:approve.
- Refusal: none: this describes the seed.
- Who: the seed.
- Source: [Ref] Roles, Full permission catalogue.
R-ACC-26 · App users can't change the permission catalogue
Section titled “R-ACC-26 · App users can't change the permission catalogue”- Status: planned
- Example: given a super_admin, when she adds a permission code, then nothing is saved.
- Refusal: none: insufficient_privilege (42501) on insert; no effect on update or delete.
- Who: every app user. Only a migration changes it.
- Source: [Ref] Data model V13, lookup tables (permissions: nobody, migration only).
R-ACC-27 · The 11 system roles hold exactly their v1 permissions, renamed: 193 grants in all
Section titled “R-ACC-27 · The 11 system roles hold exactly their v1 permissions, renamed: 193 grants in all”- Status: planned
- Example: given the seed has run, when satpam's permissions are listed, then they are exactly audit_log:read and gate:read.
- Refusal: none: this describes the seed.
- Who: the seed.
- Source: [Ref] Roles, Permissions per role; the M0 acceptance checks.
R-ACC-28 · my_permissions() returns one row per pool and permission the caller holds after roles, grants and denies
Section titled “R-ACC-28 · my_permissions() returns one row per pool and permission the caller holds after roles, grants and denies”- Status: planned
- Example: given Deka holds checker at PML and a deny for gate:approve at PML, when he calls my_permissions(), then the PML rows include inspection:handover and leave out gate:approve.
- Refusal: none.
- Who: every signed-in user.
- Source: [Ref] Roles; [Runbook] v2 backend, M0 Interface.
R-ACC-29 · Signed-out callers can't run my_permissions()
Section titled “R-ACC-29 · Signed-out callers can't run my_permissions()”- Status: planned
- Example: given a request with only the publishable key, when it calls rpc('my_permissions'), then it is refused.
- Refusal: none: insufficient_privilege (42501), as anon may not execute the function.
- Who: the anon role.
- Source: [Runbook] v2 backend, M0 Interface.
R-ACC-30 · A profile's locale defaults to id (Indonesian)
Section titled “R-ACC-30 · A profile's locale defaults to id (Indonesian)”- Status: planned
- Example: given a new login, when its profile is read, then locale is id.
- Refusal: none.
- Who: every profile.
- Source: D7; D29; [Runbook] v2 backend, M0 Interface (FE-R5).
R-ACC-31 · set_my_locale() changes only the caller's own locale
Section titled “R-ACC-31 · set_my_locale() changes only the caller's own locale”- Status: planned
- Example: given Deka, when he calls set_my_locale('en'), then his profile's locale is en and no other profile changes. The function takes no profile argument.
- Refusal: none.
- Who: every signed-in user, whatever their roles.
- Source: [Runbook] v2 backend, M0 Interface (FE-R5).
R-ACC-32 · set_my_locale() refuses any locale other than id or en
Section titled “R-ACC-32 · set_my_locale() refuses any locale other than id or en”- Status: planned
- Example: given Deka, when he calls set_my_locale('fr'), then it is refused with the detail {"locale": "fr"} and his locale stays as it was.
- Refusal: profile.locale_unsupported
- Who: every signed-in user.
- Source: [Runbook] v2 backend, M0 Interface (FE-R5); D7.
R-ACC-33 · The permission catalogue is readable by every signed-in user
Section titled “R-ACC-33 · The permission catalogue is readable by every signed-in user”- Status: planned
- Example: given a satpam, when he reads permissions, then all 45 codes and their labels come back; a signed-out request sees none (R-ACC-02).
- Refusal: none.
- Who: every signed-in user.
- Source: [Ref] Data model V13: permissions is global, one catalogue for every tenant, with no tenant data; R-TEN-03 lets every tenant read shared rows. Added for DOC-Q12.
R-ACC-34 · Reading a member's rental companies needs user:read
Section titled “R-ACC-34 · Reading a member's rental companies needs user:read”- Status: planned
- Example: given an admin, when he reads member_rental_companies, then nothing comes back; a super_admin sees which partners each member is limited to.
- Refusal: none: hidden.
- Who: super_admin holds user:read.
- Source: [Ref] Roles, policy matrix (memberships, profiles, member rental companies: read user:read, write user:write, delete user:delete). Adding and removing them are R-ACC-17 and R-ACC-18. Added for DOC-Q13.