<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Thomas W. Drake</title>
    <description>The latest articles on Forem by Thomas W. Drake (@thomasdrake).</description>
    <link>https://forem.com/thomasdrake</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1292371%2Fc27a10d3-505d-4c20-ab1d-6f75efcbe532.png</url>
      <title>Forem: Thomas W. Drake</title>
      <link>https://forem.com/thomasdrake</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thomasdrake"/>
    <language>en</language>
    <item>
      <title>Make your Azure OpenAI apps compliant with RBAC</title>
      <dc:creator>Thomas W. Drake</dc:creator>
      <pubDate>Mon, 25 Mar 2024 17:05:18 +0000</pubDate>
      <link>https://forem.com/upslide/using-rbac-with-azure-openai-services-1kl5</link>
      <guid>https://forem.com/upslide/using-rbac-with-azure-openai-services-1kl5</guid>
      <description>&lt;p&gt;Microsoft has effectively provided developers with relevant documentation to bootstrap their AI projects using &lt;a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/overview" rel="noopener noreferrer"&gt;Azure OpenAI Services&lt;/a&gt;. But, as we delve into more advanced scenarios and start encountering edge cases, there seems to be noticeably less guidelines available.&lt;/p&gt;

&lt;p&gt;What’s a recent example of this? Switching from using shared keys to &lt;strong&gt;Entra ID Authentication/Authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Although shared keys are very easy to set up, you’ll likely want to avoid them for several reasons.&lt;br&gt;
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.&lt;br&gt;
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.&lt;br&gt;
Plus, storing the key can be a security hazard in of itself.&lt;/p&gt;

&lt;p&gt;Using Entra ID Authentication eliminates all these problems. It authenticates the user, and then delegates the &lt;a href="https://auth0.com/docs/get-started/identity-fundamentals/authentication-and-authorization#authentication-vs-authorization" rel="noopener noreferrer"&gt;authorization&lt;/a&gt; component to a fine-grained, configurable system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/role-based-access-control/overview" rel="noopener noreferrer"&gt;Role-Based Access Management (RBAC)&lt;/a&gt; is the current standard in Azure user access management. It’s the backbone of the entire authorization component in Entra ID authentication.&lt;/p&gt;

&lt;p&gt;Permissions on a specific resource are set via &lt;strong&gt;user roles&lt;/strong&gt;. Each user role encompasses a range of permissions. But when it comes to Azure OpenAI Services, what user roles should we use?&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Also, Microsoft has developed specific libraries, such as &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/msal-overview" rel="noopener noreferrer"&gt;MSAL&lt;/a&gt;, 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set up resources and permissions in Azure
&lt;/h2&gt;

&lt;p&gt;Let’s assume you have already successfully &lt;a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal" rel="noopener noreferrer"&gt;created an Azure Open AI Services deployment&lt;/a&gt;. In my case, I have a text-davinci-003 deployment named &lt;code&gt;MyDaVinciDeployment&lt;/code&gt;, inside a resource called &lt;code&gt;OpenAIResource&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;✅ This following process works for any model, including GPT 3.5 turbo, GPT 4 and even Dall-E.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few2efmnm67t5oo7o3jq0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few2efmnm67t5oo7o3jq0.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftto4vnpjtkruf15l7yme.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftto4vnpjtkruf15l7yme.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create an app registration to access the API outside the Azure OpenAI Studio Playground.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouj4ngnbp556ox61gou8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouj4ngnbp556ox61gou8.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This important step provides the Application (client) ID, so copy it and keep it safe.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;access token&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6y1bpray72o80delv7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6y1bpray72o80delv7f.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqogvf4sgclj6kgm6wq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqogvf4sgclj6kgm6wq2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to specify which permissions the authenticated user will delegate to the application. In the API permissions tab, add the &lt;code&gt;Microsoft Cognitive Services &amp;gt; user_impersonation&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcr517ync4v4octwasn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcr517ync4v4octwasn9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Easy steps for authenticating
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; or &lt;a href="https://insomnia.rest/" rel="noopener noreferrer"&gt;Insomnia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a &lt;a href="https://raw.githubusercontent.com/Quertie/public-storage/main/Azure%20Open%20AI%20RBAC.postman_collection.json" rel="noopener noreferrer"&gt;Postman collection&lt;/a&gt; to get you started.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-implicit-grant-flow" rel="noopener noreferrer"&gt;OAuth 2.0 implicit grant flow&lt;/a&gt; (the simplest) works as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;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: &lt;code&gt;https://cognitiveservices.azure.com/.default&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The authentication server returns a login page.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6r4tz0zzeavc187cnfzy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6r4tz0zzeavc187cnfzy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's cover both of these requests individually. First, the authentication request.&lt;/p&gt;

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

&lt;p&gt;For the following request, &lt;a href="https://learn.microsoft.com/en-us/azure/azure-portal/get-subscription-tenant-id#find-your-microsoft-entra-tenant" rel="noopener noreferrer"&gt;here's how to find your tenant id&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id={client id}
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;response_type=token
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;redirect_uri={redirect uri}
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;scope={https://cognitiveservices.azure.com/.default} # parameters should be URL-encoded
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;response_mode=fragment


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As an example, this is the request I’ll send:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

GET https://login.microsoftonline.com/mycompany.com/oauth2/v2.0/authorize?
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865 # use client ID you copied earlier
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;response_type=token
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;redirect_uri=https%3A%2F%2Fexample.com%2Foauth%2Fcallback
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;scope=https%3A%2F%2Fcognitiveservices.azure.com%2F.default
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;response_mode=fragment


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

GET {callback url}#access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2Z...
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;token_type=Bearer
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;expires_in=3599
&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;scope=https%3A%2F%2Fcognitiveservices.azure.com%2F.default


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;💡 If the authentication fails, you might want to make sure that Multi-Factor Authentication is enabled. It might not work without it.&lt;br&gt;
Also, you might need administrator approval for this step.&lt;/p&gt;

&lt;p&gt;You can then use this token to interact with your deployment using &lt;a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/reference" rel="noopener noreferrer"&gt;Azure Open AI Service’s REST API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

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"
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This token is valid for a limited time, after which it expires unless it is &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-implicit-grant-flow#refreshing-tokens" rel="noopener noreferrer"&gt;refreshed&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More AI from Microsoft
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Microsoft offers an array of different AI-powered products, including &lt;a href="https://azure.microsoft.com/en-us/products/ai-services/openai-service" rel="noopener noreferrer"&gt;Azure OpenAI Service&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-us/products/ai-services/ai-search/" rel="noopener noreferrer"&gt;Azure AI Search&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-us/products/ai-services/ai-speech/" rel="noopener noreferrer"&gt;Azure AI Speech&lt;/a&gt;, and their most recent &lt;a href="https://www.microsoft.com/en-us/microsoft-365/enterprise/copilot-for-microsoft-365" rel="noopener noreferrer"&gt;Microsoft Copilot for Office 365&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each of these services opens the door to a spectrum of exciting possibilities that we look forward to exploring.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>ai</category>
      <category>oauth</category>
      <category>security</category>
    </item>
  </channel>
</rss>
