From 7ce05bb89adbd09af581b78daa09df0420898ee0 Mon Sep 17 00:00:00 2001
From: Garima Garg <211866541+ggarima01@users.noreply.github.com>
Date: Wed, 7 Oct 2026 15:12:05 -0700
Subject: [PATCH 1/2] Support OAuth client credential location and scopes
Adds OAuth 2.0 client credentials configuration for SCIM onboarding. Customers can select whether credentials are sent through the HTTP Basic Authorization header or request body, with Header as the default. Customers can also provide an optional space-delimited OAuth scope string. Updates the Logic App OAuth validation request, Entra connectivity parameters, onboarding agent instructions, setup documentation, validation overview, and bumps the Standard Logic App version to 13.0.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../Orchestrator_Parameters.json | 9 +++++-
.../SCIM-Validation-Test-Overview.md | 2 +-
.../StandardLogicApp/SCIMTests_Workflow.json | 6 ++--
.../SetupLogicApp-Standard-Agent.md | 13 ++++++--
.../StandardLogicApp/VERSION | 2 +-
.../StandardLogicApp/scim-onboarding.agent.md | 31 +++++++++++++------
6 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/Orchestrator_Parameters.json b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/Orchestrator_Parameters.json
index b3c4037a..ed7d6bc5 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/Orchestrator_Parameters.json
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/Orchestrator_Parameters.json
@@ -218,6 +218,13 @@
"type": "String",
"value": "changeme-oauth"
},
+ "scimCredentialLocationInRequest": {
+ "metadata": {
+ "description": "Required OAuth2 client credential location: Header or Body (used with OAuth2ClientCredentialsGrant)"
+ },
+ "type": "String",
+ "value": "Header"
+ },
"scimContentType": {
"metadata": {
"description": "Content-Type header for SCIM API calls"
@@ -231,7 +238,7 @@
},
"scimOAuthScope": {
"metadata": {
- "description": "OAuth2 scope for token acquisition (optional)"
+ "description": "Optional space-delimited OAuth2 scopes for token acquisition"
},
"type": "String",
"value": ""
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIM-Validation-Test-Overview.md b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIM-Validation-Test-Overview.md
index 9d72bd45..3a05925a 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIM-Validation-Test-Overview.md
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIM-Validation-Test-Overview.md
@@ -67,7 +67,7 @@ Tests that don't apply are reported as **SKIPPED** (not failures). However, grou
| 18 | **SCIM_User_Update_Test** | mandatory | Direct `PATCH /Users/{id}` with auto-generated update values for eligible attributes (single-valued, string/integer/datetime/boolean, excluding groups/roles/id/schemas/meta/active). | PATCH returns 200/204; subsequent GET returns 200/204; all PATCHed attribute values match in the response; zero mismatches. Passes with `(no updatable attributes)` if no eligible attributes exist. |
| 19 | **SCIM_Group_Create_Test** | mandatory | Direct `POST /Groups` with SCIM group body. **FAILED** if groups not supported. | HTTP 200 or 201; response contains non-empty `id`; returned `displayName` matches sent `displayName`. |
| 20 | **SCIM_Group_Update_Test** | mandatory | Direct `PATCH /Groups/{id}` with attribute updates (single-valued, non-reference, excluding id/members/schemas/meta). | PATCH returns 200/204; GET returns 200/204; all PATCHed attributes match; zero mismatches. |
-| 21 | **Validate_Credentials_Test** | mandatory | OAuth 2.0 Client Credentials flow — acquires token from ISV's `scimTokenEndpoint`, then validates SCIM access with the token. **Skipped** when `scimTokenEndpoint` is empty (static bearer token). | Token endpoint returns 2xx with `access_token`; token validity between 60–360 minutes; SCIM endpoint returns 2xx when called with the token. |
+| 21 | **Validate_Credentials_Test** | mandatory | OAuth 2.0 Client Credentials flow — acquires a token from the ISV's `scimTokenEndpoint`, sends credentials in the required `Header` or `Body` location, includes the optional space-delimited scope string, then validates SCIM access with the token. **Skipped** when `scimTokenEndpoint` is empty (static bearer token). | Token endpoint returns 2xx with `access_token`; token validity between 60–360 minutes; SCIM endpoint returns 2xx when called with the token. |
| 22 | **Federated_Identity_Test** | mandatory | Workload identity federation — acquires Entra ID token, then exchanges it for ISV token via one of three flows: Google Service Account, Google STS, or generic federated endpoint. **Skipped** when federated parameters are empty. | Entra token acquisition returns 2xx with `access_token`; federated token exchange returns 2xx with valid token. Supports Google SA flow (STS exchange → SA impersonation), Google STS flow (direct exchange), and generic flow (client assertion). |
| 23 | **SCIM_User_Pagination_Test** | mandatory | Ensures ≥11 users exist (creates throwaway users if needed), then paginates `GET /Users?startIndex=N&count=5` across pages. Cleans up created users afterward. | At least 2 pages traversed; all pages return HTTP 200; response `startIndex` matches expected value (`page * 5 + 1`); zero failed page verifications. |
| 24 | **SCIM_Group_Pagination_Test** | optional | Same as user pagination but for `/Groups`. Failure = WARNING. **Skipped** if groups not supported. | At least 2 pages traversed; all pages return HTTP 200; response `startIndex` matches expected; zero failed verifications. |
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json
index be7993bd..f39d9c98 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json
@@ -3462,10 +3462,8 @@
"inputs": {
"uri": "@{parameters('scimTokenEndpoint')}",
"method": "POST",
- "headers": {
- "Content-Type": "application/x-www-form-urlencoded"
- },
- "body": "@{concat('grant_type=client_credentials&client_id=', encodeUriComponent(parameters('scimClientId')), '&client_secret=', encodeUriComponent(parameters('scimClientSecret')), if(empty(coalesce(parameters('scimOAuthScope'), '')), '', concat('&scope=', encodeUriComponent(parameters('scimOAuthScope')))))}"
+ "headers": "@if(equals(toLower(coalesce(parameters('scimCredentialLocationInRequest'), 'Header')), 'header'), json(concat('{\"Content-Type\":\"application/x-www-form-urlencoded\",\"Authorization\":\"Basic ', base64(concat(parameters('scimClientId'), ':', parameters('scimClientSecret'))), '\"}')), json('{\"Content-Type\":\"application/x-www-form-urlencoded\"}'))",
+ "body": "@{concat('grant_type=client_credentials', if(equals(toLower(coalesce(parameters('scimCredentialLocationInRequest'), 'Header')), 'body'), concat('&client_id=', encodeUriComponent(parameters('scimClientId')), '&client_secret=', encodeUriComponent(parameters('scimClientSecret'))), ''), if(empty(coalesce(parameters('scimOAuthScope'), '')), '', concat('&scope=', encodeUriComponent(parameters('scimOAuthScope')))))}"
}
},
"Check_Token_Response": {
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SetupLogicApp-Standard-Agent.md b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SetupLogicApp-Standard-Agent.md
index 7270737a..44b27ece 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SetupLogicApp-Standard-Agent.md
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SetupLogicApp-Standard-Agent.md
@@ -408,12 +408,15 @@ hours.
will note that `Validate_Credentials_Test` will be skipped (this is
expected).
- **OAuth client credentials** — If you choose this, the agent will ask
- 4 follow-up questions:
+ 5 follow-up questions:
- **Client ID** — Your OAuth application’s client ID
- **Client Secret** — Your OAuth application’s client secret
- **Token Endpoint URL** — e.g., `https://auth.myapp.com/oauth/token`
- - **OAuth Scope** — The scope required for SCIM access (leave empty if
- not applicable)
+ - **How credentials are sent** — Required; select **Header** (the
+ default, using HTTP Basic authentication) or **Body** (`client_id`
+ and `client_secret` form fields)
+ - **OAuth Scope** — Optional; enter multiple scopes as one string
+ separated by spaces, or enter `none`
### Question 4: Azure Subscription Selection
@@ -1003,6 +1006,10 @@ style="width:4.43812in;height:2.54202in" />
+Update `scimCredentialLocationInRequest` with `Header` or `Body`.
+For OAuth endpoints that require scopes, update `scimOAuthScope` with
+the space-delimited scope string.
+
## Run the Logic App
34. You’re now ready to run the Logic app! Navigate to **WorkFlows\>**
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/VERSION b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/VERSION
index d7213f31..f0750610 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/VERSION
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/VERSION
@@ -1 +1 @@
-12.0
+13.0
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/scim-onboarding.agent.md b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/scim-onboarding.agent.md
index afc1475d..68db78b5 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/scim-onboarding.agent.md
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/scim-onboarding.agent.md
@@ -54,19 +54,22 @@ Collect the ISV's SCIM endpoint and bearer token, validate their Azure environme
b. **Bearer token** (must be long-lived — warn if JWT expires within 2 hours)
c. **Authentication method** — ask: "Does your SCIM endpoint use OAuth client credentials or a static bearer token?"
- - If **OAuth**: ask for all 4 parameters, one at a time:
+ - If **OAuth**: ask for all 5 parameters, one at a time:
- Client ID
- Client Secret
- Token endpoint URL (e.g., `https://auth.example.com/oauth/token`)
+ - How credentials are sent — **MANDATORY:** use `ask_user` with exactly two options: `Header` and `Body`. Set `Header` as the suggested default, but require the customer to confirm their selection.
+ - `Header` sends the client ID and secret using HTTP Basic authentication and omits them from the form body.
+ - `Body` sends `client_id` and `client_secret` in the form body.
- OAuth scope — **MANDATORY: use this EXACT prompt text in `ask_user`, do NOT paraphrase, do NOT use the words "leave blank", "leave empty", "optional", or "if not required":**
- > **OAuth scope** (e.g., `https://graph.microsoft.com/.default`).
+ > **OAuth scope** (e.g., `https://graph.microsoft.com/.default`). Enter multiple scopes as one string separated by spaces.
>
> ⚠️ If your token endpoint does NOT require a scope, type the word `none` (without quotes) and press Enter.
>
> Do NOT submit an empty box — empty submissions are treated as cancellation and the agent will stop.
The agent treats `none` (case-insensitive) as an empty scope when writing `scimOAuthScope` to `parameters.json`.
- - If **static bearer token**: record `authMethod = bearer`. The 4 OAuth fields (`scimClientId`, `scimClientSecret`, `scimTokenEndpoint`, `scimOAuthScope`) will be written as empty strings in Phase 4. (Logic App test behavior — including `Validate_Credentials_Test` — is out of scope for Phase 1; see Phase 4 for parameter handling and expected test behavior.)
+ - If **static bearer token**: record `authMethod = bearer`. The 5 OAuth fields (`scimClientId`, `scimClientSecret`, `scimTokenEndpoint`, `scimCredentialLocationInRequest`, `scimOAuthScope`) will be written as empty strings in Phase 4. (Logic App test behavior — including `Validate_Credentials_Test` — is out of scope for Phase 1; see Phase 4 for parameter handling and expected test behavior.)
d. **Federated identity test inputs (for `Federated_Identity_Test`)**:
- Ask: "Do you want to run the federated identity validation test now?"
@@ -216,6 +219,8 @@ Extract from response:
| Bearer only | A | Bearer | `authenticationType` + `baseAddress` + `secretToken` |
| Bearer + OAuth | B | OAuth | `authenticationType` + `baseAddress` + `oauth2ClientId` + `oauth2ClientSecret` + `oauth2TokenExchangeUri` + `credentialLocationInRequest` |
+For Branch B, also include the optional lower-case `scope` connectivity parameter when the ISV provided scopes. Omit `scope` when the ISV answered `none`.
+
---
**Sub-step 2b-1: validateCredentials (bearer — ALWAYS run this)**
@@ -275,7 +280,8 @@ az rest --method PATCH \
# {"key":"oauth2ClientId","value":""},
# {"key":"oauth2ClientSecret","value":""},
# {"key":"oauth2TokenExchangeUri","value":""},
-# {"key":"credentialLocationInRequest","value":"Header"}
+# {"key":"credentialLocationInRequest","value":""},
+# {"key":"scope","value":""}
# ]}
az rest --method PATCH \
--url "https://graph.microsoft.com/beta/servicePrincipals//synchronization/connectivityParameters" \
@@ -285,6 +291,8 @@ az rest --method PATCH \
> Note: `authenticationType=OAuth2ClientCredentialsGrant` is required for OAuth — without it, Graph won't attempt OAuth token acquisition from the stored creds.
>
+> `credentialLocationInRequest` is required for OAuth and must be exactly `Header` or `Body`, matching the ISV's Phase 1 answer. Add the `scope` entry only when the ISV provided one or more scopes; omit it when the ISV answered `none`. Preserve multiple scopes as one space-delimited string.
+>
> Inline `validateCredentials` with OAuth keys (i.e. `useSavedCredentials: false` + credentials array including OAuth keys) **works**, but do **not** include `CredentialLocationInRequest` in that inline payload — Graph returns `InternalError: Requested value 'CredentialLocationInRequest' was not found.` Keep that key only in the beta `connectivityParameters` PATCH payload.
Then validate saved credentials work (both branches) — **this is the Test Connection**:
@@ -303,7 +311,7 @@ az rest --method POST \
|---|---|---|
| HTTP 200/204 (empty body) | Test Connection succeeded — Entra can reach the ISV's SCIM endpoint using the saved credentials | Proceed to 2b-3 |
| HTTP 400 `CredentialValidationUnavailable` | **Branch A:** bearer token rejected by the ISV's SCIM server (401/403/5xx). **Branch B:** OAuth token exchange failed — wrong client ID, wrong client secret, bad token endpoint URL, scope issue, or the ISV's token endpoint issued a token that their SCIM server rejected. | Surface the inner error verbatim to the ISV. **ABORT.** Do NOT create the sync job — it will immediately quarantine. Wait for the ISV to provide corrected credentials, then re-PATCH `connectivityParameters` and re-validate. |
-| HTTP 500 `InternalError` — `"Requested value 'X' was not found"` | Inline validation payload included an unsupported key (for example `CredentialLocationInRequest`) or the connectivity parameters used the wrong key casing | Re-run inline validation with only the supported OAuth keys, then re-PATCH `connectivityParameters` using the lower-case portal keys (`authenticationType`, `baseAddress`, `oauth2ClientId`, `oauth2ClientSecret`, `oauth2TokenExchangeUri`, `credentialLocationInRequest`). Then re-validate. |
+| HTTP 500 `InternalError` — `"Requested value 'X' was not found"` | Inline validation payload included an unsupported key (for example `CredentialLocationInRequest`) or the connectivity parameters used the wrong key casing | Re-run inline validation with only the supported OAuth keys, then re-PATCH `connectivityParameters` using the lower-case portal keys (`authenticationType`, `baseAddress`, `oauth2ClientId`, `oauth2ClientSecret`, `oauth2TokenExchangeUri`, `credentialLocationInRequest`, plus `scope` only when provided). Then re-validate. |
| Any other 4xx/5xx | Unexpected | Surface verbatim and **ABORT**. |
Before aborting or retrying, capture the exact inner error and match it against **Step 6d: Known Issues**. If the response mentions `SystemForCrossDomainIdentityManagementServiceIncompatible`, Group connectivity, or an inner Group `404`, evaluate **Pattern #15**. Do not classify a generic `401`, `403`, rejected bearer token, or OAuth token-exchange failure as Pattern #15.
@@ -356,7 +364,8 @@ else:
| `scimClientId` | `""` | `` |
| `scimClientSecret` | `""` | `` |
| `scimTokenEndpoint` | `""` | `` |
-| `scimOAuthScope` | `""` | `` |
+| `scimCredentialLocationInRequest` | `""` | `` |
+| `scimOAuthScope` | `""` | `` |
For federated identity testing, also pass these Phase 4 parameters:
@@ -822,7 +831,7 @@ Pass criteria (ALL must hold):
- `schedule.state` is `Active`
If `status.code == Quarantine` with `lastExecError == SystemForCrossDomainIdentityManagementInvalidCredentials` and `lastExecMsg` mentions `BaseAddress`/`SecretToken`/credential, the Step 2b connectivity parameters were rejected or incomplete. Recovery:
-1. Re-PATCH `https://graph.microsoft.com/beta/servicePrincipals//synchronization/connectivityParameters` with ONLY the supported keys for the auth mode (bearer: `authenticationType` + `baseAddress` + `secretToken`; OAuth: `authenticationType` + `baseAddress` + `oauth2ClientId` + `oauth2ClientSecret` + `oauth2TokenExchangeUri` + `credentialLocationInRequest`).
+1. Re-PATCH `https://graph.microsoft.com/beta/servicePrincipals//synchronization/connectivityParameters` with ONLY the supported keys for the auth mode (bearer: `authenticationType` + `baseAddress` + `secretToken`; OAuth: `authenticationType` + `baseAddress` + `oauth2ClientId` + `oauth2ClientSecret` + `oauth2TokenExchangeUri` + `credentialLocationInRequest`, plus `scope` only when provided).
2. `POST /servicePrincipals//synchronization/jobs//restart` with body `{"criteria":{"resetScope":"Full"}}`. (Note: `credentials`/`watermark`/`escrows`/`quarantineState` are NOT valid restart criteria properties — schema only allows `resetScope`.)
3. `POST /jobs//start` again.
4. Re-run this Step 3h check. If still quarantined, abort and report the exact error.
@@ -907,7 +916,8 @@ Update these parameters in the JSON:
| `scimClientId` | `` | From Phase 1 — set if the ISV provided OAuth credentials. Used by the LA's `Validate_Credentials_Test` to exercise the OAuth flow independently. Empty string if not provided. **Note: Entra sync always uses bearer token (Step 2b), NOT these OAuth values.** |
| `scimClientSecret` | `` | From Phase 1 — same. Empty string if not provided. |
| `scimTokenEndpoint` | `` | From Phase 1 — same. Empty string if not provided. |
-| `scimOAuthScope` | `` | From Phase 1 — optional, set if provided (empty string if not). |
+| `scimCredentialLocationInRequest` | `` | From Phase 1 — mandatory when OAuth client credentials are provided. Empty string for static bearer authentication. |
+| `scimOAuthScope` | `` | From Phase 1 — optional; preserve multiple scopes as one space-delimited string. Empty string if the ISV answered `none`. |
| `federatedEntraTenantId` | `` | From Phase 1 federated inputs — empty string if not provided. |
| `federatedApplicationId` | `` | From Phase 1 federated inputs — empty string if not provided. |
| `federatedApplicationClientSecret` | `` | From Phase 1 federated inputs — empty string if not provided. |
@@ -924,7 +934,8 @@ After patching the JSON in memory, assert every key below exists at the top leve
servicePrincipalId, scimEndpoint, scimBearerToken, scimContentType,
testUserDomain, EnabledTests, IsSoftDeleted,
defaultUserProperties, defaultGroupProperties, scimTargetUserValues,
-scimClientId, scimClientSecret, scimTokenEndpoint, scimOAuthScope,
+scimClientId, scimClientSecret, scimTokenEndpoint,
+scimCredentialLocationInRequest, scimOAuthScope,
federatedEntraTenantId, federatedApplicationId, federatedApplicationClientSecret,
federatedTokenEndpoint, federatedClientId, federatedBaseAddress, federatedAudience
```
@@ -935,7 +946,7 @@ If any key is missing, abort Phase 4 and tell the ISV exactly which key is missi
After the PUT completes, re-GET `parameters.json` and for each key in the patch table above, assert the returned value matches what was sent. If `servicePrincipalId` was supposed to be `aaa-bbb-ccc` but the read-back shows something else (or the key is missing), abort Phase 4 with the specific mismatch. Do NOT proceed to Phase 5.
-If the ISV did not provide OAuth credentials, leave `scimClientId`, `scimClientSecret`, `scimTokenEndpoint`, and `scimOAuthScope` as empty strings. The `Validate_Credentials_Test` will be SKIPPED — note this as expected in the final report. This is unrelated to the Entra sync engine, which always uses the bearer token (`SecretToken`) configured in Step 2b.
+If the ISV did not provide OAuth credentials, leave `scimClientId`, `scimClientSecret`, `scimTokenEndpoint`, `scimCredentialLocationInRequest`, and `scimOAuthScope` as empty strings. The `Validate_Credentials_Test` will be SKIPPED — note this as expected in the final report. This is unrelated to the Entra sync engine, which always uses the bearer token (`SecretToken`) configured in Step 2b.
If the ISV did not provide federated identity inputs, leave all federated parameters as empty strings (`federatedEntraTenantId`, `federatedApplicationId`, `federatedApplicationClientSecret`, `federatedTokenEndpoint`, `federatedClientId`, `federatedBaseAddress`, `federatedAudience`).
From 592aeb9a37b1028e82b380a24732cb7767c55938 Mon Sep 17 00:00:00 2001
From: Garima Garg
Date: Thu, 8 Oct 2026 08:49:38 -0700
Subject: [PATCH 2/2] Encode OAuth Basic credentials per RFC 6749
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5c32705b-7e16-4b9e-8061-95f225ffc593
---
.../StandardLogicApp/SCIMTests_Workflow.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json
index f39d9c98..690ec0a4 100644
--- a/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json
+++ b/Microsoft.SCIM.LogicAppValidationTemplate/StandardLogicApp/SCIMTests_Workflow.json
@@ -3462,7 +3462,7 @@
"inputs": {
"uri": "@{parameters('scimTokenEndpoint')}",
"method": "POST",
- "headers": "@if(equals(toLower(coalesce(parameters('scimCredentialLocationInRequest'), 'Header')), 'header'), json(concat('{\"Content-Type\":\"application/x-www-form-urlencoded\",\"Authorization\":\"Basic ', base64(concat(parameters('scimClientId'), ':', parameters('scimClientSecret'))), '\"}')), json('{\"Content-Type\":\"application/x-www-form-urlencoded\"}'))",
+ "headers": "@if(equals(toLower(coalesce(parameters('scimCredentialLocationInRequest'), 'Header')), 'header'), json(concat('{\"Content-Type\":\"application/x-www-form-urlencoded\",\"Authorization\":\"Basic ', base64(concat(encodeUriComponent(parameters('scimClientId')), ':', encodeUriComponent(parameters('scimClientSecret')))), '\"}')), json('{\"Content-Type\":\"application/x-www-form-urlencoded\"}'))",
"body": "@{concat('grant_type=client_credentials', if(equals(toLower(coalesce(parameters('scimCredentialLocationInRequest'), 'Header')), 'body'), concat('&client_id=', encodeUriComponent(parameters('scimClientId')), '&client_secret=', encodeUriComponent(parameters('scimClientSecret'))), ''), if(empty(coalesce(parameters('scimOAuthScope'), '')), '', concat('&scope=', encodeUriComponent(parameters('scimOAuthScope')))))}"
}
},