From e1d6f82328a7b0a4e6c1166eae2ff84a15da3135 Mon Sep 17 00:00:00 2001 From: Nestor Carvantes Date: Tue, 10 Aug 2021 04:18:34 -0500 Subject: [PATCH 1/2] docs: add multi-tenancy docs --- README.md | 2 ++ USING_MULTI_TENANCY.md | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 USING_MULTI_TENANCY.md diff --git a/README.md b/README.md index f598b52c..0d8b8f0f 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ git clone https://github.com/awslabs/fhir-works-on-aws-deployment.git If you intend to use FHIR Implementation Guides read the [Using Implementation Guides](./USING_IMPLEMENTATION_GUIDES.md) documentation first. +If you intend to do a multi-tenant deployment read the [Using Multi-Tenancy](./USING_MULTI_TENANCY.md) documentation first. + ## Architecture The system architecture consists of multiple layers of AWS serverless services. The endpoint is hosted using API Gateway. The database and storage layer consists of Amazon DynamoDB and S3, with Elasticsearch as the search index for the data written to DynamoDB. The endpoint is secured by API keys and Cognito for user-level authentication and user-group authorization. The diagram below shows the FHIR server’s system architecture components and how they are related. diff --git a/USING_MULTI_TENANCY.md b/USING_MULTI_TENANCY.md new file mode 100644 index 00000000..cd916355 --- /dev/null +++ b/USING_MULTI_TENANCY.md @@ -0,0 +1,53 @@ +# Multi-Tenancy + +Multi-tenancy allows a single `fhir-works-on-aws` stack to serve as multiple FHIR servers for different tenants. + +`fhir-works-on-aws` uses a pooled infrastructure model for multi-tenancy. This means that all tenants share the +same infrastructure (DynamoDB tables, S3 Buckets, Elasticsearch cluster, etc.), but the data +is logically partitioned to ensure that tenants are prevented from accessing another tenant’s resources. + +## Enabling multi-tenancy + +Use the `enableMultiTenancy` option when deploying the stack: + +```bash +serverless deploy --enableMultiTenancy true +``` + +**Note:** Updating an existing (single-tenant) stack to enable multi-tenancy is a breaking change. Multi-tenant +deployments use a different data partitioning strategy that renders the old, single-tenant, data inaccessible. +If you wish to switch from single-tenant to a multi-tenant model, it is recommended to create a new multi-tenant stack +and then migrate the data from the old stack. + +## Tenant identifiers + +Tenants are identified by a tenant Id in the auth token. There are 2 ways to include a tenant Id in the auth token: + +1. Add the tenant Id in a custom claim. This is the recommended approach. +The default configuration adds the tenant Id on the `custom:tenantId` claim + +1. Encode the tenant Id in the `aud` claim by providing an URL that matches `/tenant/`. +This can be useful when using an IDP that does not support custom claims. + +If a token has a tenant Id in a custom claim and in the aud claim, then both claims must have the same tenant Id value, +otherwise an Unauthorized error is thrown. + +The default deployment adds a custom claim `custom:tenantId` to the Cognito User Pool. You can manage the tenant Id value +for the different users on the AWS Cognito Console. The [provision-user.py](https://github.com/awslabs/fhir-works-on-aws-deployment/blob/mainline/scripts/provision-user.py) +script will also create users with a set tenant Id. + +## Additional Configuration + +Additional configuration values can be set on [config.ts](https://github.com/awslabs/fhir-works-on-aws-deployment/blob/mainline/src/config.ts) + +- `enableMultiTenancy`: Whether or not to enable multi-tenancy. +- `useTenantSpecificUrl`: When enabled, `/tenant//` is appended to the FHIR server url. + + e.g. A client with `tennatId=tenantA` would use the following url to search for Patients: + ``` + GET /tenant//Patient + GET https://1234567890.execute-api.us-west-2.amazonaws.com/dev/tenant/tenantA/Patient + ``` + Enabling this setting is useful to give each tenant a unique FHIR server base URL. + +- `tenantIdClaimPath`: Path to the tenant Id claim in the auth token JSON. Defaults to `custom:tenantId` From 8265dcafa8c333b514330a427501d9a184cac6e8 Mon Sep 17 00:00:00 2001 From: Nestor Carvantes Date: Wed, 11 Aug 2021 03:22:49 -0500 Subject: [PATCH 2/2] address PR comments --- USING_MULTI_TENANCY.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/USING_MULTI_TENANCY.md b/USING_MULTI_TENANCY.md index cd916355..520124f1 100644 --- a/USING_MULTI_TENANCY.md +++ b/USING_MULTI_TENANCY.md @@ -17,11 +17,14 @@ serverless deploy --enableMultiTenancy true **Note:** Updating an existing (single-tenant) stack to enable multi-tenancy is a breaking change. Multi-tenant deployments use a different data partitioning strategy that renders the old, single-tenant, data inaccessible. If you wish to switch from single-tenant to a multi-tenant model, it is recommended to create a new multi-tenant stack -and then migrate the data from the old stack. +and then migrate the data from the old stack. Switching from multi-tenant to a single-tenant model is also a breaking change. ## Tenant identifiers -Tenants are identified by a tenant Id in the auth token. There are 2 ways to include a tenant Id in the auth token: +Tenants are identified by a tenant Id in the auth token. A tenant Id is a string that can contain alphanumeric characters, +dashes, and underscores and have a maximum length of 64 characters. + +There are 2 ways to include a tenant Id in the auth token: 1. Add the tenant Id in a custom claim. This is the recommended approach. The default configuration adds the tenant Id on the `custom:tenantId` claim