Disabling Highly Privileged Azure AD Users with Azure Logic Apps and Microsoft Graph API
Tags: azure, logicapps, microsoftgraph, tutorial
Published: 2023-03-31 02:25:07

If you're using Logic Apps to disable users in Azure AD with the Azure AD connector and encounter a **403 forbidden** error, it might be because the user is part of a role-assignable group. Members of these groups are considered **highly privileged**. 

As a result, your Logic App lacks the necessary permissions to disable these users via the Azure AD connector - even if your Azure AD account has an RBAC role such as **Privileged Authentication Administrator** or **Global Administrator**. 

Unfortunately, we can't add Graph permissions directly to the Logic App. But don't worry, with some Jedi mind tricks, you can get around it! 🧙

## Application Configuration
First, register a new application and define permissions to access and interact with Azure AD via the Graph API. Here's how to do it:

1. In the portal, navigate to **App registrations** > **New registration**.
2. Give it a memorable name and select **Register**.
3. Note the **Application (client) ID** for later use.

![Create a new app registration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qs0c9suxf5lj4ielj394.png)

Once the app is registered, add a new client secret and the required API permissions as follows:

## Adding a client secret

1. Select your application.
2. Navigate to **Certificates & secrets** > **Client secrets** > **New client secret** > **Add**.
2. Note the **Secret value** for later use.

![Adding a client secret](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1i4i8jk3niv1al8pzig.png)

## Configuring permissions
Next, configure permissions for the application. Review these permissions and others in the Graph documentation [here](https://learn.microsoft.com/en-us/graph/permissions-reference).

1.  Navigate to **API permissions** > **Add a permission**.
2.  Select **Microsoft Graph** > **Application permissions** and add the following permissions:
    -   Directory.ReadWrite.All
    -   Group.ReadWrite.All
    -   User.EnableDisableAccount.All
    -   User.ReadWrite.All
3.  Select **Grant admin consent for Default Directory** and confirm.

![Configuring permissions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vy07kwh1t0svopk2wde.png)

Your application is now configured. To enhance security, let's add the client secret to Key Vault.

## Azure Key Vault Configuration

Key Vault is an Azure key management solution that provides secure storage and management of keys, certificates, and secrets. Here's how to create a Key Vault:

1. In the portal, navigate to **Key vaults** > **Create**.
2. Select your **Resource group**.
3. Give it a memorable name and select your region.
4. **Standard** pricing tier should suffice.
5. Navigate to **Access Policy** and set permission model to **Azure role-based access control**.
6. Create the Key Vault.

![Creating the Key Vault](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eg0jy0dn6yb8kcuu29cf.png)

![Creating the Key Vault](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gyk6mxu3lcw9cz3zwdnp.png)

Now that the Key Vault is created, add the application client secret as follows:

1. Assign yourself permission to the Key Vault (e.g., Key Vault Administrator), see all available roles [here](https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-guide?tabs=azure-cli#azure-built-in-roles-for-key-vault-data-plane-operations).
2. Navigate to your Key Vault.
3. Navigate to **Secrets** > **Generate/import**.
4. Give it a memorable name.
5. Paste your **client secret value** from earlier.
6. Select **Create**.

![Add application client secret to Key Vault](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wkseh8ql3u63feew9csf.png)

![Successfully added client secret to Key Vault](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/euionud2e97nnq34rijj.png)

Now that your client secret is secured, create your Logic App and put all the pieces together!

## Logic App Configuration

Create a new Logic App resource. Here's how:

1. Select your **Resource group**.
2. Select **Create**, search for **Logic App**, and select **Create**.
3. Select your preferred **Subscription**, **Resource group**, and **Region**.
4. Give it a memorable name.
5. Select **Review + create** > **Create**.

![Creating the Logic App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gwfnrts1m6adq6087mzg.png)

6. Navigate to your new Logic App.
7. Select **Identity** > Enable **System assigned managed identity**.
8. Select **Azure role assignments** > **Add role assignment**
	- Scope: Key Vault
	- Subscription: Select your subscription
	- Resource: Select the Key Vault we created earlier
	- Role: I will be using **Key Vaults Secrets User**, but you can choose any sufficient role from the doiumentation [here](https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-guide?tabs=azure-cli#azure-built-in-roles-for-key-vault-data-plane-operations).

![Adding RBAC role to Logic App system assigned managed identity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xsvpc7bhq71nk4dv25dh.png)

## Workflow Configuration

1. Navigate to your new Logic App.
2. Select **Logic app designer**, you can start with a **template** or select **Blank Logic App**.
3. Add the Azure Key Vault **Get secret** action
	- Give your connection a memorable name
	- Authentication type: **Managed identity**
	- Vault Name: Enter the name of your Key Vault resource

![Add Azure Key Vault Get secret action to Logic App workflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5g9362lm2ee5f0ti026k.png)

After the API connection is authenticated, select the name of your secret.


![Select the name of your secret](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63rky1735t7xszy7qt6w.png)

Add an HTTP action and configure like so:
  - Method: POST
  - URI (Make sure to remove the braces and populate with your values): 
	  - https://login.microsoftonline.com/{INSERT-YOUR-TENANT-ID}/oauth2/v2.0/token
  - Headers:
	  - Content-Type: application/x-www-form-urlencoded
  - Body (Make sure to remove the braces and populate with your values):
```
client_id={INSERT-YOUR-APPLICATION-CLIENT-ID}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={INSERT-YOUR-APPLICATION-SECRET-VALUE}&grant_type=client_credentials
```

![Add HTTP action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrd6jtw91fkf27nskanm.png)

This first HTTP request will be to acquire our authentication token. The documentation regarding this process can be found [here](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#first-case-access-token-request-with-a-shared-secret).

Now we need to parse the JSON response in order to use the token in our call to Graph.

Add a Parse JSON action and configure like so:
	- Content: Body (from previous HTTP action)
	- Schema:
```json
{
	"properties": {
		"access_token": {
			"type": "string"
		},
		"expires_in": {
			"type": "integer"
		},
		"ext_expires_in": {
			"type": "integer"
		},
		"token_type": {
			"type": "string"
		}
	},
	"type": "object"
}
```

![Add a Parse JSON action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/787r409bg93799rp3at9.png)

Now the part you've been waiting for - disabling the user!

- Add another HTTP action, and configure like so: 
	- Method: PATCH
	- URI (Make sure to remove the braces):
		- https://graph.microsoft.com/v1.0/users/{INSERT-AZURE-AD-USER-UPN-HERE} 
	- Headers:
		- Content-Type: application/json; charset=utf-8
	- Body:
	```json
	{
	  "accountEnabled": "false"
	}
	```
	- Select **Add new parameter** > **Authentication**
		- Authentication type: Raw
		- Value: access_token (from Parse JSON action)

![Add HTTP action to disable user](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1063w42ydm7pgbfzp7m4.png)

- Save your workflow and **Run Trigger** to test.

![Save your workflow and run trigger to test.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26w0uaarqy3c6ite0ics.png)

- Verify the account was disabled.

![Verify the account was disabled](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1viq4bk9qa2ktua5ec0.png)

Thank you so much for taking the time to read my blog post. I hope you found it informative and helpful. If you have questions or feedback, please don't hesitate to reach out.