Filtros de segurança para cortar resultados na Pesquisa de IA do Azure

O Azure AI Search não fornece permissões no nível do documento e não pode variar os resultados da pesquisa de dentro do mesmo índice por permissões de usuário. Como solução alternativa, você pode criar um filtro que corta os resultados da pesquisa com base em uma cadeia de caracteres que contém uma identidade de grupo ou usuário.

Este artigo descreve um padrão para filtragem de segurança que inclui as seguintes etapas:

  • Monte documentos de origem com o conteúdo necessário
  • Criar um campo para os identificadores principais
  • Enviar os documentos para o índice de pesquisa para indexação
  • Consultar o índice com a search.in função de filtro

Sobre o padrão de filtro de segurança

Embora o Azure AI Search não se integre aos subsistemas de segurança para acesso ao conteúdo dentro de um índice, muitos clientes que têm requisitos de segurança no nível do documento descobriram que os filtros podem atender às suas necessidades.

Na Pesquisa de IA do Azure, um filtro de segurança é um filtro OData regular que inclui ou exclui um resultado de pesquisa com base em um valor correspondente, exceto que, em um filtro de segurança, o critério é uma cadeia de caracteres que consiste em uma entidade de segurança. Não há autenticação ou autorização através da entidade de segurança. O principal é apenas uma cadeia de caracteres, usada em uma expressão de filtro, para incluir ou excluir um documento dos resultados da pesquisa.

Há várias maneiras de obter filtragem de segurança. Uma maneira é através de uma disjunção complicada de expressões de igualdade: por exemplo, Id eq 'id1' or Id eq 'id2', e assim por diante. Essa abordagem é propensa a erros, difícil de manter e, nos casos em que a lista contém centenas ou milhares de valores, diminui o tempo de resposta da consulta em muitos segundos.

Uma solução melhor é usar a search.in função para filtros de segurança, conforme descrito neste artigo. Se você usar search.in(Id, 'id1, id2, ...') em vez de uma expressão de igualdade, você pode esperar tempos de resposta subsegundo.

Pré-requisitos

  • O campo que contém a identidade do grupo ou do usuário deve ser uma cadeia de caracteres com o atributo filtrável. Deve ser uma coleção. Não deve permitir nulos.

  • Outros campos no mesmo documento devem fornecer o conteúdo acessível a esse grupo ou usuário. Nos seguintes documentos JSON, os campos "security_id" contêm identidades usadas em um filtro de segurança, e o nome, salário e estado civil serão incluídos se a identidade do chamador corresponder ao "security_id" do documento.

    {  
        "Employee-1": {  
            "id": "100-1000-10-1-10000-1",
            "name": "Abram",   
            "salary": 75000,   
            "married": true,
            "security_id": "10011"
        },
        "Employee-2": {  
            "id": "200-2000-20-2-20000-2",
            "name": "Adams",   
            "salary": 75000,   
            "married": true,
            "security_id": "20022"
        } 
    }  
    

    Nota

    O processo de recuperar os identificadores principais e injetar essas cadeias de caracteres em documentos de origem que podem ser indexados pelo Azure AI Search não é abordado neste artigo. Consulte a documentação do seu provedor de serviços de identidade para obter ajuda com a obtenção de identificadores.

Criar campo de segurança

No índice de pesquisa, dentro da coleção de campos, você precisa de um campo que contenha a identidade do grupo ou do usuário, semelhante ao campo fictício "security_id" no exemplo anterior.

  1. Adicionar um campo de segurança como um Collection(Edm.String)arquivo . Verifique se ele tem um filterable atributo definido para true que os resultados da pesquisa sejam filtrados com base no acesso que o usuário tem. Por exemplo, se você definir o group_ids campo para ["group_id1, group_id2"] o documento com file_name "secured_file_b", somente os usuários que pertencem aos IDs de grupo "group_id1" ou "group_id2" terão acesso de leitura ao arquivo.

    Defina o atributo do retrievable campo como false para que ele não seja retornado como parte da solicitação de pesquisa.

  2. Os índices requerem uma chave de documento. O campo "file_id" satisfaz este requisito. Os índices também devem conter conteúdo pesquisável. Os campos "file_name" e "file_description" representam isso neste exemplo.

    POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2023-11-01
    {
         "name": "securedfiles",  
         "fields": [
             {"name": "file_id", "type": "Edm.String", "key": true, "searchable": false },
             {"name": "file_name", "type": "Edm.String", "searchable": true },
             {"name": "file_description", "type": "Edm.String", "searchable": true },
             {"name": "group_ids", "type": "Collection(Edm.String)", "filterable": true, "retrievable": false }
         ]
     }
    

Envie dados por push para seu índice usando a API REST

Envie uma solicitação HTTP POST para a coleção de documentos do ponto de extremidade de URL do seu índice (consulte Documentos - Índice). O corpo da solicitação HTTP é uma renderização JSON dos documentos a serem indexados:

POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2023-11-01

No corpo do pedido, especifique o conteúdo dos seus documentos:

{
    "value": [
        {
            "@search.action": "upload",
            "file_id": "1",
            "file_name": "secured_file_a",
            "file_description": "File access is restricted to the Human Resources.",
            "group_ids": ["group_id1"]
        },
        {
            "@search.action": "upload",
            "file_id": "2",
            "file_name": "secured_file_b",
            "file_description": "File access is restricted to Human Resources and Recruiting.",
            "group_ids": ["group_id1", "group_id2"]
        },
        {
            "@search.action": "upload",
            "file_id": "3",
            "file_name": "secured_file_c",
            "file_description": "File access is restricted to Operations and Logistics.",
            "group_ids": ["group_id5", "group_id6"]
        }
    ]
}

Se precisar atualizar um documento existente com a lista de grupos, você pode usar a merge ação ou mergeOrUpload :

{
    "value": [
        {
            "@search.action": "mergeOrUpload",
            "file_id": "3",
            "group_ids": ["group_id7", "group_id8", "group_id9"]
        }
    ]
}

Aplicar o filtro de segurança na consulta

A fim de cortar documentos com base no group_ids acesso, você deve emitir uma consulta de pesquisa com um group_ids/any(g:search.in(g, 'group_id1, group_id2,...')) filtro, onde 'group_id1, group_id2,...' são os grupos aos quais pertence o emissor do pedido de pesquisa.

Este filtro corresponde a todos os documentos para os quais o group_ids campo contém um dos identificadores fornecidos. Para obter detalhes completos sobre como pesquisar documentos usando a Pesquisa de IA do Azure, você pode ler Pesquisar Documentos.

Este exemplo mostra como configurar a consulta usando uma solicitação POST.

Emita a solicitação HTTP POST:

POST https://[service name].search.windows.net/indexes/securedfiles/docs/search?api-version=2020-06-30
Content-Type: application/json  
api-key: [admin or query key]

Especifique o filtro no corpo da solicitação:

{
   "filter":"group_ids/any(g:search.in(g, 'group_id1, group_id2'))"  
}

Você deve obter os documentos de volta onde group_ids contém "group_id1" ou "group_id2". Em outras palavras, você obtém os documentos aos quais o emissor da solicitação tem acesso de leitura.

{
 [
   {
    "@search.score":1.0,
     "file_id":"1",
     "file_name":"secured_file_a",
   },
   {
     "@search.score":1.0,
     "file_id":"2",
     "file_name":"secured_file_b"
   }
 ]
}

Próximos passos

Este artigo descreve um padrão para filtrar resultados com base na identidade do usuário e na search.in() função. Você pode usar essa função para passar identificadores principais para que o usuário solicitante faça a correspondência com os identificadores principais associados a cada documento de destino. Quando uma solicitação de pesquisa é tratada, a função filtra os search.in resultados da pesquisa para os quais nenhuma das entidades do usuário tem acesso de leitura. Os identificadores principais podem representar coisas como grupos de segurança, funções ou até mesmo a própria identidade do usuário.

Para obter um padrão alternativo baseado no Microsoft Entra ID ou para revisitar outros recursos de segurança, consulte os links a seguir.