Security > System User
System User
The system user is a system object in ThingWorx designed with the special purpose of making the management of internal service permissions easier, while still allowing the external API layer to be permissioned on a user-by-user basis. Normally, when a user calls a service, that user must have permission to the called service as well as permissions to any other services called from within the initial called service. For example, a user executes a service named GetMachineRunTimeHistory on a Thing that internally calls QueryStreamEntriesWithData and GetDataTableEntryByKey. Without using the system user, the user that called GetMachineRunTimeHistory also needs explicit permissions to execute QueryStreamEntriesWithData and GetDataTableEntryByKey.
With the system user, if a custom service is called from within a service or subscription (a wrapped service call), and the system user is permitted to execute the service, the service will be permitted to execute regardless of the user who initially triggered the sequence of events, scripts, or services. However, the user will not be able to directly call the wrapped service itself (from the example above, QueryStreamEntriesWithData or GetDataTableEntryByKey unless the user is explicitly permitted).
This practice allows an administrator to lock down externally-accessible surface APIs using users and groups with explicit access enablement. While it is always recommended to depend on user propagation to wrap service calls, the system user can make management of internal services calls easier from a permission management perspective.
The system user can be added to the Administrators group. Doing this will effectively grant all users full permission on everything nested within a service call – all services invoked inside a custom service will succeed, regardless of the invoking user’s permissions.
We do not recommend using the system user to bypass security or to alleviate the need to carefully design and implement a secure application. Best practice dictates that you should limit the reliance on the system user to specific use cases and not as a general workaround to user propagation practices.
The system user is optional. If the system user is not assigned to a service, ThingWorx will check the permissions of the user who made the original request for all subsequent wrapped services.
System User Example
Granting system user permission to run a service means that every user will be granted permission to run that service from within a custom service, but not necessarily granted permission to call that service directly. To use it properly:
1. Give the system user permission to run a service, but restrict that service's permissions so that other users do not have permission to run that service.
2. Write a custom service that calls that restricted service, then give users permission to run the custom service but not the restricted service.
3. Users will be able to run that custom service, even though they do not have permission to run the restricted service.
To further illustrate this concept using an example, consider the following use case:
You want to write a custom service where users are shown the status of a particular connected device, named CustomService1. In order to do that, CustomService1 could use the SearchDevices service on the DeviceFunctions resource to look at all devices on the platform, then filter out the results to return only the particular device.
However, permissions are checked not only for CustomService1, but for every service call made within CustomService1. The user would need permission to run the SearchDevices service in order to successfully call CustomService1, otherwise the call to CustomService1 will fail. Giving the user permission to call SearchDevices is not ideal because you may not want the user to have access to the status of every device, only the particular device in question.
The system user can resolve this. When a service is executed directly, the permissions of that user is checked to determine if it has permission. This is true for any service, including all custom services. However, when a service is executed from within a custom service, there are actually two permissions checked: the user's permission, and the system user's permission. If either the user or the system user have permission to run the service within the custom service, the within service is executed as if the user has permission to run it. Since SearchDevices is only being called inside CustomService1 and is not being called directly, you can give system user permission to run SearchDevices. When the user calls CustomService1, the permissions check will occur, seeing that User1 does not have permission, but also seeing that system user does have permission. As a result, SearchDevices will be executed as if the user has permission. If the user ever attempts to call SearchDevices directly without calling it from within CustomService1, then the system user's permission would not apply and the user would be denied permission.