B2B SaaS auth provider — SSO, directory sync, SCIM, organization management. В BloodGPT задействован в b2b-platform, b2b-api, phr; для patient-portal обсуждался как design proposal (session 871a7608), не реализован.
Где используется в BloodGPT (canonical из INFRA/services-architecture.md)
- b2b-platform — Next.js, WorkOS + Google OAuth. Admin/staff dashboard.
- b2b-api — auth для backend API (валидация tokens из WorkOS).
- phr (B2C consumer портал на
phr.bloodgpt.tech) — Next.js, Prisma, WorkOS. Потребительский portal с AI-чатом и оплатой.
Где НЕ используется (но обсуждалось)
- patient-portal (
apps/patient-portal) — tech stack: Next.js + Prisma + Mailgun. Без WorkOS в текущей реализации. Что-то внутреннее (вероятно session-based через Prisma + email magic-link через Mailgun).
В session 871a7608 (Feb 13-16, 2026) обсуждался дизайн multi-tenant patient-portal flow с интеграцией WorkOS — single redirect_uri + per-tenant org-context через query parameter. Это не существующее состояние, а design proposal для рассматриваемой feature multi-tenancy. Не реализовано на момент сессии.
Multi-tenant pattern (предложен в 871a7608, не в production)
Single redirect_uri на всех tenants:
https://portal.bloodgpt.tech/auth/callback
Tenant определяется через WorkOS authorize URL parameter:
authkit.bloodgpt.tech/sign-in
?organization=org_01H... ← конкретная org для login form
&redirect_uri=portal.bloodgpt.tech/auth/callback
&state={"return_to": "..."} ← куда вернуть после auth
WorkOS показывает login с org branding. Callback exchange code → session, set cookie, redirect на state.return_to.
См. single-workos-redirect (TBD создать после фактической имплементации) для rationale, если решение реально применят.
Cross-domain cookie ограничение
Для subdomain-based tenants ({hash}.portal.bloodgpt.tech) — cookie Domain=.portal.bloodgpt.tech шарится через wildcard.
Для client-owned доменов (patient.pzalab.com, Phase 2 в cloudflare-custom-hostnames) — cookie не пересекает domain boundary. Решение — token-redirect: callback на portal.bloodgpt.tech создаёт one-time Redis token (TTL 30s), redirect на patient.pzalab.com/auth/exchange?token=xyz, там обмен на cookie на правильном домене.
Capabilities
- SAML / OIDC SSO для enterprise customers
- Directory Sync (Okta, Azure AD, Google Workspace)
- SCIM (User provisioning)
- Per-organization branding
- Organization Feature Flags — per-org rollout фичей через
workos.organizations.listOrganizationFeatureFlags({organizationId}). Используем это вместо отдельной БД-таблицы / LaunchDarkly / Statsig. - WorkOS Custom Domain (платный) —
auth.client.comвместоauthkit.bloodgpt.tech. Не настроено.
Feature flags — паттерн использования
apps/b2b-platform/src/lib/workos.ts:isFeatureFlagEnabled(workosOrgId, flagSlug):
- Один централизованный helper, fail-closed на ошибках (если WorkOS API упал — фича считается выключенной для всех orgs, чтобы случайно не открыть gated функционал)
autoPagination()— обходит все страницы (флаг на page 2+ не должен silently читаться как disabled)- Slug-based:
FEATURE_FLAGS = { LLM_JUDGE: "llm-judge" }в коде, в WorkOS dashboard включается per-organization
Текущие флаги:
| Slug | Где проверяется | Контекст |
|---|---|---|
llm-judge | DQD cron (evaluation-judge.function.ts), org-monitoring API endpoint | Per-org rollout LLM judge оценок (data-quality-dashboard) |
Это generic pattern для постепенного rollout новых pipeline’ов / фичей per organization. Когда появятся следующие флаги (например, для FHIR single-pass, для нового survey, для ClinicalImpression-based output), ожидается тот же подход — slug в FEATURE_FLAGS enum, проверка через isFeatureFlagEnabled, переключение в WorkOS dashboard.
Связано
- cloudflare-custom-hostnames — multi-tenant custom domain routing
- saas-tenant-routing — full auth + routing flow (если/когда реализуют)
- google-healthcare-api —
Organization.workosOrgIdполе связывает WorkOS org с FHIR dataset - data-quality-dashboard — потребитель
llm-judgefeature flag для per-org rollout
Источники
Сноски
-
WorkOS docs, accessed 2026-05-17, https://workos.com/docs. ↩
-
Сессия
ildar/871a7608, 2026-02-13 — design proposal для patient-portal multi-tenant flow. ↩