Roles & permissions
Distribu has three separate permission systems. They cover three different
kinds of actor and they don't overlap — a staff MEMBER is not the same thing as
a customer contact VIEWER, and neither has anything to do with an API key.
| System | Who it governs | Set on |
|---|---|---|
| Staff roles | People at your company signing into the dashboard | Their staff membership |
| Customer contact roles | Sub-users inside a customer account using your storefront | The contact itself |
| API key scopes | Programmatic requests to the REST API | The API key |
This page explains each one and how they're enforced.
1. Staff roles
Everyone who signs into your dashboard has a staff role. There are three:
OWNER— exactly one per company. The person who signed up. Can do everything.ADMIN— trusted staff. Can manage the team and integrations but not billing.MEMBER— day-to-day operators. Can use the app but not invite people or manage keys.
What each role can do
| Action | OWNER | ADMIN | MEMBER |
|---|---|---|---|
| Sign into the dashboard | ✓ | ✓ | ✓ |
| View inventory, customers, orders | ✓ | ✓ | ✓ |
| Create / edit products | ✓ | ✓ | ✓ |
| Place and manage orders | ✓ | ✓ | ✓ |
| Invite new members | ✓ | ✓ | — |
| Remove members | ✓ | ✓ (except admins) | — |
| Change a member's role | ✓ | — | — |
| Create / revoke API keys | ✓ | ✓ | — |
| Configure webhooks | ✓ | ✓ | — |
| Manage billing & subscription | ✓ | — | — |
| Delete the company | ✓ | — | — |
The role matrix and invite flow are covered in detail in Team & roles.
How staff roles are enforced
Every dashboard page and action does a role check using the signed-in
user's staff role. If you're a MEMBER and you try to hit
/dashboard/settings/api-keys, the page redirects you away — the UI never
even renders. The same check happens again server-side on mutations, so
nothing slips through by URL-hacking.
2. Customer contact roles
Your customers (the businesses buying from you) can have multiple people logging in under the same account. We call those sub-users contacts, and they each have a role:
ADMIN— can manage other contacts and view every order placed under the customer account.BUYER— can browse the catalog, place orders, and view their own orders.VIEWER— read-only. Can see the catalog and order history but cannot place orders.
All three share the parent Customer record — addresses, credit limit, price
overrides, and existing orders are attached to the customer, not to the
individual contact.
How contact roles are enforced
When a contact signs in at /store/{slug}/login, their session records who
they are and what role they have under the parent customer. Permission
checks happen server-side on every request — e.g. a VIEWER who tries to
place an order gets back "Your account does not have permission to place
orders."
The primary customer credential (the original email + password from when the account was created) is always treated as an ADMIN — it isn't stored as a contact.
For the full picture, see Multi-user customer accounts.
3. API key scopes
When you create an API key from Settings → API keys, you pick one or more scopes that decide what that specific key can do. There are four:
| Scope | What it unlocks |
|---|---|
products:read | GET /api/v1/products, GET /api/v1/products/{id} |
products:write | POST, PATCH, DELETE on products |
orders:read | GET /api/v1/orders, GET /api/v1/orders/{id} |
orders:write | Advance order status, update fields |
A key only needs the scopes for the endpoints it'll hit. The default when
creating a new key is products:read alone. Pick only what you need — if you're
building a read-only reporting integration, don't check the :write boxes.
How API key scopes are enforced
Every API endpoint checks the incoming key before running your request:
- Reads the
Authorization: Bearer ...header. - Looks up the key (hashed, never stored in plain text).
- Checks the key hasn't been revoked and hasn't expired.
- Confirms the key has the scope the endpoint requires. If not, it returns HTTP 403 with a clear error message.
- Applies a per-key rate limit of 60 requests per minute. On overrun, HTTP
429 with a
retryAfterseconds hint.
Keys are scoped to their creating company — they can only ever see that company's data. See REST API authentication and API key scopes for the full reference.
How the three systems relate
They don't. That's the whole point.
- Giving someone a staff
MEMBERrole in your dashboard does not give them any access to the storefront as a customer. - Adding someone as an
ADMINcontact on a customer account does not let them sign into your dashboard. - An API key's scopes are independent of whoever created it — revoking the user who made the key does not revoke the key itself. You revoke keys explicitly from the API keys page.
This separation is intentional: the dashboard is for your team, the storefront is for your customers, and the API is for your integrations. One person might wear two of those hats (say, you're the Owner and also shop as a test customer), but those are two different accounts with two different credentials.
Up next: Multi-user customer accounts goes deeper on the customer/contact model — when to use it and how it works on your storefront.
