Multitenancy

Bosch IoT Things service provides various ways to support solution developers in creating multitenant-ready applications by allowing to restrict the access rights on things and their messages at different levels.

Multitenancy as a principle

Multitenancy is the capability of a single application instance to handle different tenants while the strict separation of their data is ensured.

This principle is fully implemented by the Things service:

  • The cloud platform marketplace will not show any customer who else has booked our service
  • When working with a thing we apply strict control by always:
    • Identifying which solution tries to call the service,
    • Authenticating technical clients or users, and
    • Authorizing technical clients and user based on the thing’s own data.

Permissions on a thing

Our main concept is, that a thing belongs in the first place to the solution which has “created” the thing. Thus the solution is fully responsible for setting the initial permission for the specific thing.

  • To ensure all your solution parts which need to access your things are not handicapped, grant all your client IDs permission on the thing.
  • In case a thing is to be accessible for users you can benefit from the full integration with Bosch IoT Permissions service. As that service is also multitenant-ready, it can assure a strict tenant orientated management on all its entities. Thus, a tenant’s data (e.g. user, groups, roles etc.) and services (e.g. application data registered at the Permissions service) are by default not visible to other tenants (data segregation). As a result, each tenant can manage his own data and his offerings to other tenants. The IDs for users, groups, roles etc. provided by Bosch IoT Permissions can there be clearly assigned to the rightful tenant. However, please be aware that Bosch IoT Things will not prevent someone with full permission on a thing to grant access to a user belonging to another tenant.
  • In case you register your solution with its own roles and permissions within Bosch IoT Permissions you can also use the tenant relation model described there, and help your solution by using such IDs to take care of data segregation (e.g. if you also store or cache things, apart of our persistence layer).
  • Given a thing is pre-commissioned by your solution and needs to be associated to a specific tenant at a later point in time, make sure to assign the right access control information while someone triggers a claiming process, and to not lock your solution clients out completely.

Tenant identifier included in namespace

In addition to the concept on how you can create a thing ID (see Things and features, regarding multitenancy the best practice would be to include the tenant identifier within the namespace. This would allow to reflect the affiliation of a thing to a distinct tenant, even at the persistence level. However, always on top make sure to set the rightful actors as authorized subjects in the thing’s policy.

Including the tenant information is useful for either a setup where different subscriptions of the Things service are used for different tenants, or for a setup where a common Things service subscription is used. In the latter case, please be aware of restrictions regarding the number of namespaces per instance. See restrictions.

Example 1

Tenant 1 and Tenant 2 will share your solution but must not be aware of the existence of one another:

Tenant 1 Tenant 2
Solution ID 123 123
Device Integration Client 123:deviceIntegration 123:deviceIntegration
Web UI Client 123:WebUI 123:WebUI
Namespace com.bosch.iot.maker.tenant1 com.bosch.iot.maker.tenant2
Thing ID com.bosch.iot.maker.tenant1:sensorxyz com.bosch.iot.maker.tenant2:sensorxyz
Policy Tenant1-Policy authorizes
- users, groups, roles from own Tenant
- your solution clients
Tenant2-Policy authorizes
- users, groups, roles from own Tenant
- your solution clients

The setup could be as shown in following picture:

tenants

Example 1 - policy for a thing owned by tenant 1

{
  "policyId": "com.bosch.iot.maker.tenant1:sensorxyz",
  "entries": {
    "User-of-Tenant1-Policy": {
       "subjects": {
          "iot-permissions:111-my-all-users-group-ID": {
             "type": "iot-permissions-groupid"
          }
       },
       "resources": {
          "thing:/": {
            "grant": ["READ", "WRITE"],
            "revoke": []
          },
          "policy:/": {
            "grant": ["READ", "WRITE"],
            "revoke": []
          },
          "message:/": {
            "grant": ["READ", "WRITE"],
            "revoke": []
          }
       }
    },
    "Solutions-Policy": {
      "subjects": {
         "iot-things:123:WebUI": {
           "type": "iot-things-clientid"
         },
         "iot-things:123:deviceIntegration": {
            "type": "iot-things-clientid"
         }
      },
      "resources": {
         "thing:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
         }
      }
    }
  }
}

Example 1 - policy for a thing owned by tenant 2

{
  "policyId": "com.bosch.iot.maker.tenant2:sensorxyz",
  "entries": {
    "User-of-Tenant2-Policy": {
       "subjects": {
            "iot-permissions:222-my-all-users-group-ID": {
            "type": "iot-permissions-groupid"
          }
       },
       "resources": {
          "thing:/": {
            "grant": ["READ", "WRITE"],
            "revoke": []
          },
          "policy:/": {
            "grant": ["READ", "WRITE"],
            "revoke": []
          },
          "message:/": {
            "grant": ["READ", "WRITE"],
            "revoke": []
          }
       }
    },
    "Solutions-Policy": {
      "subjects": {
           "iot-things:123:WebUI": {
           "type": "iot-things-clientid"
         },
           "iot-things:123:deviceIntegration": {
           "type": "iot-things-clientid"
         }
      },
      "resources": {
         "thing:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
         }
      }
    }
  }
}

Tenant identifier included in client suffix

A further option to make sure one tenant never get to see a thing of another tenant is to fully customize the “tenant-specific” view on the data. In our example we have extended the technical client ID with a tenant identifier, but you can apply the method also for technical client instances respectively. However, always on top make sure to set the rightful actors as authorized subjects.

Example 2

Tenant 1 and Tenant 2 will share your solution but must not be aware of the existence of one another:

Tenant 1 Tenant 2
Solution ID 123 123
Device Integration Client 123:integration 123:integration
Web UI Client 123:WebUItenant1 123:WebUItenant2
Namespace com.bosch.iot.maker.tenant1 com.bosch.iot.maker.tenant2
Thing ID com.bosch.iot.maker.tenant1:sensorxyz com.bosch.iot.maker.tenant2:sensorxyz
Policy Tenant1-Policy
authorizes only users, groups, roles from own Tenant
Tenant2-Policy
authorizes only users, groups, roles from own Tenant

tenants example 2

Example 2 - policy for a thing owned by tenant 1

{
  "policyId": "com.bosch.iot.maker.tenant1:sensorxyz",
  "entries": {
    "User-of-Tenant1-Policy": {
      "subjects": {
         "iot-permissions:111-my-all-users-group-ID": {
           "type": "iot-permissions-groupid"
         }
      },
      "resources": {
         "thing:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
         },
         "policy:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
         },
         "message:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
         }
      }
    },
    "Solutions-Policy": {
      "subjects": {
         "iot-things:123:WebUItenant1": {
           "type": "iot-things-clientid"
         },
         "iot-things:123:deviceIntegration": {
           "type": "iot-things-clientid"
         }
      },
      "resources": {
         "thing:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
         }
      }
    }
  }
}

Example 2 - policy for a thing owned by tenant 2

{
  "policyId": "com.bosch.iot.maker.tenant2:sensorxyz",
  "entries": {
    "User-of-Tenant2-Policy": {
      "subjects": {
        "iot-permissions:222-my-all-users-group-ID": {
          "type": "iot-permissions-groupid"
        }
      },
      "resources": {
         "thing:/": {
          "grant": ["READ", "WRITE"],
          "revoke": []
        },
         "policy:/": {
          "grant": ["READ", "WRITE"],
          "revoke": []
        },
         "message:/": {
          "grant": ["READ", "WRITE"],
          "revoke": []
        }
      }
    },
    "Solutions-Policy": {
      "subjects": {
        "iot-things:123:WebUItenant2": {
          "type": "iot-things-clientid"
        },
        "iot-things:123:deviceIntegration": {
          "type": "iot-things-clientid"
        }
      },
      "resources": {
         "thing:/": {
           "grant": ["READ", "WRITE"],
           "revoke": []
        }
      }
    }
  }
}
Imprint Legal info Privacy statement