Tenant Service — Service Overview
Status: populated
Owner: TBD
Last updated: 2026-04-18
Companion: Service Template · 03 platform-services · 02 DDD
1. Purpose
The tenant-service is the authoritative owner of the legal entity (tenant) on the Ghasi-eHealth platform. It governs tenant onboarding and lifecycle (pending → active → suspended → terminated), subscription management, RBAC/ABAC policy (authorization), user profiles and org membership, org hierarchy governance, and data-residency configuration. It is the platform's authorization hub: downstream services resolve roles, memberships, and permission grants against tenant-service.
2. Bounded context
Tenant, Authorization & Membership — classified as Generic / Supporting. Runs in-house because:
- Multi-tenant data isolation enforced at DB level via
tenant_id column + RLS.
- Authorization policy (RBAC/ABAC evaluate) is tenant-sensitive and must be evaluated in-cluster.
- Org hierarchy is tenant-owned; structure varies by country profile (AFG MoPH, UAE DOH, private hospital).
- SCIM-driven provisioning requires tight integration with identity-service events.
3. Responsibilities
| Area | What tenant-service owns |
|---|
| Tenant lifecycle | Create (PENDING), activate, suspend, reactivate, terminate; orchestrates root hierarchy node + admin user + always-on license seeding on activation |
| Subscription management | Tier (STARTER / PROFESSIONAL / ENTERPRISE), contract dates, expiry events |
| Tenant configuration | Config KV store with allow-listed keys; branding, MFA policy, session timeouts |
| Org hierarchy | HierarchyNode tree (organization → facility → department → ward → bed); country-profile-based structure |
| RBAC/ABAC | Role definitions, role assignments to users at nodes, permission grants, evaluate() decision endpoint |
| User profiles | Provider profiles (name, specialty, credentials) for clinical users; links to UserId in identity-service |
| Org membership | User ↔ node membership; multi-node assignments; status transitions |
| FHIR Organization | Tenant is modelled as FHIR Organization resource via interop-service bridge |
4. Non-responsibilities
| Area | Owner |
|---|
| Authentication / credentials / sessions | identity-service |
| Module licensing | identity-service |
| Notification delivery | communication-service |
| Audit log storage | audit-service |
| Platform operator console (cross-tenant oversight) | platform-admin-service |
| Billing transactions | billing-service |
5. Upstream & downstream dependencies
5.1 Upstream (services tenant-service calls or consumes events from)
| Dependency | Pattern | Purpose |
|---|
| identity-service | Event consumer (identity.user.registered.v1) | Provision user profile; link UserId to org membership |
| identity-service | Internal HTTP (GET /internal/identity/providers/:id/identity) | Identity package for evaluate() context |
| facility-service | Internal HTTP | Hierarchy cross-reference for facility-level node creation |
| config-service | Pull | Platform runtime config (hierarchy profile defaults) |
5.2 Downstream consumers
| Consumer | Pattern | What they consume |
|---|
| identity-service | Event consumer | tenant.activated, tenant.suspended, tenant.terminated for session management and user seeding |
| All services | Internal HTTP (GET /internal/tenant/tenants/:id) | Tenant status / active check |
| All services | JWT claim tid | Trust tenant-scoped requests |
| platform-admin-service | Internal HTTP + events | Cross-tenant health / oversight |
| communication-service | Event consumer | tenant.activated, tenant.user.invited for onboarding emails |
| audit-service | Event consumer | All tenant lifecycle events |
6. Slice involvement
| Slice | Scope | Milestone |
|---|
| S0 — Foundation | Tenant lifecycle, basic config, hierarchy root, simple RBAC, user profiles | M0 |
| S1 — Hierarchy & membership | Full hierarchy tree, multi-node membership, permission grants, SCIM | M1 |
| S2 — ABAC & federated | ABAC policy engine, context-aware evaluate(), external IdP membership sync | M2 |
| S4 — Enterprise | Advanced ABAC (attribute policies), freeze mode, idempotency hardening | M3 |
7. Architecture diagram
8. Key design decisions
- AuthN vs AuthZ split. identity-service owns who you are; tenant-service owns what you can do within a tenant. Prevents circular dependencies.
- Activation is orchestrated.
POST /admin/tenants/:id/activate is a saga: create root HierarchyNode → seed Tenant Admin user in identity-service → seed always-on licenses. Bounded retries with backoff; tenant stays PENDING on failure.
- Hierarchy nodes. All org structure (facility, dept, ward) lives in tenant-service as
HierarchyNode aggregates, not in a separate service. This reduces fan-out for authorization path.
- RBAC first, ABAC later. S0 delivers role-based access (TENANT_ADMIN, CLINICIAN, NURSE, PATIENT). ABAC attribute policies are S2.
- FHIR Organization. Tenant is exposed as FHIR
Organization via interop-service bridge. Tenant-service owns the source record; FHIR representation is derived.
9. Source reconciliation
| Concern | Decision |
|---|
Legacy tenant module | Core tenant lifecycle + config retained; schema updated to ULID IDs and RLS |
Legacy hierarchy module | Merged into tenant-service — HierarchyNode is a tenant aggregate |
Legacy access-policy module | Moved from identity-service into tenant-service — RBAC/ABAC is a tenant concern |
| FHIR Organization | Exposed via interop-service bridge; tenant-service owns source record |
| Legacy FR prefixes | FR-TEN-* → FR-TENANT-*; FR-ACPOL-* → FR-TENANT-ACC-* |