Easy & secure 3rd Party Application access to Cumulocity IoT
Overview
Cumulocity IoT does not have an API-key functionality which can be used to integrate 3rd party application. Still, it comes with a comprehensive user & role management combined with a very fine granular access management. The most obvious but less secure way to integrate 3rd party applications is to create a technical user in each tenant and use these credentials to access Cumulocity IoT. There are multiple downsides of this approach:
In tenants were SSO is configured you don’t want to or even can’t create “local” technical users.
There is, in most cases, no 1:1 relation between an external application and a technical user. Meaning, the risk is high that the user is deactivated / changed and the application loses the connection.
When a technical user is created humans tend to give unsecure non-generated passwords.
The roles assigned to a technical user might give permissions to things which is not intended.
And finally, when storing user + password credentials this could lead to data leaks compromising the technical user. In combination of 4, attackers can do really bad stuff in your Cumulocity IoT Tenant
In this article I will suggest & describe a proper, but yet undocumented, way to access Cumulocity IoT from a 3rd party application.
The Service User approach for microservices
To extend the platform Cumulocity IoT offers microservices. The authentication concept behind microservices are so called service user which are dynamically generated users in each tenant the microservice is subscribed to.
https://cumulocity.com/guides/microservice-sdk/concept/#users-and-roles
Service user*: A generated user that allows a microservice to access a subscribed tenant independent of a REST API invocation, for example, for initialization or regular jobs.*
The concept behind the service user is to use so called Bootstrap Credentials for each individual microservice to authenticate against the following API endpoint:
GET /application/currentApplication/subscriptions
The bootstrap credentials can be retrieved by the following authenticated request where application id is the ID of the created application / microservice within Cumulocity:
GET /application/applications/<APPLICATION_ID>/bootstrapUser
The process is visualized in the following illustration:
Only the bootstrap credentials must be provided to the microservice which is a very limited generated user to retrieve only the service user with assigned roles. Running within Cumulocity IoT this is provided via environment variables. Running outside of Cumulocity the bootstrap credentials must be provided.
When the application is created it should come with a payload containing some basic information like the type of the application but also in case of microservices an property called requiredRoles
which contains all the global role IDs that should be assigned to the service user.
In the example below we allow that the external application can read all device & events but is not allowed to create, update or delete any of them.
{
"name": "custom-application",
"type": "MICROSERVICE",
"key": "custom-application-key",
"requiredRoles": [
"ROLE_INVENTORY_READ",
"ROLE_EVENT_READ"
]
}
You can check the available global roles in the Open API specification.
Please note: Only global roles and permissions are supported by this approach. You cannot use Inventory Roles with service users.
That way you can control in your tenant by subscribing an application if and what kind of access it should have to your IoT device data. When unsubscribing the application from a tenant the service user & bootstrap user will be revoked.
Leveraging the Service User for 3rd Party Applications
For 3rd Party Applications we can adopt this. The only difference is that the 3rd Party Application mainly runs outside of Cumulocity IoT, so we need to do the following steps:
Create an application in the tenant we need access to.
Subscribe the application to the tenant/s.
Retrieving the bootstrap credentials.
Providing the bootstrap credentials to the 3rd Party Application.
The 3rd Party Application retrieves the service user (per subscribed tenant).
The 3rd Party Application authenticates with the service user (per subscribed tenant).
Multi Tenancy
Implementing this logic mentioned above also supports multi tenancy out of the box. In a scenario where the microservice is deployed in an enterprise tenant and subscribed to multiple sub tenants you can use the bootstrap credentials retrieved from the enterprise tenant to access all subscribed sub-tenants. Still you need to retrieve the service users for each tenant of course.
Benefits
Using this approach has many benefits in comparison to using a technical user.
The service user has a 1:1 relation to the 3rd Party application.
As the service user is generated by the system it cannot be deactivated or changed by mistake.
The generated service user has in most cases a much more secure password then manual created passwords
You don’t have to provide sensitive credentials to the 3rd Party application, only the bootstrap user for all the tenants where the application is subscribed to
Full multi tenant support: Provide the bootstrap credentials once and access multiple subscribed tenants (when desired).
Without changing any credentials in the 3rd Party App you can just revoke access to single tenants by just unsubscribing the application without impacting other tenants access.
And finally the core benefit is the configuration flow: It is s straight forward with much less maintenance involved. You don’t have to log in in all tenants, create technical users etc. but just subscribe the application to them to grant access (in multi-tenant environments).
Cons
The only downside of this approach is that the 3rd Party Application needs to implement logic mentioned above. It cannot just ask for Cumulocity IoT credentials and then authenticate all requests with them. It needs to perform the requests with the bootstrap user to fetch the service user (for each tenant). If the service user is persisted or requested on each request depends on the use case.
Summary
The service user of microservices is a good alternative for a technical user shared with a 3rd Party Application. When integrating 3rd Party Applications it should be considered to use the service user approach instead of using just technical users.