manager in the apparel store and just a staff member in the home-goods store.
OpenFGA models the org/store split natively. The full sample lives in openfga/sample-stores/stores/ecommerce.
Core resources and relations
Two-tier role model:- organization roles —
admin,store_manager,member. Granted at the org level, inherited where it makes sense. - store roles —
owner,manager,staff. Per-store and not automatically inherited from org membership.
- organization — the merchant tenant.
- store — belongs to an
organization, has its ownowner,managers, andstaff. - product — belongs to a
store. Managers create/edit/delete; the staff member who authored a product can edit it; everyone in the store can read. - customer — staff view, managers edit, admins delete.
- order — the customer who placed the order can view and cancel; staff fulfill; managers refund; admins delete.
- store_settings — owners configure, staff view.
What the model gets right
Org admin ≠ store owner. A platform admin who needs to see every store’s data is not automatically an owner of any individual store. Role inheritance is opt-in, expressed in the model rather than buried in application code. Author-edit on products. The staff member who created a product can edit it, even though staff in general can only view. This is a classic ReBAC pattern (creator relation as a fallback for manager).
Customer self-service. Customers see only their own orders by being the direct subject of customer on the order, which lets the same Check API serve both the merchant admin UI and the customer-facing storefront.
Refund vs. delete. Refund is a manager-level permission; delete is admin only. Two separate relations means audits can answer “who could have refunded this order” independently of “who could have deleted it”.
Where this maps to OpenFGA features
Common extensions
- Seller marketplaces (Etsy-like). Add a
sellertype that owns one or more stores; platform admins moderate but don’t own. - Returns and exchanges. Treat each return as its own object with its own approval chain (manager creates, admin approves) rather than overloading the order’s relations.
- Promotions and discounts. Discount codes can be modeled as objects with
creator,approver, andviewerrelations — useful when finance must approve before a code goes live.