Canopy SaaS environments offer our customers a fully multi-tenant solution based on the “one application, one database” model. This provides our customers with the most cost-effective means of scaling on Canopy. This solution is transparent to our customers and may result in data being stored across multiple physical database instances for performance reasons. Because Canopy utilizing a micro-service architecture, each service maintains its own data which may also further delineate physical database instance choice. However, all data across all databases carries a link to the tenant identifier for the customer so that access controls can be maintained.
Hierarchy and Tenancy
In Canopy, the Hierarchy (organizational structure) determines the tenancy of data. All parent records within the data are stored with a path attribute that is populated with an appropriate hierarchy to govern tenancy. The hierarchy is a directed graph structure that can be constructed as deep and wide as the customer has need for in their organization. When stored as the path attribute, the hierarchy takes the form of a string that resembles a folder path, for example /Canopy/A/B.
Users within Canopy are tenant entities and therefore exist at a Hierarchy location and have a path tenant identifier. Users have roles that govern the breadth of data and actions that they have access to within Canopy. The hierarchy association governs the depth of the data that the user has access to within Canopy. By default, Users within Canopy have access to data that exists at their level of the hierarchy and down. For example, consider this user:
-
User: Example User
-
Hierarchy: /Canopy/A
-
Role Permissions:
- Device: Create, Read, Update, Delete
- Location: Read
And the following example use cases:
- User attempts to create a Device under /Canopy/A - result: success; the user has visibility to /Canopy/A and has create Device permission
- User attempts to create a Location under /Canopy/A - result: failure; the user has visibility to /Canopy/A, but does not have create Location permission
- User attempts to update a Device under /Canopy/A/B - result: success; the user has visibility to /Canopy/A/* and has update Device permission
- User attempts to read a Location under /Canopy/X - result: failure; the user has no visibility to /Canopy/X
Storage, Retrieval, and Modification of Tenant Data
Canopy tenancy is built in to all data storage, retrieval, and modification of tenant data via the libraries used for these functions, and is therefore not able to be bypassed. When a request to store, retrieve, or modify data is made, the User’s path is used as the default tenant filter. This filter can be added to by specifying the path parameter on the request, but the filter cannot be replaced via any mechanism. For example, a user with hierarchy /Canopy/A may add to their tenant filter so that they only see data that lives at /Canopy/A/B/C; but they may not replace their filter so that they might see data that lives at /Canopy/X. Canopy tests for the veracity of this capability with each release via automated test cases.