# User-attributed SAP writeback with OAuth 2.0 This page contains instructions for [setting up the OAuth 2.0 server in SAP](#setting-up-the-oauth-20-server-in-sap) and [setting up the OAuth 2.0 client in Foundry](#setting-up-the-oauth-20-client-in-foundry). ## Setting up the OAuth 2.0 server in SAP ### Prerequisites * SP21 or above of the Palantir Foundry Connector 2.0 for SAP Applications ("Connector") * The Foundry technical user in SAP should be a `SYSTEM` user * `/PALANTIR/OAUTH_CLIENT` should be assigned to the Foundry technical user and any end users wishing to write back to SAP from Foundry * `/PALANTIR/CONTENT_FUNCTION_ALL` should be assigned to end user * All services under the `/sap/public/bc` node to be activated (for OAuth 2.0 configuration) * `/sap/bc/sec/oauth2*` * `/default_host/sap/bc/webdynpro/sap/oauth2_authority` * SAP Gateway is active * SAP\_BASIS (the technical component version, applicable to both SAP NetWeaver and SAP S/4HANA systems) 7.4 SP09 or above (support for OAuth 2.0 and OData) ### Reference * [Note 1688545 - OAuth 2.0 Server in AS ABAP troubleshooting ↗](https://me.sap.com/notes/1688545) (SAP login required) * [Help: OAuth 2.0 Server for AS ABAP ↗](https://help.sap.com/viewer/3c4e8fc004cb4401a4fdd737f02ac2b9/7.5.9/en-US/4bd73e2050e84ce99b2d781687e0c62d.html) ### OAuth 2.0 configuration 1. Run the `SOAUTH2` transaction. 2. Select **Create...**. 3. Enter the username of the Foundry technical user as the **OAuth 2.0 Client ID**. 4. Select **Next >**. 5. Enter the username of the Foundry technical user as the **User ID**. 6. Ensure **Client User ID and Password** and **SSL Client Certificate** are both checked. 7. Select **Next >**. 8. Set the **Redirect URI** as `https:///workspace/oauth2-clients/callback`. 9. Select **Next >**. 10. Add a **Scope Assignment** with an **OAuth 2.0 Scope ID** of `/PALANTIR/SRV_0001` and a description such as `Palantir Foundry writeback using SAP functions`. 11. Select **Next >** and then **Finish**. ### OData configuration 1. In the **Maintain service** page within SAP, follow the hierarchy of services to find **opu > odata > palantir**. 2. Right-click on **palantir** and select **Activate Service**. 3. Select **Yes** when prompted. 4. On the **Create/Change a Service** tab, select **GUI Configuration** under **Interactive Options**. 5. Add parameter with name `~CHECK_CSRF_TOKEN` and value `0` (zero). 6. Disable CSRF\_TOKEN validation as outlined here: https://help.sap.com/doc/saphelp\_hba/1.0/de-DE/e6/cae27d5e8d4996add4067280c8714e/content.htm 7. Run the `/IWFND/MAINT_SERVICE` transaction. 8. Select **Add System Alias** under **System Aliases**. 9. Add a system alias with the following values: * **Service Doc. Identifier:** `/PALANTIR/SRV_0001` * **User Role:** blank * **Host Name:** blank * **SAP System Alias:** `LOCAL` * **Metadata Default:** unchecked * **Default System:** checked * **Tech. Svc. Name:** `/PALANTIR/SRV` * **Ext. Service Name:** `ODATA_SRV` * **Version:** `1` * **User Name:** blank ## Setting up the OAuth 2.0 client in Foundry This follows the general approach outlined in [Configure outbound applications](../../administration/configure-outbound-applications/index.md) but has been tailored specifically to SAP systems. Choose the setup that matches your SAP connection: * If your SAP ERP source uses **SAP Data Accelerator**, follow [Outbound application setup with SAP Data Accelerator](#outbound-application-setup-with-sap-data-accelerator). * For connections using an agent proxy egress policy, follow [Outbound application setup](#outbound-application-setup). ### Outbound application setup 1. Navigate to Control Panel and select **Outbound applications** under **Organization settings**. 2. Select **New application**. 3. Provide an **Application name**, for example, the name of your SAP system. 4. Set the **Approval prompt** to describe the authorization action, for example, `Allow Foundry to act on your behalf in SAP?`. 5. Under **OAuth 2.0 server connection**, select the **Foundry Worker** option. 6. Set the **Authorization page URL** to the SAP OAuth 2.0 authorization endpoint, including the SAP HTTPS port. Replace `` with your SAP hostname and `` with its HTTPS port: ``` https://:/sap/bc/sec/oauth2/authorize ``` 7. Set the **Token endpoint URL** to the SAP OAuth 2.0 token endpoint, including the SAP HTTPS port: ``` https://:/sap/bc/sec/oauth2/token ``` 8. Under **Egress policy**, select an [agent proxy egress policy](../../administration/configure-egress/index.md#agent-proxy-egress-policies) that routes traffic through a [Data Connection agent](../../data-connection/core-concepts/index.md#agents) installed in your network with access to the SAP system. ![An outbound application configured with the Foundry Worker option, SAP authorization and token endpoint URLs, and an agent proxy egress policy.](../../../assets/567decff91e55ae846903828a8922ce2a6b9d43efa1aa9080caca0a376b362d1.webp) 9. Under **OAuth 2.0 settings**, set the **Client ID** to the client ID from the SAP OAuth 2.0 server configuration. Under **Scopes**, add `/PALANTIR/SRV_0001`. 10. Save the outbound application. 11. This outbound application can now be used when creating an SAP webhook. For more details on outbound application configuration options, see [Configure outbound applications](../../administration/configure-outbound-applications/index.md#configuration-options). ### Outbound application setup with SAP Data Accelerator :::callout{theme="neutral" title="Beta"} User-attributed writeback through SAP Data Accelerator is in the [beta](../../platform-overview/development-life-cycle/index.md) phase of development and may not be available on your enrollment. This includes the get token and refresh token webhooks, outbound application setup, and BAPI writeback described below. Functionality may change during active development. ::: To enable user-attributed writeback through SAP Data Accelerator, create two webhooks on your **SAP ERP** source: a **get token webhook** and a **refresh token webhook**. Then, select both webhooks in an outbound application. These webhooks use the source's authentication and SAP Data Accelerator connection settings to exchange and refresh tokens. Before you begin, complete the [SAP OAuth 2.0 server setup](#setting-up-the-oauth-20-server-in-sap) and [configure your SAP ERP source to use SAP Data Accelerator](../data-accelerator/index.md#configure-the-foundry-source). You also need permission to [manage outbound applications](../../administration/configure-outbound-applications/index.md#create-an-outbound-application). #### Create the get token and refresh token webhooks :::callout{theme="warning" title="Turn off Function configuration for both webhooks"} When creating the get token webhook and the refresh token webhook, turn off **Function configuration**. If this setting is enabled, the webhooks are published as functions and cannot be used in outbound applications. ::: Use **Insert example** for each webhook after selecting its **Task type**. It automatically fills the task body template and creates the input and output parameters, including their types and mappings to response fields. Use the parameter tables below to check the generated configuration. ![The Insert example button beside Task body template, with the SAP ERP get token webhook task type selected.](../../../assets/059f22af6eafb34514f3a47c74fadf69b6ccc993924b3efb176ba679401ece6e.webp) :::callout{theme="neutral" title="Authorization for get token and refresh token webhooks"} For both webhooks, leave **Outbound application** set to **Not selected** under **Request configuration > Authorization**. They use the SAP source's authentication to obtain and refresh tokens for the outbound application. Selecting that application here would create a circular dependency. ::: For both webhooks, leave **Webhook safety** set to the default **Write API**. Follow the instructions below to create two webhooks on the same SAP ERP source: 1. First, create the get token webhook. Open the source in Data Connection and select **Create webhook**. 2. Enter a name for the webhook, such as `Get OAuth Token`, and turn off **Function configuration**. 3. Set **Task type** to `sap-erp-oauth2-token-webhook-task` in **Request configuration**, 4. Select **Insert example** beside the empty **Task body template** to generate the get token webhook configuration. Check the generated parameters against the reference below, then save the webhook. 5. Next, create the refresh token webhook on the same source. Enter a name, such as `Refresh OAuth Token`. 6. Turn off **Function configuration** and set **Task type** to `sap-erp-oauth2-refresh-webhook-task`. 7. Select **Insert example** to generate the refresh token webhook configuration. Check the generated parameters against the reference below, then save the webhook. The get token webhook expects the following input parameters: | Input parameter | Type | Required | | --- | --- | --- | | `client_id` | String | Yes | | `redirect_uri` | String | Yes | | `authorization_code` | String | Yes | | `code_verifier` | Optional string | Required when **Enable PKCE** is turned on in the outbound application. | The generated task body maps these inputs as follows: ```json { "client_id": {{json client_id}}, "redirect_uri": {{json redirect_uri}}, "authorization_code": {{json authorization_code}}, "code_verifier": {{json code_verifier}} } ``` The refresh token webhook expects the following input parameters: | Input parameter | Type | Required | | --- | --- | --- | | `client_id` | String | Yes | | `refresh_token` | String | Yes | The generated task body maps these inputs as follows: ```json { "client_id": {{json client_id}}, "refresh_token": {{json refresh_token}} } ``` Foundry supplies these input values during authorization and token refresh. Keep the parameter references in the task bodies so each request receives the appropriate values. **Insert example** also creates the following output parameters for both webhooks. In **Responses**, verify that each variable has its own output parameter with the specified name, type, and response key. If configuring a webhook manually, create one output parameter for each row and map it to the matching response key as outlined in the table below: | Output parameter | Type | Response key | | --- | --- | --- | | `access_token` | String | `access_token` | | `scope` | String | `scope` | | `token_type` | Optional string | `token_type` | | `expires_in` | Optional string | `expires_in` | | `refresh_token` | Optional string | `refresh_token` | The following example shows the configured inputs and output mappings for the get token webhook: ![A get token webhook with four input parameters, including an optional code verifier, and output parameters extracted by their JSON response keys.](../../../assets/f45bdcd7d328784d2f61e51510151a217e13475502da56bffb9d6556b9a8af55.webp) The refresh token webhook uses the same output mappings with its two input parameters: ![A refresh token webhook with client ID and refresh token inputs, and output parameters extracted from matching JSON response fields.](../../../assets/ab1c1351d5fbf307be366d903913d671fc4dbf553de87e2354b381afab038bd7.webp) #### Configure the outbound application Follow the instructions below to use the two saved webhooks to configure the OAuth 2.0 connection: 1. In Control Panel, open **Organization settings > Outbound applications** and select **New application**. 2. Provide an **Application name** and an **Approval prompt**, such as `Allow Foundry to act on your behalf in SAP?`. 3. Under **OAuth 2.0 server connection**, select **On-premise webhook**, which is marked **Legacy**. This option lets the outbound application use the SAP source's Data Accelerator connection. The source itself continues to run on a Foundry worker. 4. Under **Source connection**, select the SAP ERP source on which you created the webhooks. 5. Set **Token webhook** to the webhook using `sap-erp-oauth2-token-webhook-task` and **Refresh token webhook** to the webhook using `sap-erp-oauth2-refresh-webhook-task`. 6. Set **Authorization page URL** to `https:///sap/bc/sec/oauth2/authorize`. Use an SAP URL that users can reach from their browsers. This interactive authorization step requires access from the user's computer even though token exchange and refresh use SAP Data Accelerator. 7. Under **OAuth 2.0 settings**, set **Client ID** to the **OAuth 2.0 Client ID** created in the [SAP OAuth 2.0 configuration](#oauth-20-configuration). Following those instructions, this is the Foundry technical user's SAP username. 8. Add `/PALANTIR/SRV_0001` under **Scopes**. 9. Save the outbound application. ![An outbound application using On-premise webhook (Legacy), with an SAP ERP source, get token and refresh token webhooks, the SAP authorization URL, an example client ID of PALANTIR, and the /PALANTIR/SRV\_0001 scope.](../../../assets/0b2520fa0420c218fb67d82d5175cdb9e981ed939b986b75b8e1ea178b44f3ad.webp) #### Use the outbound application for writeback On the same SAP ERP source, create or edit the [webhook that invokes your BAPI](../../available-connectors/sap-erp/index.md#webhooks). For this BAPI webhook, select the saved application under **Request configuration > Authorization > Outbound application**. When a user runs the writeback workflow, Foundry prompts them to authorize access to SAP if they do not already have a valid token. The writeback then uses that user's SAP authorization, and the refresh token webhook obtains a new access token when needed. ### (Legacy) Webhook-based OAuth 2.0 configuration :::callout{theme="warning" title="Legacy"} The REST API webhook configuration described below is in the [legacy](../../platform-overview/development-life-cycle/index.md) phase of development and no additional development is expected. For new configurations, choose the matching connection setup under [Setting up the OAuth 2.0 client in Foundry](#setting-up-the-oauth-20-client-in-foundry). For more information on the legacy approach, see [(Legacy) Custom webhook-based OAuth 2.0 handshakes](../../administration/configure-outbound-applications/index.md#legacy-custom-webhook-based-oauth-20-handshakes). ::: Previously, configuring OAuth 2.0 for SAP required creating a dedicated REST API source with webhooks to handle the token and refresh flows manually. If your existing SAP integration uses this approach, it will continue to work. #### Source connection setup :::callout{theme="warning"} Ensure that the SAP source URL is using HTTPS, or webhooks will fail when using an OAuth flow. ::: 1. Create a new **REST API** source. ![Create REST API source](../../../assets/397743f63a15d9dbbeb2b00c2d071b0e6a1c10f5789f2afcc43d0ff81df239fa.webp) 2. Configure the source with the base domain URL and port used for the SAP source. 3. Select **Basic** authentication and add the username and password used to connect to SAP. ![Configure REST API source](../../../assets/f9c788881a37aa168fa13fd7839889ca1a49e3bd9f9e9e71e4db25be5e191545.webp) 4. Save the source. #### OAuth 2.0 authorization flow webhook setup :::callout{theme="warning" title="Webhooks published as functions are incompatible"} Webhooks published as functions cannot be used in legacy custom webhook-based OAuth 2.0 outbound applications. When creating your token and refresh webhooks, ensure function publishing is disabled. ::: 1. On the overview page of the new **REST API** source, select **Create webhook**. 2. Give the webhook a name (such as `SAP OAuth2 authorization code flow webhook`). Ensure that **Function Configuration** is toggled off. 3. Advance to the **Request configuration** step. 4. Under **Calls**, select **POST** as the request type and enter `sap/bc/sec/oauth2/token` as the path. 5. Under **Query Params**, `sap-client` might have to be set if the client used is not the default client. ![Webhook calls](../../../assets/94bcbbc7720c276551582e339a0090bc21992f343d0b07b428fbdd82e517cf5a.webp) 6. Scroll down to **Input Parameters** and add the following three parameters (all string type): * `redirect_uri` * `client_id` * `authorization_code` ![Webhook input parameters](../../../assets/cf548016ae7e4cf859ab3a654fe487243c6b86fb953487332addf8b1d68aca8b.webp) 7. Scroll back up to **Calls** and select the **Body** tab. 8. Choose **Form URL Encoded** and add the following four entries: * `grant_type` → `authorization_code` * `redirect_uri` → Mapped to the `redirect_uri` input parameter (see below for how to do this) * `client_id` → Mapped to the `client_id` input parameter * `code` → Mapped to the `authorization_code` input parameter 9. To map an input parameter, type **@** into the field and then select **Input Parameter**. Find the relevant parameter, select it and then select **Add** beneath. ![Input parameter mappings](../../../assets/925ae2d9c1e48a5551901825d70cef1d5b2c510b560491a1830186596e3c8f12.webp) 10. The finished **Body** configuration should look like this: ![Webhook body](../../../assets/b1d533e6ceaf6419c29a41924b9962673b4d9709603cbb0a41a207ab1e3cdc4d.webp) 11. Advance to the **Responses** step. 12. Create the following five **Output Parameters**. All should be of type string and should be extracted by key from the response. * `access_token` * `token_type` * `expires_in` * `refresh_token` * `scope` This is an example for creating `access_token`. All output parameters should follow this pattern. ![Webhook output parameter](../../../assets/9cd82b59a62cd50473c5974a9ec6c0379f16eb33a0305f33a70a635b44885262.webp) 13. Save the webhook by selecting **Create webhook and continue**. #### OAuth 2.0 refresh flow webhook setup 1. Create a new webhook from the **REST API** source. 2. Give the webhook a distinct name (such as `SAP OAuth2 refresh flow webhook`). Ensure that **Function Configuration** is toggled off. 3. The request method should again be set to **POST** and the same path (`sap/bc/sec/oauth2/token` ) should be used. 4. As with the previous webhook, set `sap-client` as a **Query Param** if needed. 5. On the **Headers** tab, add the following header: * `Content-Type` → `application/x-www-form-urlencoded` ![Refresh webhook header](../../../assets/828a94e5e50129a0c9fefff1009a0390137d7de54cd89a60e29c0352c01e3709.webp) 6. Set up these two **Input Parameters** (both strings): * `client_id` * `refresh_token` 7. Then under the **Body** tab, add these three entries: * `grant_type` → `refresh_token` * `client_id` → Mapped to the `client_id` input parameter * `refresh_token` → Mapped to the `refresh_token` input parameter ![Refresh webhook body](../../../assets/abd4d0c106a4398e4d40411117dfa831682b4fd7e54d31d1177830ca910175fb.webp) 8. Create exactly the same five **Output Parameters** as for the authorization code flow webhook. All should be of type string and should be extracted by key from the response. * `access_token` * `token_type` * `expires_in` * `refresh_token` * `scope` 9. Save the webhook by selecting **Create webhook and continue**. #### Legacy outbound application setup 1. Navigate to the **Foundry Control Panel** and select **Outbound applications**. 2. Give the application a name then follow the steps outlined under [(Legacy) Custom webhook-based OAuth 2.0 handshakes](../../administration/configure-outbound-applications/index.md#legacy-custom-webhook-based-oauth-20-handshakes). 3. The two webhooks created earlier should be used as the **Token webhook** and **Refresh token webhook** respectively. 4. The **Authorization page URL** should be of the form: ``` https:///sap/bc/sec/oauth2/authorize ``` 5. Under **OAuth 2.0 settings**, the **Client ID** should be set to the client ID from the SAP OAuth 2.0 server configuration. Under **Scopes**, add `/PALANTIR/SRV_0001`. 6. Save the outbound application. 7. This outbound application can now be used when creating an SAP webhook.