Security
Last updated 5 August 2026
Bulkroom holds two things worth protecting: a merchant's store access token, and the wholesale prices they've negotiated with each of their buyers. Here's how each is handled.
Store access
- Access is granted by OpoShop's OAuth flow and scoped to one store. The token lives server-side only and is never sent to a browser.
- The app requests least-privilege scopes — only what it actually calls.
- An embedded session is minted only after store ownership is proven using the caller's own credential. "This store is already connected" is explicitly not accepted as evidence of who is asking.
- Uninstalling revokes access and immediately closes the buyer portal and storefront link.
Wholesale buyers
- No passwords. Buyers sign in with a one-click link that expires in 45 minutes and can only be exchanged for a session once.
- The sign-in code travels in the URL fragment, so it is never sent to a server or written to an access log, and it's stripped from the address bar as soon as it's used.
- Every buyer read is scoped to the signed-in account. Guessing another quote's id returns nothing.
- Revoking or suspending an account locks the buyer out on their very next request, not when their token happens to expire.
No enumeration. The application and sign-in endpoints return the same response whether or not an email already has an account. Neither can be used to work out which retailers a brand sells to.
The order path
Creating an order in a merchant's store is the highest-consequence thing this app does, so it is gated repeatedly:
- Only an explicit merchant approval can start it. No schedule, webhook or automatic path exists.
- The conversion slot is claimed in a single atomic operation backed by a unique database index, so a double-click, a retry and a concurrent API call cannot produce two orders.
- Prices are re-read from the live catalog at the moment of conversion; a client-supplied price is never used anywhere in the app.
- The created order is read back and its arithmetic verified. If the total doesn't match the approved total, or an unexpected discount was applied, the order is cancelled and the merchant is told exactly why.
- The single-use discount that sets the negotiated price is retired immediately after use.
Tenancy
Every record is scoped to one store, and every query filters on it. One owner with two stores gets two entirely separate sets of trade accounts, price lists and quotes. A boot-time audit re-verifies the isolation constraints on every deploy.
Storefront safety
The storefront element makes exactly one request and renders a single overlay link. It reads no shopper data, sets no cookie, never modifies anything the theme already rendered, and causes no layout shift. Every failure path — network error, bad response, rate limit, our service being down — results in nothing being drawn at all, so a merchant's shop is never affected by us.
Infrastructure
- HTTPS everywhere, HSTS enforced by the platform.
- Managed database with encryption at rest and restricted network access.
- Secrets injected at runtime; nothing sensitive is committed to source control.
- Public endpoints are rate-limited per IP, and malformed request bodies return a clean 4xx rather than a server error.
- No card or bank details ever reach our systems.
Reporting a vulnerability
Email brandon@tryfound.io with steps to reproduce. We'll acknowledge within two business days. Please don't test against a store you don't own.