Tenants & context
litecommerce is multi-tenant from the ground up. A tenant is one merchant's store — its catalog, inventory, orders, staff, and settings. Every row in the database is tenant-scoped, and every API guard enforces that scoping on public, merchant, and platform routes alike.
How context is resolved
Tenant context is usually carried in the x-organization-slug header — the
slug of the store you're acting on. It's required on tenant-resolving public
requests and merchant requests.
x-organization-slug: your-store- Public reads need only this header. A server-side guard resolves the organization from the slug (404 if no such store, 400 if the header is missing) and scopes every query to it — so a storefront reads its own catalog with no privileged credentials in the browser.
- Token-only public routes resolve tenant context from their opaque token
target instead of the slug header. For example,
POST /public/checkout/sessions/:token/payment-sessiondoes not sendx-organization-slug. - Merchant requests send the header and an
Authorization: BearerSupabase JWT. After the token is validated, a membership check confirms the authenticated user actually belongs to the org named by the slug before any read or write proceeds.
Because the slug only ever resolves to one organization and every query is
scoped to its id, a request can't reach across tenants — there's no
parameter that widens the scope. A mismatched slug + session returns an
authorization error rather than leaking another tenant's data.
Related
- Auth & roles — who can do what within a tenant
- API keys — the planned server-to-server auth path (staff JWT today)