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-healthis the tenant identifierproductionis the project identifierr4is 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"
}
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:
- https://haste.health/tenant: Which organization
- 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:
- User authenticates (System Project validates credentials)
- Project Membership resources determine project access
- Project Access policies grant resource-level permissions
- 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, notproj1) - 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.