Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
PriyankaChak
SAP Champion
SAP Champion
2,666

Introduction:

In this blog post, I will show how to use SAP credential store and access the credential storage API using Python.

What Is SAP Credential Store?

A repository for passwords, keys and keyrings for the applications that are running on SAP BTP.

How to setup credential Store in BTP trial account?

Go to BTP sub-account -> Instances and Subscription

Screenshot 2024-03-11 at 11.40.29 AM.png

Screenshot 2024-03-11 at 11.42.08 AM.png

Click on 'View Dashboard'.

Screenshot 2024-03-11 at 11.47.10 AM.png

The SAP Credential Store logically segregates data by namespaces.

Click on 'Create Namespace'.

Screenshot 2024-03-11 at 11.49.44 AM.png

Select credential type as password.

Screenshot 2024-03-11 at 11.51.36 AM.png

Screenshot 2024-03-11 at 11.53.45 AM.png

Screenshot 2024-03-11 at 2.24.00 PM.png

Now, lets bind this to application named 'WeatherApp'.

Screenshot 2024-03-11 at 2.28.32 PM.png

Screenshot 2024-03-11 at 2.29.53 PM.png

Now, navigate to the app -> environment variables. 

Screenshot 2024-03-11 at 2.55.56 PM.png

Environment variable named 'VCAP_SERVICES' contains the rest api endpoint details of SAP credential store and associated credentials to access the api. Also, It contains 'client_private_key' details which is used to decrypt the response payload.

 

{
  "VCAP_SERVICES": {
    "credstore": [
      {
        "label": "credstore",
        "provider": null,
        "plan": "trial",
        "name": "credential-store",
        "tags": [
          "credstore",
          "securestore",
          "keystore",
          "credentials"
        ],
        "instance_guid": "b5b73270-6336-419e-8c38-90161efa8132",
        "instance_name": "credential-store",
        "binding_guid": "30d62116-331f-4086-b228-7681a9dbdc85",
        "binding_name": null,
        "credentials": {
          "password": "<password>",
          "expires_at": "2024-05-10T09:00:44.0Z",
          "encryption": {
            "client_private_key": "<client private key>",
            "server_public_key": "<server public key>"
          },
          "parameters": {
            "authorization": {
              "default_permissions": [
                "create",
                "decrypt",
                "delete",
                "encrypt",
                "info",
                "list",
                "namespaces",
                "read",
                "update"
              ]
            },
            "encryption": {
              "payload": "enabled",
              "key": {
                "size": 3072
              }
            },
            "authentication": {
              "type": "basic"
            },
            "access_policy": {
              "creds_api": "public",
              "token_api": "public",
              "kms_api": "public",
              "encryption_api": "public"
            }
          },
          "url": "https://credstore.cfapps.us10.hana.ondemand.com/api/v1/credentials",
          "username": "<username>"
        },
        "syslog_drain_url": null,
        "volume_mounts": []
      }
    ]
  }
}

 

Python code to access credential storage API

SAP Credential Store exposes a RESTful API to create, read and delete credentials.

Demo Scenario:

For this demo, Sample Weather API is used. 

 

from jwcrypto import jwk, jwe
from flask import Flask
import requests
import os
import json
# latitude of Bengaluru
LAT = 12.9716
#longitude of Bengaluru
LON = 77.5946
namespace = "APIKeyHub"
api_key_name = "Weather_API_Key"


cred_headers = {
    "sapcp-credstore-namespace": namespace
}

cred_params = {
    "name": api_key_name
}


vcap_services = os.getenv('VCAP_SERVICES')
if vcap_services:
    binding = json.loads(vcap_services)['credstore'][0]['credentials']
    response = requests.get(url=f"{binding['url']}/password", headers=cred_headers, params=cred_params,
                        auth=(binding['username'], binding['password']))
    private_key_pem =f"-----BEGIN PRIVATE KEY-----\n{binding['encryption']['client_private_key']}\n-----END PRIVATE KEY-----"
    private_key = jwk.JWK.from_pem(private_key_pem.encode('utf-8'))
    jwetoken = jwe.JWE()
    jwetoken.deserialize(response.text, key=private_key)
    resp = jwetoken.payload.decode('utf-8')
    json_payload = json.loads(resp)
    api_key_val = json_payload['value']

    FORECAST_URL = "https://api.openweathermap.org/data/2.5/forecast"

    query_params = {
        "lat": LAT,
        "lon": LON,
        "appid": api_key_val,
        "cnt": 4
    }

    forecast_response = requests.get(url=FORECAST_URL,params=query_params)
    data = forecast_response.json()
    
app = Flask(__name__)

@app.route('/')
def home():
    if data:
        return data
    else:
        return 'No data'    

if __name__ == "__main__":
    app.run()

 

Requirements:

 

flask~=3.0.2
gunicorn~=21.2.0
requests~=2.31.0
jwcrypto~=1.5.6

 

Reference Link:

SAP Credential Store

Credential Management – Example (Node.js)

Regards,

Priyanka Chakraborti

 

1 Comment