Make your Azure OpenAI apps compliant with RBAC
Tags: azure, ai, oauth, security
Published: 2024-03-25 17:05:18

Microsoft has effectively provided developers with relevant documentation to bootstrap their AI projects using [Azure OpenAI Services](https://learn.microsoft.com/en-us/azure/ai-services/openai/overview). But, as we delve into more advanced scenarios and start encountering edge cases, there seems to be noticeably less guidelines available.

What’s a recent example of this? Switching from using shared keys to **Entra ID Authentication/Authorization**.

Although shared keys are very easy to set up, you’ll likely want to avoid them for several reasons.
Firstly, if you lose the key or if someone gets their hands on it, you need to reset it. All systems that used the old key then need to be updated with the new one to keep working.
This becomes an issue when people leave the company; they might still have that shared key stored somewhere, and there is no way to revoke their permissions.
Plus, storing the key can be a security hazard in of itself.

Using Entra ID Authentication eliminates all these problems. It authenticates the user, and then delegates the [authorization](https://auth0.com/docs/get-started/identity-fundamentals/authentication-and-authorization#authentication-vs-authorization) component to a fine-grained, configurable system.

[Role-Based Access Management (RBAC)](https://learn.microsoft.com/en-us/azure/role-based-access-control/overview) is the current standard in Azure user access management. It’s the backbone of the entire authorization component in Entra ID authentication.

Permissions on a specific resource are set via **user roles**. Each user role encompasses a range of permissions. But when it comes to Azure OpenAI Services, what user roles should we use?

Disclaimer: Azure OpenAI Services is still a new feature and the technology may be subject to change. The tips shared in this article work now but may become less relevant in the future.

Also, Microsoft has developed specific libraries, such as [MSAL](https://learn.microsoft.com/en-us/entra/identity-platform/msal-overview), to run the client-side authentication process. Unless you have a good reason for sending the requests yourself, you should use those for the OAuth component. I will share the different requests involved in the OAuth 2.0 implicit flow, as well as how to retrieve an access token for Azure Open AI Services using Entra ID authentication.

## How to set up resources and permissions in Azure

Let’s assume you have already successfully [created an Azure Open AI Services deployment](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal). In my case, I have a text-davinci-003 deployment named `MyDaVinciDeployment`, inside a resource called `OpenAIResource`.

<aside>
✅ This following process works for any model, including GPT 3.5 turbo, GPT 4 and even Dall-E.
</aside>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ew2efmnm67t5oo7o3jq0.jpg)

To give users access to the AI service, you must provide them with the Cognitive Services User role by navigating to your AI resource and open the Access control (IAM) tab.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tto4vnpjtkruf15l7yme.jpg)

Create an app registration to access the API outside the Azure OpenAI Studio Playground.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouj4ngnbp556ox61gou8.jpg)

This important step provides the Application (client) ID, so copy it and keep it safe.

The app registration is not enough to gain access to the service. It registers the application, but does not grant any permissions. The app registration must be set up to perform authentication so that it can run some operations in the user’s name, with the user’s permissions.

On the app registration page, navigate to the authentication tab and set up a platform configuration for Single-page application. Set your own callback URL, and set the token type to `access token`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6y1bpray72o80delv7f.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqogvf4sgclj6kgm6wq2.png)

Next, we need to specify which permissions the authenticated user will delegate to the application. In the API permissions tab, add the `Microsoft Cognitive Services > user_impersonation` permission. You can find the Microsoft Cognitive Services API by searching it in the “APIs my organization uses” tab. Note that this permission might not show up if there is no AI service registered.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qcr517ync4v4octwasn9.png)

## Easy steps for authenticating

We will be performing all of the authentication requests manually, however for testing purposes, you might want to use an API testing tool such as [Postman](https://www.postman.com/) or [Insomnia](https://insomnia.rest/).

Here is a [Postman collection](https://raw.githubusercontent.com/Quertie/public-storage/main/Azure%20Open%20AI%20RBAC.postman_collection.json) to get you started.

The [OAuth 2.0 implicit grant flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-implicit-grant-flow) (the simplest) works as follows:

- The client sends a request to the authentication endpoint, specifying an application ID (to indicate which application is sending the request) and the desired scope - in our case: `https://cognitiveservices.azure.com/.default`
- The authentication server returns a login page.
- When the login is complete, the authentication endpoint issues an access token which can be used to request resources accessible to the logged in user and within the requested scope. In practice, the server redirects the user to a specific callback url and the token is communicated as a parameter or a fragment of that callback url.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6r4tz0zzeavc187cnfzy.png)

Let's cover both of these requests individually. First, the authentication request.

To keep things minimalistic, we do not include some optional parameters, but you might want to check them out depending on your use case.

For the following request, [here's how to find your tenant id](https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-microsoft-entra-tenant).

```xml
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id={client id}
&response_type=token
&redirect_uri={redirect uri}
&scope={https://cognitiveservices.azure.com/.default} # parameters should be URL-encoded
&response_mode=fragment
```

As an example, this is the request I’ll send:
```xml
GET https://login.microsoftonline.com/mycompany.com/oauth2/v2.0/authorize?
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865 # use client ID you copied earlier
&response_type=token
&redirect_uri=https%3A%2F%2Fexample.com%2Foauth%2Fcallback
&scope=https%3A%2F%2Fcognitiveservices.azure.com%2F.default
&response_mode=fragment
```

If you copy this url into a browser, you should be able to log in and eventually be redirected to your callback URL, which contains the access token as a fragment:

```xml
GET {callback url}#access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2Z...
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fcognitiveservices.azure.com%2F.default
```

<aside>
💡 If the authentication fails, you might want to make sure that Multi-Factor Authentication is enabled. It might not work without it.
Also, you might need administrator approval for this step.

</aside>

You can then use this token to interact with your deployment using [Azure Open AI Service’s REST API](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference).

As an example:

```xml
POST https://OpenAiResource.openai.azure.com/openai/deployments/MyDaVinciDeployment/
completions?api-version=2022-12-01

# Headers
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2Z...

# Body
{
    "prompt": "Once upon a time"
}
```

This token is valid for a limited time, after which it expires unless it is [refreshed](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-implicit-grant-flow#refreshing-tokens).

## More AI from Microsoft

The concepts covered in this article remain virtually the same throughout the Azure platform, but you will have to adapt some parameters (namely the user roles and requested scopes) to get your apps to work in the different contexts.

Microsoft offers an array of different AI-powered products, including [Azure OpenAI Service](https://azure.microsoft.com/en-us/products/ai-services/openai-service), [Azure AI Search](https://azure.microsoft.com/en-us/products/ai-services/ai-search/), [Azure AI Speech](https://azure.microsoft.com/en-us/products/ai-services/ai-speech/), and their most recent [Microsoft Copilot for Office 365](https://www.microsoft.com/en-us/microsoft-365/enterprise/copilot-for-microsoft-365).

Each of these services opens the door to a spectrum of exciting possibilities that we look forward to exploring.

Happy coding!