Intro
Using a technical user for accessing SAP Business Technology Platform is often hinted at in SAP Help or community tutorials, but how exactly this can be achieved, has not been documented as far as I can tell. I'm writing this blog to share the lessons learned and to teach you how you can manage your technical users for SAP BTP going forward.
A technical user is a user account that is used for automated and integrated operations.
If you arrive at the situation where you want or need to use a technical user for accessing SAP BTP and you start searching for information, you might arrive at this SAP Support page:
Online help: Technical communication users. Unfortunately, this isn't the solution you are looking for. These technical communication users are not known to the SAP ID Services identity provider (the default SAP BTP IdP) and hence cannot be used to authenticate such a technical communication user.
ℹ️ An S-user account (which depends on manually extending its validity) is meant to be associated with a person and should not be used as a technical user.
|
Trust IAS
The solution can be found in SAP Cloud Identity Services - Identity Authentication (IAS). On a global account (platform) level, a trust can be setup with a single IAS instance. This is not only be useful to strengthen the security to access your BTP environment (e.g. stronger password policies and MFA enforcement), but also offers a solution for managing technical users.
It's important to note the difference between platform access and application access. The population of the users accessing either the platform or the applications can be vastly different. It can be a good option to use a separate IAS productive instance dedicated to platform access.
Setup in a nutshell
Prerequisite: an IAS instance associated to the same SAP customer account as the SAP BTP global account. Ideally, this should be a productive IAS instance.
1. Establish platform trust with IAS
- In BTP the global account, access the "Trust Configuration" page within the "Security" panel of the side menu.
- Click "Establish Trust" and select the IAS instance, confirm
- Important: Note down the "Origin Key" (hereafter referred to as '<origin-key>')
2. Create technical user(s)
- Login to IAS as admin
- add one or more technical users manually
- Set an initial password and logon once with each to set a definitive password
- The email does not to exist. I chose to align my login name and email. E.g. login name: "tech-btp-cfapi" & email: tech-btp-cfapi@company.com
- Mark email as verified
3. Authorize the technical users
On subaccount level, the user needs to be a member (with certain roles) for doing operations on subaccount level (e.g. BTP API).
- Access the subaccount
- Go to the 'Users' page on the 'Security' panel of the side menu
- Click 'Create'
- Enter the (dummy) email address of the technical user for both login name and email
- Important: select the IAS instance as Identity Provider
Cloud Foundry org and space level. This is required for the CF API.
- Within your subaccount, access your Cloud Foundry space
- Navigate to the 'members' page
- Click 'Add Members'
- Enter the (dummy) email address of the technical user
- Important: select the IAS instance from the 'origin' selection
- Assign role "Space Developer" if necessary - e.g. to manage apps
- Optionally, assign a specific Org Manager/Org Auditor role on org level if required for your integration
Use case #1 - CF CLI for CI/CD
I'm using this in an Azure DevOps CI/CD flow to deploy apps upon release to SAP BTP Cloud Foundry.
To log in with the technical user from IAS, login with a specific 'origin':
cf login --origin <origin-key>
Use case #2 - CF API destination for MTX
In multi-tenant implementations, CF routes can be automatically created and deleted upon subscribing and unsubscribing to and from applications. To achieve this, the CF API is used by the service implementation of the provider application. The destination that is used to store the credentials to the CF API, can be used by any application, and therefore I opted to manually set it up on subaccount level.
ℹ️ You need at least a destination service instance on space level to be able to access the destination on subaccount level, even if the space level destination service does not contain any own destinations.
|
I have created a minimal example to demonstrate using the CF API from a backend service deployed to SAP BTP Cloud Foundry:
https://github.com/piejanssens/btp-cf-api-destination
- Clone the GitHub repository
- Test the OAuth2Password grant to get an access token from UAA (via IAS)
Prerequisite: this assumes having the REST Client extension in BAS / VS Code
- Open the 'prep' folder
- Create a '.env' file with the following tuples:
Note: if you have a '+' character in your username, you will need to URL encode it (in the .env, not in the actual destination)
cf_login=https://login.cf.<region>.hana.ondemand.com
cf_api=https://api.cf.<region>.hana.ondemand.com
idp_origin_key=<origin-key>
idp_username=<tech-user-username>
idp_password=<tech-user-password>
- Run the first request from test.http --> should show the response with access token
- Run the second request from test.http --> should show the CF spaces info
- Go to your subaccount
- Import the 'CFAPI' destination from the 'prep' folder
- Change the username, password
- Make sure you have the correct region in the subdomain of both the API and the token service URL
- Important: Make sure to change the origin value with the <origin-key> at the end of the token service URL
- Set a dummy client secret (bug in BTP cockpit...)
- Save
- Edit again
- Remove the value of the client secret input field
- Save
- From your terminal in the root project folder
- Run 'mbt build'
- Make sure you are logged in (cf login) and targeting the correct org/space
- Run 'cf deploy mta_archives/cfapi_0.0.1.mtar'
- Access the '-app' URL once it's completely deployed
The resulting page should show the CF space information which is obtained by the backend service from the CF API via the 'CFAPI' destination.
ℹ️ You might have noticed that we now have set a client ID with value 'cf' and an empty client secret. This is intentional and required by CF's UAA implementation to get this OAuth grant type to work.
|
Use case #3 - SAP Integration Suite
Gotya, not going in to that because it's not a best practice use case (any longer). There is a better way:
Creating Service Instance and Service Key for Inbound Authentication
Use case #4 - SAP BTP API
No specific examples from my own experience yet, but there are many possibilities for automating BTP administration tasks via the
APIs of the SAP Cloud Management service for SAP BTP.
To get an OAuth access token using curl (any region):
curl https://login.cf.eu10.hana.ondemand.com/oauth/token \
-X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \
--user "cf:" \
-d username=############## \
-d password=############## \
-d client_id=cf \
-d grant_type=password \
-d response_type=token \
-d login_hint=%7B%22origin%22:%22##############%22%7D
Conclusion
This blog has shown that (since the support for custom IdP on platform level), it is now possible to implement a manageable solution for technical users through the use of IAS. This allows to use dedicated user accounts only to be used by applications, systems, scripts and integrations that might have different password and access policies than true, human users.
🙏 Special thanks to gregorwolf for the help in troubleshooting the password grant on IAS. |