Skip to content

Reference

SAP S/4HANA (Client Credentials)

Connect SAP S/4HANA to Alter Vault using OAuth client credentials

Use SAP S/4HANA Cloud OAuth client credentials to make authenticated OData API calls through Alter Vault. The client secret stays in the vault: Alter exchanges it for a short-lived access token and only that token is used on the wire and returned to the SDK.

PropertyValue
Provider IDsap-s4hana-client-credentials
CategoryERP
Credential TypeOAuth client credentials

Open the SAP Fiori launchpad

Log in to the S/4HANA Cloud tenant’s SAP Fiori launchpad with an administrator user. SAP’s communication management documentation covers the full flow.

Create a communication system with OAuth

In the ‘Communication Systems’ app, create a system for the integration, enable inbound communication, and add an inbound user with Authentication Method ‘OAuth 2.0’.

Note the client ID and secret

Note the generated OAuth Client ID and Client Secret. The secret is shown once and cannot be retrieved afterwards.

Activate the API scenarios

In the ‘Communication Arrangements’ app, create an arrangement for each API scenario the integration needs, such as SAP_COM_0008 (Business Partner), SAP_COM_0009 (Product Master), or SAP_COM_0109 (Sales Order), then select the communication system.

Note the API host and token endpoint

Note the tenant’s API host from the arrangement’s service URLs (https://my<tenant>-api.s4hana.cloud.sap, the -api host, not the UI host). The token endpoint is that same host followed by /sap/bc/sec/oauth2/token.

Open the Developer Portal

Go to portal.alterauth.com and navigate to the application.

Add SAP S/4HANA (Client Credentials)

Go to Managed Secrets > Add Provider > SAP S/4HANA Cloud (Client Credentials).

Enter credentials

Enter the Client ID and the Token Endpoint URL, and paste the Client Secret into the credential field.

Save

Click Save. Alter performs a real token exchange to verify the credentials before storing them. You’ll receive a grant_id to use with the SDK.

response = await alter_app.request(
HttpMethod.GET,
"https://my123456-api.s4hana.cloud.sap/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner?$top=10&$format=json",
grant_id="YOUR_GRANT_ID",
)

The credential returned to the SDK is a short-lived access token, not the client secret. Its expiry is reported on the response, and a new token is obtained automatically when it lapses.

S/4HANA rejects a POST, PATCH, or DELETE that arrives without an X-CSRF-Token tied to the session that issued it. Alter obtains that token and replays it with its session cookies, so no CSRF header of your own is needed, but this only happens when Alter makes the call. Use proxy_request for modifying calls, not request.

response = await alter_app.proxy_request(
HttpMethod.PATCH,
"https://my123456-api.s4hana.cloud.sap/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder('500001')",
grant_id="YOUR_GRANT_ID",
json={"SalesOrderType": "OR"},
)

request hands the credential to the SDK and the call leaves from the application, so the token exchange cannot happen and S/4HANA answers 403 CSRF token validation failed. Reads are unaffected: GET needs no token, so either method works for them.

Alter policy rules can target these attested operations and families for operation-level and parameter-aware controls.

Operation IDFamiliesMethodProvider pathNotes
business-partners/createwritePOST/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner—
business-partners/updatewritePATCH/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner('{BusinessPartner}')also served at /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner='{BusinessPartner}')
sales-orders/createpayment, writePOST/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder—
sales-orders/updatepayment, writePATCH/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder('{SalesOrder}')also served at /sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder(SalesOrder='{SalesOrder}')
sales-orders/deletedelete, paymentDELETE/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder('{SalesOrder}')also served at /sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder(SalesOrder='{SalesOrder}')
products/createwritePOST/sap/opu/odata/sap/API_PRODUCT_SRV/A_Product—
products/updatewritePATCH/sap/opu/odata/sap/API_PRODUCT_SRV/A_Product('{Product}')also served at /sap/opu/odata/sap/API_PRODUCT_SRV/A_Product(Product='{Product}')
business-partners/listreadGET/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner—
business-partners/getreadGET/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner('{BusinessPartner}')also served at /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner='{BusinessPartner}')
business-partner-addresses/listreadGET/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartnerAddress—
customers/listreadGET/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_Customer—
suppliers/listreadGET/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_Supplier—
sales-orders/listreadGET/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder—
sales-orders/getreadGET/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder('{SalesOrder}')also served at /sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder(SalesOrder='{SalesOrder}')
sales-order-items/listreadGET/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrderItem—
products/listreadGET/sap/opu/odata/sap/API_PRODUCT_SRV/A_Product—
products/getreadGET/sap/opu/odata/sap/API_PRODUCT_SRV/A_Product('{Product}')also served at /sap/opu/odata/sap/API_PRODUCT_SRV/A_Product(Product='{Product}')
product-descriptions/listreadGET/sap/opu/odata/sap/API_PRODUCT_SRV/A_ProductDescription—
service-documents/business-partnerreadGET/sap/opu/odata/sap/API_BUSINESS_PARTNER—
service-documents/sales-orderreadGET/sap/opu/odata/sap/API_SALES_ORDER_SRV—
service-documents/productreadGET/sap/opu/odata/sap/API_PRODUCT_SRV—
business-partners/batchadmin, delete, read, writePOST/sap/opu/odata/sap/API_BUSINESS_PARTNER/$batch—
sales-orders/batchadmin, delete, payment, read, writePOST/sap/opu/odata/sap/API_SALES_ORDER_SRV/$batch—
products/batchadmin, delete, read, writePOST/sap/opu/odata/sap/API_PRODUCT_SRV/$batch—

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.