Wednesday, April 30, 2014

Explaining the built-in SYSTEM and INTEGRATION users

If you have played with CRM long enough, you might have noticed the existence of 2 special user accounts: SYSTEM and INTEGRATION. In this post I’ll try to answer the typical questions I get around what these are and what you need to know about them.

Let me start with some of the facts and characteristics about these 2 user accounts which will help us draw some conclusions later on.

 

THE FACTS

1. SYSTEM and INTEGRATION users have a different SystemUserId (Guid) across all CRM organizations (and CRM Online organizations). To get their user ids you’d have to perform a query (or Advanced Find).

2. These users are very well hidden from the application. They are technically “disabled” and they are even filtered out from the “Disabled Users” view. If you’d like to see them you’d have to build your own Advanced Find without the default filters.

3. Nobody can log in CRM as either of these 2 users.

4. These users are read-only. You are not able to change their teams, security, FLS, business unit or any other field.

5. They do not consume a license.

6. These users are always on the root business unit.

7. They don’t have a mailbox or the ability to send or receive emails.

8. No security applies to these users (any action is allowed when executing as SYSTEM or INTEGRATION), all security validations are bypassed.

9. Unofficial fact: Seems like you cannot impersonate these users in CRM Online from outside of plugins. I haven’t been able to impersonate SYSTEM or INTEGRATION from an external application calling into CRM Online (however, works fine on my OnPrem orgs).

 

THE EFFECT

By now you might be wondering why do we even care about these obscure users. The answer is: we shouldn’t; there is a reason why they are so hidden and sometimes unheard of. However, you might also be thinking that if you have another application integrating with CRM then you could make use of [for example] the SYSTEM/INTEGRATION users to make all service calls into CRM. This way, whenever let’s say an audited record is updated via your integration then it will show as updated by INTEGRATION user which could be a neat indicator that the update came from an external system. This is technically possible (quite easy actually), all you have to do is set the CallerId in your proxy (OrganizationServiceProxy.CallerId or CrmConnection.CallerId) to their userId whenever you create your proxy from the external system to call into CRM, this is what it would look like:

image

Similarly, if you are working from a plugin, you can configure the plugin step to execute as SYSTEM or INTEGRATION user. You can configure that in the Plugin Registration Tool or the Development Toolkit:

image

So now that you know how to impersonate these users, let’s explore the details of why we would do so:

 

THE SCENARIOS

1. Elevation of Privileges.

You might have some business logic implemented in plugins which should bypass security checks (e.g. auto-calculated or rollup fields). In that case it might be useful to run the plugin as SYSTEM user. Additionally, you will see in the audit history that the record has been updated by SYSTEM user which gives us a hint that the update was made by an automated logic of a plugin. On the other hand, you have to be very careful when doing this. The reason is that a plugin can trigger another plugin or a workflow and you might end up with a chain of plugins/workflows triggering. Once you elevate the privileges, every action after that will also run in elevated privilege mode (SYSTEM). Therefore you need to make sure that whatever chain of plugins/workflows will be triggered is OK to execute as SYSTEM. For example, sending an email as SYSTEM will fail because that user does not have a mailbox/email address so if anywhere in your plugin chain you send an email then you might have a problem.

Here is an example: You have tasks with different priorities. The priority of the case is automatically taken from the highest priority of the tasks associated. Not all users have access to update the priority of the case but any user can update the priority of their task which will rollup to the case via a plugin. When a case priority is set to “1” a plugin will send a warning email to the case owner. If you impersonate SYSTEM to rollup the task priority to the case priority you need to make sure that in your plugin that sends the email you set the “from” field, otherwise CRM will try to send the email from SYSTEM which won’t work.

 

2. Generic “system” user for system operations

These special users can work whever you want to do actions on the system programmatically and tag the action to a generic system user. A typical example is when you have integrations with other systems and you want the automatic integration in CRM to execute as a generic system user. For example, if you have integration with ERP system, and whenever a new account is created in ERP it should also be created in CRM. In that case the accounts in CRM would be created by “SYSTEM” or “INTEGRATION” user if you use impersonation to perform the account create under one of those user accounts.

 

THE CAVEAT

As I mentioned earlier, impersonating these system accounts can have some bad side effects. The reason is that any action you perform under one of those user accounts can trigger plugins (which can trigger other plugins). You need to be very careful and make sure you understand that your impersonated action can trigger plugins then those plugins will also execute under the context of the SYSTEM /INTEGRATION accounts. Some plugins you might want to always execute under the context of the Calling User (depending on the scenario). The other things to consider is that these special accounts have no User Settings entity associated (they have no language, time zone, format, etc.) and in some cases your customizations might rely on the existence of user settings for every user account. For example, in some plugins you might check that the user’s language or time zone is in order to execute some business logic. This would break if the plugin executes as SYSTEM/INTEGRATION.

Another issue with these accounts is that they are always at the root business unit. If a record is created by one of these accounts, the record will belong to the root business unit which can mean that many users in child business units will have no visibility into the record (unless they have organization-level privileges). You would have to make sure that you assign the records when they get created if you need those records to sit on different business units other than the root.

 

THE CONCLUSION / ALTERNATIVE SOLUTION

Impersonating SYSTEM/INTEGRATION can be useful for some scenarios for privilege elevation purposes; however, it does have its side effects or considerations as explained above. You need to carefully consider whether it makes sense to impersonate these user accounts given the side effects. Another alternative would be to create a new user (e.g. “CRM System User”) in AD and CRM and chose to impersonate that user whenever you are performing “system” transactions that should execute with elevated privileges. The advantage of doing that is that now you can control exactly how you configure that “super user”. You can choose to give it System Administrator role or a more restrictive role. You can decide whether or not to give it field-level permissions and in what business unit the user should be. Furthermore, you can configure a “system” mailbox so that this user is able to send “system” communications to end users (which can be quite useful as well and cannot be done with built-in SYSTEM/INTEGRATION account).

Note that if your plugins are configured to run under the context of a specific user (e.g. CRM System User) then it’s a good practice that this same user exists in all your environments (DEV/QA/Prod) with the same full name. If that is the case then you can safely transport your solutions and the impersonation configuration will be preserved when you transport plugins across your environments because CRM will be able to find the impersonating user by full name (even though the systemuserid and the AD accounts might not match it will still be able to resolve by full name).