Stella is multi-tenant by construction. Every row in every table is tagged with aDocumentation Index
Fetch the complete documentation index at: https://docs.stella-commerce.com/llms.txt
Use this file to discover all available pages before exploring further.
site_id (or transitively, via a foreign key to a row
that is). Every query in every endpoint filters by site_id drawn
from the caller’s token. There is no code path that elides this
filter.
Where site_id comes from
| Caller | Source |
|---|---|
| Storefront token | storefront_access_tokens.merchant_id (joined to merchants.site_id) |
| Customer token | The customer’s merchant_id at the time the token was minted |
| Agent token | The agent’s merchant_id (inherited from the customer who consented) |
| Dashboard | The authenticated user’s active merchant (per session) |
kasa returns 401
on /api/storefront/products if X-Site-ID: huba-nepal is sent —
because the storefront-token gate runs first and rejects the mismatch.
Data isolation invariants
- Every multi-tenant table has a
site_idcolumn or a non-nullable FK to one that does. Reviewed at PR time; integration tests assert. - Every query joins through
site_idor filters on it. SQLAlchemy model definitions encode the relationships; cross-tenant joins would require explicit ORM gymnastics. - Every webhook payload carries
site_idso consumers can route without ambiguity. - Audit events include
merchant_idfor cross-merchant forensics.
Per-merchant CORS
/api/storefront/* does dynamic CORS reflection: the response
Access-Control-Allow-Origin only mirrors the request’s Origin if
it appears in any active token’s allowed_origins for the merchant
identified by X-Site-ID. Tokens revoked or merchants without an
allowlisted origin → preflight 403.
This is enforced on top of standard server-side Origin checks — both
layers must pass.
Multi-merchant developer use cases
If you operate multiple Stella tenants (e.g. an agency managing several brands), you mint one storefront token per tenant. Tokens don’t compose across merchants; each call carries exactly oneX-Site-ID and one X-Stella-Token.