Per-view & per-vault ACL
Section permissions (R/W/E/D) are the outer gate. For some surfaces, that’s not granular enough — a Sales rep with cars:read = true should see their assigned yard’s cars, not every car in the company. The platform layers inner gates for this.
The three-layer model
Section titled “The three-layer model”- Section visibility — does this role see the route/sidebar item at all? (
cars:read,vaults:read) - Sub-tab or sub-content gating — within a shared section, does this role see this particular tab/view? (Saved views; vault-row visibility)
- Row-level scoping — within an accessible view, which rows are returned? (Per-location ACL filters; per-vault ACL gates)
All three must pass for the user to see a row.
Per-view ACL (cars)
Section titled “Per-view ACL (cars)”Each saved view carries a per-role bindings table. Each binding has:
- Visible toggle — does this role see the view in the tab strip?
- Offering price toggle — can this role edit
internalOfferingPriceon rows in this view?
A role with no binding to a view doesn’t see it. A role with multiple bound views sees a tab strip with each.
Per-vault ACL
Section titled “Per-vault ACL”Same pattern, applied to vaults. Each vault row has per-role bindings:
- Visible toggle — does this role see the vault in
/vaults? - Write toggle — can this role create transactions on this vault?
A role bound only to “Cash KEB USD” can’t see “Cash KEB KRW” — the vault is filtered out of every list query for them.
Per-location ACL (cars)
Section titled “Per-location ACL (cars)”Cars also use locations as an action-level ACL. Each role gets per-location flags, all of them enforced:
canSee— see cars at this locationcanReceive— accept a location change to this locationcanMoveOut— initiate a location change away from this locationcanSell— issue an invoice for cars at this location
There is no canEdit flag — it was never implemented. Editing a car is still gated by the outer cars:edit section permission; the location layer only controls visibility and the receive/move-out/sell actions. See Locations.
Layering example
Section titled “Layering example”A Sales role with:
cars:read = true,cars:edit = true(section layer — passes)- Bound to the “Showroom A” view,
canEditOfferingPrice = true(sub-tab layer — passes) canSell = trueandcanSee = trueon the Showroom A location (row layer — passes)
…can see cars at Showroom A, edit their offering price, and issue invoices against them. Sees nothing at the Korea yard. The platform composes all three gates; missing any one = no access.
Related
Section titled “Related”Change log
Updated on Feature / change Reason 2026-07-07 Corrected per-location ACL: canReceive/canMoveOut/canSellare actively enforced (not planned); removed the nonexistentcanEditflagCode audit against server/db/carLocationScope.tsfound all four action flags enforced and nocanEditfield ever implemented