Multitenancy
Introduction
In the Basic Service example, we learned to perform a heartbeat check on a service, in order to monitor its health.
Moreover, sample tests to expose the basic functionalities of a SOAJS service, and those of the IMFV.
In the oAuth Security example, one of the APIs from the Basic Service example will be secured with oAuth.
The example allowed the user to explain the integration of the oAuth service with a SOAJS service.
This example explores SOAJS' ability of multitenancy.
Multitenancy allows a collection of tenants/users to share the same set of resources (i.e., a database, service, etc) by allowing each tenant to access only the allowed portion of that resource, and prohibiting them from accessing resources of other tenants.
SOAJS allows different tenants to use the same service, each using their own settings, ACL and configurations.
This example also introduces the User Registration & Access Control (URAC) service, which holds records of all the tenants and its corresponding users.
Moreover, the example teaches how to benefit from multitenancy, and how to configure ACLs, in addition to securing the APIs using tenant keys.
Code Walkthrough
This page shows you how to interact with the example03 & URAC services after you install them and run them. It also demonstrates how SOAJS implements multitenancy.
The code walkthrough is located in a sub page and explained in depth. Click here to read the explanation.
Service Exploration
To turn on URAC in a development environment you just need to start the environment as follow
sudo soajs services start --env=example
Verify URAC
To verify if oauth is running you need to login to soajs console and
- go under deploy tab
- select environment example
- click on SOAJS catalog from the left menu
- expand URAC item
- click on maintenance operations
- select heartbeat
# go to examples/example03 and start the service cd soajs.examples/example03/ # start the soajs example environment sudo soajs services start --env=example # export necessary environment variables to create local awareness export SOAJS_ENV=EXAMPLE export SOAJS_SRVPORT=4023 export SOAJS_DEPLOY_MANUAL=1 export SOAJS_REGISTRY_API=127.0.0.1:21000 # start service node .
The service is now running and listens on port 4023. Therefore, its maintenance port is 5023.
Next, a heartbeat request is sent to check the health of the service.
curl -X GET "http://127.0.0.1:5023/heartbeat"
A response similar to the one below indicates a healthy functioning of the service.
{"result":true,"ts":1425372737466,"service": {"service":"example03","type":"rest","route":"/heartbeat"}}
Tenant Level Access Control
Using the Service APIs
As mentioned previously, this example is multitenant. Therefore, this tutorial simulates several tenants, which will be used across the examples that follow.
Package Name | Access to Service | Access Type |
---|---|---|
Example | NO | N/A |
Example2 | YES | FULL |
Example3 | YES | "buildName" |
The table above lists three packages. each package represents a list of permissions.
Example does not have access to the service.
Example2 has full access to the service.
Example3 has access to only the buildName API of the service.
What we also did is we create an example tenant and we gave added 3 applications one per package under this tenant where each application has its own API key and
Tenant Name | Application Name | Access to Service | Access Type |
---|---|---|---|
Tenant example | EXAMP_BASIC | NO | NA |
Tenant example | EXAMP_3ZE08 | YES | FULL |
Tenant example | EXAMP_4H6CQ | YES | "buildName" |
An application is defined as the combination of a tenant and a package assigned to that tenant.
buildName using EXAMP_BASIC
curl -X GET -H "key:4ea5db4c70b6168aeede6a8a56cb4624efdb6cb2cf3c7b88cbc1f5d97080a44f18083fa195e20dcc0b42496ae268ea91c657dd9b252b72de14c862e64f8522a9dbdaa1ce0f48ba2d5ed5eff49b47d0f728bddb2080c8cbc7bde3771116192b51" "http://127.0.0.1:20000/example03/buildName?lastName=Smith&access_token=valid_access_token"
The key sent with the request is that generated for EXAMP_BASIC
The response to the request is shown below
{"result": false,"errors": {"codes": [154],"details": [{"code": 154,"message": "Access denied: The service is not available in your current package."}]}}
buildName using EXAMP_3ZE08
curl -X GET -H "key:4ea5db4c70b6168aeede6a8a56cb46246ca38b1b4f801f090d5821bd76b339e34b8ddb9ac2cb7ffee220cf3e463ac9cdf3902e91720c8f56684d7d88287affc0092eeb37648e7bde4f565f509b1b384127022bc2c1c1581f4ba50e28564d1c5c" "http://127.0.0.1:20000/example03/buildName?lastName=Smith&access_token=valid_access_token"
The key sent with the request is that generated for EXAMP_3ZE08
{"result": true,"data": {"tenantName": "Client One","fullName": "John Smith"}}
Clearly, the response generated proves that the second application has access to the API, and the response came back with a positive result to the tenant's query.
More importantly, the response containts the name of the tenant that requested the query.
testGet using EXAMP_3ZE08
curl -X GET -H "key:4ea5db4c70b6168aeede6a8a56cb46246ca38b1b4f801f090d5821bd76b339e34b8ddb9ac2cb7ffee220cf3e463ac9cdf3902e91720c8f56684d7d88287affc0092eeb37648e7bde4f565f509b1b384127022bc2c1c1581f4ba50e28564d1c5c" "http://127.0.0.1:20000/example03/testGet?lastName=Smith&firstName=John&access_token=valid_access_token"
The response below contains the answer to the user's query.
{"result": true,"data": {"firstName": "John","lastName": "Smith"}}
testGetusing EXAMP_4H6CQ
curl -X GET -H "key:4ea5db4c70b6168aeede6a8a56cb4624079ff72a87d5174f5d880d546f326077dd82b8131322c2a5dbc02edec9d5ad7bfbfcf3730c2205850ffe7644e259ad2ee20280d25a1cfecdb7a62992920d2155cb30edffb6e53d49c528cc2e1ae54a6e" "http://127.0.0.1:20000/example03/testGet?lastName=Smith&firstName=John&access_token=valid_access_token"
The response to the request is shown below
{"result": false,"errors": {"codes":[159],"details":[{"code":159,"message":"System api access is restricted. api is not in provision."}]}}
In conclusion, multitenancy is a powerful approach that allows the sharing of the resources while ensuring the integrity and security of each tenants resources.
The examples above elaborate how SOAJS implements this concept, allowing numerous tenants to use the same service.
Our documentation provides a detailed explanation for the concepts of multitenancy and productization.
User Level Access Control
The examples above clearly exploit multitenancy using SOAJS, on the tenant level. Indeed, SOAJS permits several tenants to share the same resources (i.e., application, service, etc..).
The ACLs provide permissions for each tenant, thus restricting each tenant's access to what is included in the permissions list.
Interestingly, SOAJS does not enforce access control on the the tenant level only. The framework goes one step further and enforces is on the users of the same tenant.
Consider the following example of a company, composed of two departments: The IT department, and the financial department. The company represents the tenant, and each department
represents a user of that tenant. The IT department should only have access to the IT resources. It must not have access to the resources of the financial department.
The same thing applies for the financial department as well. In this regard, multitenancy on the user level is also supported by SOAJS.
Conclusion
In conclusion, multitenancy, productization and urac are efficient concepts that allow the tenants and users to share the available resources, in an optimized way, while respecting the privacy of each tenant/user's data,
using the Access Control Lists, which, as the name states, contain the permissions of each tenant/user.
- The ACL is explained in depth in the Access Levels section.
- Products and packages are explained in depth in the Productization section.
- Tenants, and applications are explained in the Multitenancy section.
- Finally users, groups and ACL overriding are explain in the URAC section.