Authentication and Authorization in Generative AI applications with Entra ID and Azure AI Search
Published Jan 09 2024 07:42 AM 4,524 Views
Microsoft

In this blog, I will address a scenario where a customer wishes to implement authentication and authorization for their generative AI applications. Recently, customers have been implementing RAG patterns to construct the generative AI application. I will provide a detailed guide on how to enable authentication for a Gen AI web app, which signs in users using Entra ID, and how to restrict access to web pages based on Entra ID security groups. Furthermore, I will discuss how to implement access control when searching documents on Azure AI Search, using the security group as a filter. This pattern can similarly be applied to other metadata elements, like user ID, for enhanced security and personalized information retrieval.

 

The following diagram demonstrates the architecture of a web app with identity and access management -

bbanerjee_0-1704478024381.png

Customer primarily using the demo repository or deploying the web app from Azure OpenAI studio.

 

Enabling authentication

 

After deploying your application, you must add an identity provider to facilitate authentication support. See this tutorial for more information.

 

  1. On your app's left menu, select Authentication, and then click Add identity provider.

  2. In the Add an identity provider page, for example select Microsoft as the Identity provider to sign in Microsoft and Microsoft Entra identities.

  3. Select a Tenant type, for example Workforce for work and school accounts or Microsoft accounts.

  4. For App registration > App registration type, select Create new app registration to create a new app registration in Microsoft Entra ID.

  5. Add a Name for the app registration, a public facing display name.

  6. For App registration > Supported account types, select Current tenant-single tenant so only users in your organization can sign in to the web app.

  7. In the App Service authentication settings section, leave Authentication set to Require authentication and Unauthenticated requests set to HTTP 302 Found redirect: recommended for websites.

  8. At the bottom of the Add an identity provider page, click Add to enable authentication for your web application.

  9. In the app's registration screen, select the API permissions blade in the left to open the page where we add access to the APIs that your application needs.

    • Select the Add a permission button and then:
    • Ensure that the Microsoft APIs tab is selected.
      • In the Commonly used Microsoft APIs section, select Microsoft Graph
      • In the Delegated permissions section, select User.Read and GroupMember.Read.All in the list. Use the search box if necessary.
      • Select the Add permissions button at the bottom.
    • GroupMember.Read.All requires admin consent. Select the Grant/revoke admin consent for {tenant} button, and then select Yes when you are asked if you want to grant consent for the requested permissions for all accounts in the tenant. You need to be an Azure AD tenant admin to do this.
    bbanerjee_1-1704467042868.png

     

Configure Security Groups

 

You have two different options available to you on how you can further configure your application(s) to receive the groups claim.

 

  1. Receive all the groups that the signed-in user is assigned to in an Azure AD tenant, including nested groups.
  2. Receive the groups claim values from a filtered set of groups that your application is programmed to work with (Not available in the Azure AD Free edition)

 

Configure your application to receive all the groups the signed-in user is assigned to, including nested groups

 

  1. In the app's registration screen, select the Token Configuration blade in the left to open the page where you can configure the claims provided tokens issued to your application.
  2. Select the Add groups claim button on top to open the Edit Groups Claim screen.
  3. Select Security groups or the All groups (includes distribution lists but not groups assigned to the application) option. Choosing both negates the effect of Security Groups option.
  4. Under the ID section, select Group ID. This will result in Azure AD sending the Object ID of the groups the user is assigned to in the groups claim of the ID Token that your app receives after signing-in a user.

 

Configure your application to receive the groups claim values from a filtered set of groups a user may be assigned to

 

  1. In the app's registration screen, select the Token Configuration blade in the left to open the page where you can configure the claims provided tokens issued to your application.
  2. Select the Add groups claim button on top to open the Edit Groups Claim screen.
  3. Select Groups assigned to the application.
    1. Choosing additional options like Security Groups or All groups (includes distribution lists but not groups assigned to the application) will negate the benefits your app derives from choosing to use this option.
  4. Under the ID section, select Group ID. This will result in Azure AD sending the Object ID of the groups the user is assigned to in the groups claim of the ID Token.
  5. In the app's registration screen, select on the Overview blade in the left to open the Application overview screen. Select the hyperlink with the name of your application in Managed application in local directory (note this field title can be truncated for instance Managed application in ...). When you select this link you will navigate to the Enterprise Application Overview page associated with the service principal for your application in the tenant where you created it. You can navigate back to the app registration page by using the back button of your browser.
  6. Select the Users and groups blade in the left to open the page where you can assign users and groups to your application.
    1. Select the Add user button on the top row.
    2. Select User and Groups from the resultant screen.
    3. Choose the groups that you want to assign to this application.
    4. Click Select in the bottom to finish selecting the groups.
    5. Select Assign to finish the group assignment process.
    6. Your application will now receive these selected groups in the groups claim when a user signing into your app is a member of one or more these assigned groups.
  7. Select the Properties blade in the left to open the page that lists the basic properties of your application. Set the User assignment required? flag to Yes.

 

Enabling document level access control

 

 

Add blob metadata

 

You can follow the instructions to add the group_id metadata in your blobs.

 

bbanerjee_0-1704467884255.png

 

 

Index file content and metadata by using Azure AI Search

 

User-specified metadata properties are extracted verbatim. To receive the values, you must define field in the search index of type Edm.String, with same name as the metadata key of the blob

 

Follow the instructions to create group_id field in AI Search index.

 

bbanerjee_1-1704470079272.png

 

Apply the group_id filter in the query

 

  1. The user’s identifier is extracted from the token claims and combined with the user’s group memberships.
  2. AI Search filter uses a specific search.in syntax that can support hundreds or even thousands of group or user identifiers in a single query.
  3. For example, to filter over the groups field using a single group identifier, the filter would be groups/any(g: search.in(g, 'x'))
  4. Filters can be combined using either an and or an or operator. For example, to match documents where either the user id or the group id is present in the access control fields, the filter would be groups/any(g: search.in(g, 'x')) or users/any(g: search.in(g, 'y'))

 

Here is a sample python code where user claims are extracted and used as a filter for searching - 

 

 

 

def build_security_filters(self, overrides: dict[str, Any], auth_claims: dict[str, Any]):
        # Build different permutations of the oid or groups security filter using OData filters
        # https://learn.microsoft.com/azure/search/search-security-trimming-for-azure-search
        # https://learn.microsoft.com/azure/search/search-query-odata-filter
        use_oid_security_filter = self.require_access_control or overrides.get("use_oid_security_filter")
        use_groups_security_filter = self.require_access_control or overrides.get("use_groups_security_filter")

        if (use_oid_security_filter or use_groups_security_filter) and not self.has_auth_fields:
            raise AuthError(
                error="oids and groups must be defined in the search index to use authentication", status_code=400
            )

        oid_security_filter = (
            "oids/any(g:search.in(g, '{}'))".format(auth_claims.get("oid") or "") if use_oid_security_filter else None
        )
        groups_security_filter = (
            "groups/any(g:search.in(g, '{}'))".format(", ".join(auth_claims.get("groups") or []))
            if use_groups_security_filter
            else None
        )

        # If only one security filter is specified, return that filter
        # If both security filters are specified, combine them with "or" so only 1 security filter needs to pass
        # If no security filters are specified, don't return any filter
        if oid_security_filter and not groups_security_filter:
            return oid_security_filter
        elif groups_security_filter and not oid_security_filter:
            return groups_security_filter
        elif oid_security_filter and groups_security_filter:
            return f"({oid_security_filter} or {groups_security_filter})"
        else:
            return None

 

 

 

Now, users can only search the documents associated with their respective Entra ID security groups. As a result, the Large Language Model (LLM) can provide answers based on the search results that users are already authorized to access. 

 

 

Happy learning!

 

Co-Authors
Version history
Last update:
‎Jan 09 2024 07:45 AM
Updated by: