Skip to content

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.

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)
  • 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.
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.