01
European hosting · only
All product data, assets and AI logs live on European infrastructure. PostgreSQL clusters in EU-Central. Cloudflare R2 buckets pinned to EU regions. Never replicated outside the EU, ever, not for analytics, not for backups, not for support.
- Database Postgres 16 · EU-Central
- Object storage Cloudflare R2 · EU region pinning
- CDN edge Amsterdam · Frankfurt · Paris · London
02
Row-level tenant isolation
Multi-tenancy that isn't a polite suggestion. Every row in 109 database tables carries a tenant_id with a PostgreSQL Row-Level Security policy enforced at the database layer. The application layer can't bypass it, only a narrowly-scoped admin client can, and only for auth.
- 40+ RLS policies across the schema
- Dual Prisma client RLS-bound by default
- SET app.current_tenant_id before every request
03
Authentication you can't replay
Passwordless OTP login. JWT access tokens expire in 15 minutes. Refresh tokens rotate; if an old one is reused, the entire family is revoked and the user is logged out everywhere. Tokens hashed with SHA-256, never stored in plaintext.
- JWT 15-minute access, 7-day refresh, rotated
- Family-based theft detection, reuse = revoke
- API keys bcrypt-hashed, 8-char prefix lookup
04
Audit every destructive thing
Every create, update, delete, role change, module toggle, plan change, import, export, sync, and impersonation event lands in the audit log. Filterable by user, action, date range. Exportable on demand. Kept for the lifetime of the tenant.
- 14 action types tracked end-to-end
- Filterable per-user, per-action, per-window
- Exportable CSV / JSON on request
05
Secrets out of code · always
Shopify access tokens encrypted at rest. Webhook payloads verified by HMAC against per-store secrets. Claude calls go through a circuit breaker. Sentry catches errors with PII scrubbing. Health endpoints are public, detailed health is SUPER_ADMIN only.
- HMAC-verified Shopify webhooks · per-store secret
- Encrypted Shopify tokens · at-rest
- Circuit breakers on Claude & Shopify API
06
Roles & least privilege
Eight roles from SUPER_ADMIN down to VIEWER plus supplier-side roles. Module-gated features, tenants only see modules their plan enables. Permission matrix enforced at the API layer; SUPER_ADMIN impersonation always emits an audit event.
- 8 roles + supplier portal subset
- Module gates tenant-level on/off
- Impersonation audited start & end