Skip to main content

Platform architecture

Haste Health uses a hierarchical multi-tenant architecture with two levels of isolation: Tenants and Projects. This design provides secure data separation and flexible resource organization for healthcare applications.

Architecture Overview

Haste Health
└── Tenant (Organization)
├── System Project (Special)
│ ├── IdentityProvider resources
│ ├── User resources
│ └── Authentication configuration

└── User Projects (Multiple)
├── Membership resource (links Users to Projects)
├── Patient resources
├── Observation resources
├── Condition resources
└── All other FHIR resources

Tenants

A Tenant represents the top-level organizational boundary in Haste Health. Each tenant is a completely isolated environment with its own:

  • Authentication and authorization configuration
  • User management
  • Projects and data
  • Identity providers

Tenant Isolation

Tenants provide complete data isolation:

  • Resources in one tenant cannot access resources in another tenant
  • Authentication tokens are scoped to a specific tenant
  • Each tenant has independent configuration
  • API endpoints are tenant-specific

Tenant URL Structure

All API requests are scoped to a tenant:

https://api.haste.health/w/{tenant}/{project}/api/v1/fhir/{version}

Example:

https://api.haste.health/w/acme-health/production/api/v1/fhir/r4

Where:

  • acme-health is the tenant identifier
  • production is the project identifier
  • r4 is the FHIR version

Projects

A Project is a FHIR resource that provides resource isolation within a tenant. Each project contains its own set of FHIR resources and operates independently.

Project Resource

Projects are defined using the custom FHIR Project resource type with the following key properties:

  • ID: Unique identifier for the project
  • Name: The name of the project
  • FHIR Version: R4 or R4B

Project Isolation

Resources are strictly isolated by project:

  • A Patient in Project A cannot reference an Observation in Project B
  • Search operations are scoped to the current project
  • Access policies are project-specific
  • Resource references must be within the same project

Multiple Projects

Tenants can have multiple projects for different purposes:

Use Cases:

  • Environment separation: development, staging, production
  • Department isolation: cardiology, oncology, emergency
  • Application separation: patient-portal, clinical-system, analytics
  • Client isolation: Each customer gets their own project

Example Setup:

Tenant: hospital-network
├── System Project
├── cardiology-dept
├── oncology-dept
├── emergency-dept
└── analytics-warehouse

System Project

The System Project is a special, reserved project that exists in every tenant. It stores tenant-level configuration and authentication resources.

Purpose

The System Project contains resources that manage the tenant itself:

  • IdentityProvider: External authentication provider configurations (OIDC, SAML)
  • User: User accounts and profiles
  • ClientApplication: OAuth clients for authentication
  • AccessPolicyV2: Authorization policies

System Project Characteristics

Read-Only Enforcement:

  • System resources are protected from modification in certain contexts
  • System-created projects cannot be deleted
  • Critical configuration is preserved

Special Access:

  • Authentication flows access the System Project to verify users
  • User management happens in the System Project
  • Identity provider configuration is centralized

Automatic Creation:

  • Created automatically when a tenant is provisioned
  • Always has the identifier: system
  • Cannot be deleted or renamed

Resources in System Project

IdentityProvider

External identity providers for federated authentication:

{
"resourceType": "IdentityProvider",
"name": "My Identity Provider",
"status": "active",
"accessType": "oidc",
"oidc": {
"authorization_endpoint": "idp_authorization_endpoint",
"token_endpoint": "idp_token_endpoint",
"jwks_uri": "idp_jwks_uri",
"scopes": [
"openid profile"
],
"client": {
"clientId": "idp-client",
"secret": "idp-client-secret"
},
"pkce": {
"code_challenge_method": "S256",
"enabled": true
}
}
}

View IdentityProvider Documentation →

User

User accounts associated with the tenant:

{
"resourceType": "User",
"email": "bob@myhealth.health",
"role": "admin"
}

View User Documentation →

Working with Projects

Creating a Project

Create a new project via the FHIR API:

POST /w/{tenant}/system/api/v1/fhir/r4/Project
Content-Type: application/fhir+json

{
"resourceType": "Project",
"name": "MY CLINIC",
"fhirVersion": "r4",
"identityProvider": [
{
"reference": "IdentityProvider/my-idp"
}
]
}

Note: Projects are created in the System Project context but represent separate data containers.

Switching Projects

To work with resources in different projects, change the project in the URL:

# Access production project
GET /w/acme-health/production/api/v1/fhir/r4/Patient

# Access staging project
GET /w/acme-health/staging/api/v1/fhir/r4/Patient

Listing Projects

Query available projects:

GET /w/{tenant}/system/api/v1/fhir/r4/Project

Deleting a Project

Delete a user-created project:

DELETE /w/{tenant}/system/api/v1/fhir/r4/Project/cardiology

Restrictions:

  • System-created projects (like system) cannot be deleted
  • All resources in the project are deleted
  • This operation is permanent

URL Structure Explained

Complete URL Anatomy

https://api.haste.health/w/{tenant}/{project}/api/v1/fhir/{version}/{resourceType}/{id}
↓ ↓ ↓ ↓ ↓
Tenant Project FHIR Version Resource Resource ID
Isolation Isolation Type

Examples

Patient in production project:

https://api.haste.health/w/acme-health/production/api/v1/fhir/r4/Patient/123

User in system project:

https://api.haste.health/w/acme-health/system/api/v1/fhir/r4/User/user-456

Search in specific project:

https://api.haste.health/w/acme-health/cardiology/api/v1/fhir/r4/Observation?patient=Patient/123

Authentication Context

Token Scoping

Authentication tokens are scoped to:

  1. https://haste.health/tenant: Which organization
  2. https://haste.health/project: Which project within the tenant

JWT Token Claims:

{
"sub": "xltz0pcjiekiseeai2deaht4dy",
"exp": 1764630902,
"aud": "admin-app",
"scope": "offline_access openid email profile fhirUser system/*.cruds",
"https://haste.health/tenant": "ohio-health",
"https://haste.health/project": "my-project",
"https://haste.health/user_role": "admin",
"https://haste.health/user_id": "user-id",
"https://haste.health/resource_type": "Membership",
"https://haste.health/access_policies": [],
"https://haste.health/membership": null
}

Project Access Control

Users must have explicit access to projects:

  1. User authenticates (System Project validates credentials)
  2. Project Membership resources determine project access
  3. Project Access policies grant resource-level permissions
  4. Tokens are scoped to accessible projects

Use Cases and Patterns

Multi-Environment Setup

Separate projects for different deployment stages:

Tenant: healthcare-app
├── system (Authentication & config)
├── development (Dev environment)
├── staging (QA environment)
└── production (Live system)

Benefits:

  • Test changes in development before production
  • Isolate staging data from production
  • Same authentication across environments

Departmental Isolation

Separate projects per hospital department:

Tenant: city-hospital
├── system
├── emergency
├── cardiology
├── oncology
└── radiology

Benefits:

  • Department-specific access control
  • Data isolation between departments
  • Specialized workflows per department

Customer/Client Separation

Each customer gets their own project:

Tenant: health-saas-provider
├── system
├── customer-a
├── customer-b
└── customer-c

Benefits:

  • Complete data isolation per customer
  • Customer-specific configurations
  • Independent backup and recovery

Application Separation

Different applications in different projects:

Tenant: health-system
├── system
├── patient-portal
├── clinical-emr
└── analytics

Benefits:

  • Application-specific data models
  • Prevent cross-application data leaks
  • Independent scaling and optimization

Best Practices

Project Design

Do:

  • Use descriptive project names (cardiology-dept, not proj1)
  • Plan project boundaries based on access control needs
  • Document project purposes and ownership
  • Use consistent naming conventions

Don't:

  • Create too many projects (adds complexity)
  • Mix unrelated data in the same project
  • Use projects as temporary storage
  • Share projects across different customers

Resource Organization

Do:

  • Keep related resources in the same project
  • Use references within the same project
  • Plan for data migration when restructuring
  • Regular project audits and cleanup

Don't:

  • Create cross-project resource references
  • Store System Project resources in user projects
  • Duplicate configuration across projects unnecessarily

System Project

Do:

  • Limit access to System Project resources
  • Centralize identity provider configuration
  • Maintain user accounts in System Project

Don't:

  • Store clinical data in System Project
  • Modify system-created resources without understanding impact
  • Share System Project credentials

Summary

Haste Health's tenant and project architecture provides:

  • Two-level isolation: Tenants for organizations, Projects for data separation
  • System Project: Special project for authentication and configuration
  • Flexible organization: Multiple projects per tenant for any use case
  • Complete isolation: Resources strictly contained within projects
  • Scalable design: Support for multi-environment, multi-department, and multi-customer scenarios
  • Security: Multiple layers of access control and data separation

This architecture enables healthcare organizations to securely manage multiple applications, departments, or customers within a single Haste Health deployment while maintaining strict data isolation and access control.