SAP CPI – Fetch All Security Artifacts – Don’t Read this!
The method shown in this blog exposes all security materials deployed in a tenant. Hence the usage of it should be carefully evaluated and should be used at your own risk.
A few weeks ago I wrote a blog SAP CPI – High Availability using Azure Traffic Manager about HA solution. The foundation of HA is to clone the Primary Instance and build a Secondary SAP CPI instance. While cloning of Package and IFlow Configuration can be done with Platform APIs the security artifacts require a custom solution since the platform API doesn’t allow reading the passwords or private key. In this blog, I will show how we can leverage an IFlow (which by architecture has access to the security artifact at runtime for connectivity) to read the security material and respond to an API call. This API response can be used to programmatically create/update the security artifacts in the secondary tenant using platform APIs. This approach can also be used in Neo to CF migration for fetching Security Materials.
The scope of this blog will limit only to fetching the Security artifacts and not replicating them to a target instance.
Create an IFlow to expose individual endpoint for below
- User Credentials – Default, Open Connectors, SuccessFactors, and Security Parameter
- OAuth Client Credentials
- Keypair – Private and Public key in PEM format
In each resource branch, we will fetch the respective Security Artifacts deployed in the tenant using the platform APIs. Then loop through the artifacts to read the credentials from Runtime using Groovy Script that will leverage API interfaces such as com.sap.it.api.securestore.* and com.sap.it.api.keystore.* accessed through Factory class i.e. ITApiFactory.
Important: Do not have this IFlow protected with the default ESBMessaging.send role. Create a Custom role and limit the assignment.
Below is the Script line(s) that are key for retrieving the password / private key (but not the complete executable script that is part of the IFlow solution).
//Get the Service Instance of the SecureStoreService API def service = ITApiFactory.getService(SecureStoreService.class, null); //Read the credential of a given alias def credential = service.getUserCredential(<alias>); //Read the User Name or password def unm = credential.getUsername(); def pwd = credential.getPassword();
The above code is to retrieve the password of the User Credential(default, OpenConnectors & Successfactors), Security Parameters, and OAuth-Client Credentials.
Similarly, the below code is to read the Key Pair and retrieve the Public and Private Key.
//Get the Service Instance of the KeystoreService API KeystoreService service = ITApiFactory.getService(KeystoreService.class, null); //Read the Public Certificate of a given alias Certificate pCer = service.getCertificate(<alias>); //Get Byte encoded data of the Certificate, then Base64 encode it to a String String pCerB64Enc = new String(Base64.getEncoder().encode(pCer.getEncoded())); //Read the Private Key of a given alias Key pKey = service.getKey(Alias); //Get Byte encoded data of the Private Key, then Base64 encode it to a String String pKeyB64Enc = new String(Base64.getEncoder().encode(pKey.getEncoded()));
API Endpoint and Testing
This IFlow will listen and respond to below 3 Endpoints.
Download the IFlow
You can download the IFlow as Utility_SecurityMaterial.zip from this SAP_CPI GIT Repository. It has below 4 Configuration Parameter
|Address||API URL Path|
|User Role||Role to protect this API Endpoint|
|Host||Your SAP CPI TMN Host URL|
|Credential Name||Alias of the Credential to invoke Platform APIs|
Any comment from SAP? Do we have encryption on Security Material of some sort?
I'd advise using pgp encryption and decryption to secure the data going over the line. That way your passwords are secure even if the end-point is being called from an unknown system.
Hi Santhosh Kumar Vellingiri,
Is it possible to read the code of Auhtorization Code or directly the Token? (by Groovy?)
I can't use OAuth2 autorization_code request on OData and HTTP request and I want to read it by groovy or API access.
On request : OAuth Client Credentials
I receive "" like response but there are OAuth2 credentials, there is some Permission Issue on Role to achieve that result?
I a trying to get Open Connectors specific details from the UserCredentials object but I can see any specific getter for User, Organization and Element and in the properties Map too these fields aren't available. Is there any way to retrieve these OpenConnector data by API in a script step?
Is it possible to retrieve JDBC credentials from JDBC Material in CPI by some way ?