SAP Analytics Cloud SCIM API version 1 and 2 high-level comparison
The release of SAP Analytics Cloud SCIM API version 2 earlier in the year resolved many restrictions compared to version one. This blog provides insights into what this means and is suitable for developers or anyone adopting the SCIM API of SAP Analytics Cloud. In particular:
- High-level comparison of version 1 and version 2
- Benefits of version 2 compared to version 1
- Working with version 1
- Endpoints are UUIDs
- Teams with version 1, including options IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS and ‘Ignore Content Namespace For Teams’
- Mixing version 1 and version 2
- Version 1 or version 2?
For those that enabled the IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS, I’ve explained the options available, so this setting is no longer needed.
High-level comparison of version 1 and version 2
The SAP Analytics Cloud SCIM API provides two versions; both are SCIM version 2 compliant:
- Version 1 uses a root endpoint /api/v1/scim/. For example, a GET request to /api/v1/scim/Users will return the users.
- Version 2 uses a root endpoint /api/v1/scim2/. For example, a GET request to /api/v1/scim2/Users would also return the users, albeit with a different schema than version 1.
There are no plans to retire version 1; indeed, you may find version 1 more straightforward, and you can even use both versions side-by-side. The recent update to my SCIM API sample scripts uses both versions, albeit in a minimal way, within the same script (Postman Collection).
Benefits of version 2 compared to version 1
- Teams can be created without a team folder, and duplicated Team names can co-exist. Version 2 means you no longer need to delete all those team folders, saving many manual clicks. Duplicate team names aren’t a problem because having two teams of the same name doesn’t make sense.
- The /Users endpoint allows team membership to be updated. With version 1, you could only update team membership on the teams (/Groups) endpoint. To add a single user to 3 teams meant updating three teams. With version 2, you can use the /Users endpoint and make a single request for the user to be added to 3 teams. Don’t get too carried away; if you add 500 users to a team, using the /Groups endpoint will still be quicker than 500 individual requests to the /Users endpoint. At least now you have the choice.
- Both teams (/Groups) and /Users endpoints now support a ‘PATCH’ request. PATCH requests fully respect the existing settings (like team or role membership) whilst adding or removing a property, like a team or role. It means they no longer need to ‘GET’ the current and then ‘PUT’ back the original with a new updated value. In practical terms, role assignment to either users or teams won’t be ‘dropped’ when a user provisioning tool comes along to update either. It means features like ‘request roles’ or ‘default roles’ are no longer restrictive to their application, so long as version 2 of the API is used with a ‘PATCH’ request. In other words, ‘request roles’ or ‘default roles’ are no longer problematic for SAP User Provisioning or most other enterprise user provisioning solutions.
Sadly, version 1 and version 2 don’t allow a user to be created and added to Teams (Groups) in a single request. The SCIM API standard states these attributes are readOnly. A version 2 POST request is needed to create the user and a subsequent PATCH request to add the teams (Groups).
Working with version 1
Endpoints are UUIDs
Endpoints differ; version 1 is /api/v1/scim/Users/USERID, and version 2 is /api/v1/scim2/Users/UUID.
The USERID is the SAP Analytics User ID. You only need the USERID to update a user when using version 1. When the SAML SSO authentication is configured as ‘default’ or ‘UserID’, then the USERID is what you want it to be. When the SAML SSO Authentication is configured as ‘e-mail’, the USERID is derived from the e-mail address (MATTHEW would be the USERID when creating a user with firstname.lastname@example.org as the e-mail.) So, in general, the USERID is something your organisation knows, and there’s no need to store an extra property in your system for each user.
Knowing the USERID is handy when using version 1 of the API to update teams (/Groups) because the USERID identifies the user.
When using version 2 of the API, users are identified by the UUID. A UUID is unique to a user and unique to that user on that system. The same user would never, and can never, have the same UUID across multiple systems. SAP determines the UUID at user creation, and its value is returned as part of the responseBody.
In practical terms, updating either a user (/Users) or a team (/Groups) requires knowledge of the UUID. You can search for the UUID given a USERID (e.g. POST /api/scim2/Users/.search with requestBody containing “filter”: “userName eq MATTHEW”), which is fine if you have just a few users, but with many hundreds, you’ll need to store the UUID to avoid a performance issue for all the querying to get the UUIDs.
SAP User Provisioning Solution does all the hard work for you. It stores these UUIDs internally, so they shield you and all this complexity. Adopting version 2 is straightforward, and you’ll be done with a few configuration changes. So, for those using SAP User Provisioning, you can benefit from version 2 today with less fuss.
If you’re hard-coding your solution, consider using SAP User Provisioning Solution to provide an abstract layer; all you need to do is expose a readable SCIM API for your users and groups. Then, SAP User Provisioning Solution can query your SCIM API to update another, for example, SAP Analytics Cloud. Suppose you would instead make direct SCIM API requests to SAP Analytics Cloud. In that case, you’ll either need to store the UUIDs for the users, query the users’ UUID each time, or stick with the old version 1 of the API to identify users by the USERID.
The endpoints for teams are similar; version 1 is /api/v1/scim/Groups/TEAMID, version 2 is /api/v1/scim2/Groups/UUID
Again, you’ll need to know the Team (Group) UUID when updating a team in version 2, compared to just the team ID with version 1. Again, you can search for the UUID of a team, given its name, and you’ll need to store that to avoid continuing queries.
Teams with version 1
Version 1 struggled with teams in many ways; for example, it doesn’t understand the ‘namespace’ concept, and this means you need a workaround ‘IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS’, which requires contacting SAP Support to implement on your behalf. Thankfully, SAP Analytics Cloud now has a self-service means to achieve the same result called ‘Ignore Content Namespace For Teams’. This setting was added midway through 2023.
Why a change is needed for version 1
If you don’t implement one of these, a setting change is needed so teams created by the user interface or imported Teams via the Content Network can be read and updated via the API. Failure to make this change will mean Teams cannot be updated, and an error will be returned from the API, complaining that a Team can’t be found even though it exists. Version 2 of the API does not have this issue, meaning neither of the above settings needs to be changed so that Teams can be updated, unlike with version 1.
If you only use version 2 of the SCIM API, then no change to these settings is needed.
You cannot update Teams with version 1 until a setting is changed, unlike version 2.
This restriction to version 1 is not applicable when SAP Analytics Cloud is hosted on an SAP Data Centre (NEO). However, most customers are hosted on a non-SAP Data Centre, so it’s almost certain this restriction applies to your organisation. It means you almost certainly need to change one of these settings.
Only 1 of these two settings is needed, but changing both is no harm if you have previously enabled the other. The settings are:
- Ignore Content Namespace For Teams
This is the recommended setting to change.
Once this setting has been changed, all teams can be used by version 1 of the API and the user interface, regardless of how or when they were created. There are no* restrictions. Version 2 of the SCIM API isn’t restricted this way.
* However, there’s a problem when two teams share the same name! It is rare, but it can happen when a Team is created manually and another Team of the same name is imported via the Content Network. In such cases, two Teams of the same name can exist. Technically, they will have different namespaces. If you have two Teams of the same name, then version 1 of the API will return an error, complaining the Team doesn’t exist, even when this setting is ON. It does this because it doesn’t know which Team to use, so it throws an error because version 1 of the API isn’t aware of namespaces! Delete the duplicate Team, and the problem is resolved. Consider using a sample script to copy team members from one Team to another to save some rework. However, deleting a Team is problematic if the Team is used to grant access rights to resources, as extra rework is needed to use the other Team in those sharing settings.
How to change the ‘Ignore Content Namespace For Teams’ setting
Log in as an administrator for each SAP Analytics Cloud Service and select Menu-System-Administration-System Configuration. Then, search for the setting ‘Ignore Content Namespace For Teams’ and press the edit button to change the value from OFF to ON, as shown in the image above. Save the change.
Option 2 (no longer recommended): IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS
Changing this setting from off/disabled to on/enabled is not recommended because there is a complication with all teams previously created manually or via importing them from the Content Network.
The difficulty is that the API cannot update any previously created teams, so you must delete all those existing teams if you want to use the API to manage them. Though, confusingly, a sample script can read, though not manage, these teams to transfer the user (and role) membership to another Team, saving much rework, namely sample script “1654-All_T-Uc-Uur-Oark-Transfer API Hidden Team To API Created Team”. Please refer to the user guide and the sample notes section for further understanding and explanation.
Once the setting has changed to on/enabled, the API and the user interface can manage Teams created manually or by importing them from the Content Network. You can mix the management of the Team through both the API and the user interface as you please.
Given the abovementioned complications, avoiding creating teams before changing this setting to on/enabled makes sense.
How to change the IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS setting
Log an incident with SAP Support, quoting your SAP Analytics Cloud URL and requesting the business toggle IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS turned on/enabled as mentioned in SAP KBA 2857395.
Before submitting your request to have each SAP Analytics Cloud Service updated with this change, please consider updating your SAP Analytics Cloud’ Content Namespace’ to be the same consistent value across all your SAP Analytics Cloud Services.
It is not essential to use the same Content Namespace throughout your landscape. However, there are a few benefits to doing so. With the business toggle IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS enabled, you will not be able to change the Content Namespace (until it is disabled/turned off)
Already enabled IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS?
If you have already enabled IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS, you could enable the other option and disable IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS. The result would be the same, but you would have lifted the restriction associated with IMPLEMENT_WORKAROUND_FOR_SCIM_GROUPS regarding changing the Namespace, and it would also put your organisation back in control of the setting rather than requiring SAP to make the change for you.
Mixing version 1 and version 2
There’s no harm in mixing the use of both endpoints. For example, my sample scripts do this. While most of the samples today use version 1, I use version 2 to create teams without a team folder amongst all that version 1 content.
Version 2 also saw the documented and supported endpoint to fetch an x-csrf-token, namely /api/v1/csrf. There’s a number of really great things about this:
- Simplifies the logic. There’s no need to add an x-csrf-token header with ‘fetch’ to get a new one, request /api/v1/csrf immediately after obtaining an access token. If you receive a 401 or 403 from any request, then get a new access token and then request a new x-csrf-token from /api/v1/csrf to resolve it, before heading back to resubmit your original request.
- It works for and across both version 1 and version 2.
I’ve started this new workflow in a few of my updated sample scripts so that you can observe a working example. (see sample 1665).
Version 1 or version 2?
If you’re using version 1 today, there’s no need to move to version 2; stay as you are. If you’re embarking on a new project, then consider the benefits of version 2. If you’re using SAP User Provisioning, consider adopting version 2 of the API. Still, I would only recommend it if you must resolve a problem with those ‘default roles’ for users or where team updates are dropping role assignments. The ‘PATCH’ request will fix both of these issues.