Reference
SAP S/4HANA (Client Credentials)
Connect SAP S/4HANA to Alter Vault using OAuth client credentials
Overview
Section titled “Overview”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.
| Property | Value |
|---|---|
| Provider ID | sap-s4hana-client-credentials |
| Category | ERP |
| Credential Type | OAuth client credentials |
Step 1: Get Credentials
Section titled “Step 1: Get 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.
Step 2: Add to Alter Vault
Section titled “Step 2: Add to Alter Vault”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.
Using in Code
Section titled “Using in Code”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.
Modifying calls
Section titled “Modifying calls”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.
Policy-cataloged operations
Section titled “Policy-cataloged operations”Alter policy rules can target these attested operations and families for operation-level and parameter-aware controls.
| Operation ID | Families | Method | Provider path | Notes |
|---|---|---|---|---|
business-partners/create | write | POST | /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner | — |
business-partners/update | write | PATCH | /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/create | payment, write | POST | /sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder | — |
sales-orders/update | payment, write | PATCH | /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/delete | delete, payment | DELETE | /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/create | write | POST | /sap/opu/odata/sap/API_PRODUCT_SRV/A_Product | — |
products/update | write | PATCH | /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/list | read | GET | /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner | — |
business-partners/get | read | GET | /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/list | read | GET | /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartnerAddress | — |
customers/list | read | GET | /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_Customer | — |
suppliers/list | read | GET | /sap/opu/odata/sap/API_BUSINESS_PARTNER/A_Supplier | — |
sales-orders/list | read | GET | /sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder | — |
sales-orders/get | read | GET | /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/list | read | GET | /sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrderItem | — |
products/list | read | GET | /sap/opu/odata/sap/API_PRODUCT_SRV/A_Product | — |
products/get | read | GET | /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/list | read | GET | /sap/opu/odata/sap/API_PRODUCT_SRV/A_ProductDescription | — |
service-documents/business-partner | read | GET | /sap/opu/odata/sap/API_BUSINESS_PARTNER | — |
service-documents/sales-order | read | GET | /sap/opu/odata/sap/API_SALES_ORDER_SRV | — |
service-documents/product | read | GET | /sap/opu/odata/sap/API_PRODUCT_SRV | — |
business-partners/batch | admin, delete, read, write | POST | /sap/opu/odata/sap/API_BUSINESS_PARTNER/$batch | — |
sales-orders/batch | admin, delete, payment, read, write | POST | /sap/opu/odata/sap/API_SALES_ORDER_SRV/$batch | — |
products/batch | admin, delete, read, write | POST | /sap/opu/odata/sap/API_PRODUCT_SRV/$batch | — |