Working with Encrypted Key Value Maps using SAP Cloud Platform API Management UI
As an exciting update to SAP API Management three major updates have been made for the Key Value Map concept.
#1 – You can now securely encrypt the actual data stored within a Key Value Map, allowing for storage of sensitive data.
#2 – You can now access and update Key Value Map information through the SAP API Management Design Time UI in addition to API calls.
#3 – You can now add Key Value Maps at an API proxy level rather than the environment level. Read more here.
In this Blog I will assume that you would have already read the excellent previous blog on using Key Value Maps (KVMs) located here to understand what a KVM is, what it is used for, and when to use it. I will be focusing on using the Design Time UI to generate an encrypted KVM in a codeless manner and accessing that Encrypted KVMs data at runtime.
Note: I will also be working from the assumption that you have created the ES5_Gateway account and API Provider.
Oftentimes customers would like to access data from the SAP ERP Backend and expose this for consumption into an application either within their organization or to partners / 3rd party providers. Since ERP data is extremely valuable and important there is a very tight security process in place for adding users, which makes it impractical to administer for an unknown and potentially high number of incoming users.
This is where the common use case of Bi-Modal IT, with API Management as the “Umbrella” governance layer providing Agility and secure exposure on top of existing Legacy systems comes into the picture. SAP API Management will be the public facing access point, and will invisibly transform consumer requests into a service user provisioned on the Backend. One analogy is the funnel.
Exposing this sensitive ERP data will require some gating mechanism, so in this blog will explore utilizing the API Key as the new authentication mechanism, however API Management supports many other more advanced patterns, like OAuth, SAP IDP, callout to 3rd party IDP, IP whitelisting, etc. which I will not explore here.
Let’s get started!
As before we start by entering the API Portal from SAP Cloud Platform
Creating the Key Value Map
From the API Portal Home page expand the Menu and select Configure
In the Configure menu that comes up, select the Sub-tab Key Value Maps to pull up a list of Key Value Maps configured on your SAP API Management tenant. Click Create to generate a new KVM in the UI.
This will bring up the Create Key Value Map wizard. In this screen provide a distinct name for the KVM, this will be used in the API Proxy so make it something memorable but not too complex. Check the Encrypt Key Value Map box. You will notice when this box is checked, even in the Create Key Value Map screen the Value Data is hidden.
Then under Entries enter a distinct Key name, and a value for this Key, then click Add to enter additional entries. For this Blog, since we will be defining a Service user I will enter Username and Password keys:
<Your ES5 User ID>
<Your ES5 Password>
Once you have filled in all the KVM information, and are satisfied, click Save. Once you receive the message that it was saved successfully, we can create an API Proxy that leverages these credentials.
Creating an API Proxy
Open the Menu and select Develop to start creating an API Proxy. Then click Create to bring up the Create API Proxy window.
Now in the Create API Proxy Wizard, select the API Provider Radio Button and select your ES5 API Provider from the drop down list.
Click the Discover button to bring up the list of APIs defined in the ERP system.
In the Search field search for GWSAMPLE and select the GWSAMPLE_BASIC service and click OK.
Enter distinct information for the API Proxy describing what the API is and what it does. For the Blog I will be naming this as an Open API integration for ERP, using the following information:
|Title||Open authentication API for ERP|
|Description||<Leave as Default>|
|Host Alias||<Leave as Default>|
|API Base Path||/api/odata/v1/openerp|
Click Create to get into the final page of API creation, and then Click Deploy to bring the API live. Once the API has been successfully deployed, if you like, you can try the API at this point, and if you do not provide credentials, it will provide a 401 Unauthorized error as expected.
Adding KVM & Auth Policy to API Proxy
Within the API Proxy window you just created, click the Policies button on the top right of the API Proxy to enter the Policy Editor.
For passing Authentication credentials to the backend, it makes sense to place this policy at the end of the API Flow, so I will be placing these Policies in the Target Endpoint PostFlow, although this could be done elsewhere in the flow as well. If you need a refresher on API Policy Flows I recommend reviewing this intro blog or this advanced blog on flows
In the Flows section first click the Edit button on the top right. Then in the Flows window in the top left, either collapse the ProxyEndpoint flows, or scroll down until you see TargetEndpoint, and select PostFlow to add Policies there.
Adding KVM Policy
On the right hand side, scroll down the Policies list to Mediation Policies, and click the + symbol next to Key Value Map Operations to add the KVM Policy. This policy will be pulling the encrypted User Credentials before passing the request to the backend.
In the Add Policy Wizard enter the following information and then click Add:
Now select the newly created KVM Policy and replace the code with the following:
<!-- Key/value pairs can be stored, retrieved, and deleted from named existing maps by configuring this policy by specifying PUT, GET, or DELETE operations --> <!-- mapIdentifier refers to the name of the key value map --> <KeyValueMapOperations mapIdentifier="ES5Credentials" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt"> <!-- PUT stores the key value pair mentioned inside the element --> <Get assignTo="private.username"> <Key> <Parameter>ES5User</Parameter> </Key> </Get> <Get assignTo="private.password"> <Key> <Parameter>ES5Pass</Parameter> </Key> </Get> <!-- the scope of the key value map. Valid values are environment, organization, apiproxy and policy --> <Scope>environment</Scope> </KeyValueMapOperations>
This policy is creating an internal variable called “username” and “password” with the private flag to denote that this is coming from the encrypted data store, from the entries defined in the myES5Credential KVM step.
Adding Basic Authentication Policy
On the right hand side, scroll to the Policies list to Security Policies, and click the + symbol next to Basic Authentication to add the Auth Policy. This policy will be generating an encoded Header containing the User Credentials to be passed with the request to the backend.
In the Add Policy Wizard enter the following information and then click Add:
Select the newly created Basic Authentication policy and replace the code with the following:
<BasicAuthentication async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'> <!-- Operation can be Encode or Decode --> <Operation>Encode</Operation> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <!-- for Encode, User element can be used to dynamically populate the user value --> <User ref='private.username' /> <!-- for Encode, Password element can be used to dynamically populate the password value --> <Password ref='private.password' /> <!-- Source is used to retrieve the encoded value of username and password. This should not be used if the operation is Encode--> <Source>request.header.Authorization</Source> <!-- Assign to is used to assign the encoded value of username and password to a variable. This should not be used if the operation is Decode --> <AssignTo createNew="false">request.header.Authorization</AssignTo> </BasicAuthentication>
Here SAP API Management Basic Auth is encoding a header containing User / Password called from the previously defined KVM variables calling against the encrypted KVM variables.
It is important that the policies happen in the correct order, KVM policy first, then Basic Authentication following after.
Once done, click Update in the Policy Editor to be taken back to the API Proxy page. Then click Save to save the changes to the runtime.
After you receive the success message – click the API Proxy URL to access the API, you should see a successful request without any request for credential information, generating the Service User call that we were looking to create at the start.
Securing the API Proxy
The calling user has now been successfully mapped to a service user in API Management, removing the need to onboard any consumers into the Backend ERP system, however this is not a secure exposure. So the last step would be to add an authentication mechanism in API Management, such as API Key. See an example of utilizing API Keys within Fiori Applications against APIs from API management here