Фильтры безопасности для обрезки результатов поиска ИИ Azure

Поиск по искусственному интеллекту Azure не предоставляет разрешения на уровне документа и не может изменять результаты поиска в одном индексе по разрешениям пользователя. В качестве обходного решения можно создать фильтр, который обрезает результаты поиска на основе строки, содержащей группу или удостоверение пользователя.

В этой статье описывается шаблон фильтрации безопасности, включающий следующие действия.

  • Сборка исходных документов с необходимым содержимым
  • Создание поля для идентификаторов субъекта
  • Отправка документов в индекс поиска для индексирования
  • Запрос индекса с search.in помощью функции фильтра

Сведения о шаблоне фильтра безопасности

Хотя поиск по искусственному интеллекту Azure не интегрируется с подсистемами безопасности для доступа к содержимому в индексе, многие клиенты, имеющие требования к безопасности на уровне документа, обнаружили, что фильтры могут соответствовать их потребностям.

В поиске ИИ Azure фильтр безопасности — это обычный фильтр OData, который включает или исключает результат поиска на основе соответствующего значения, за исключением того, что в фильтре безопасности критерий — это строка, состоящая из субъекта безопасности. Проверка подлинности или авторизация не выполняется через субъект безопасности. Субъект — это только строка, используемая в выражении фильтра, для включения или исключения документа из результатов поиска.

Существует несколько способов фильтрации безопасности. Один из способов заключается в сложном дисъюнкции выражений равенства: например, Id eq 'id1' or Id eq 'id2'и т. д. Это ненадежный подход, его трудно поддерживать, а в тех случаях, когда список содержит сотни или тысячи значений, замедляется время ответа на запрос (в секундах).

Лучшее решение использует функцию search.in для фильтров безопасности, как описано в этой статье. Если вы используете search.in(Id, 'id1, id2, ...') вместо выражения равенства, вы можете ожидать несекундное время отклика.

Необходимые компоненты

  • Поле, содержащее группу или удостоверение пользователя, должно быть строкой с атрибутом, допускающим фильтрацию. Это должна быть коллекция. Он не должен разрешать значения NULL.

  • Другие поля в том же документе должны предоставлять содержимое, доступное для этой группы или пользователя. В следующих документах JSON поля "security_id" содержат удостоверения, используемые в фильтре безопасности, а имя, зарплата и семейное состояние будут включены, если удостоверение вызывающего объекта соответствует "security_id" документа.

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

    Примечание.

    Процесс получения идентификаторов субъекта и внедрения этих строк в исходные документы, которые можно индексировать с помощью поиска ИИ Azure, не рассматриваются в этой статье. Дополнительные сведения о получении идентификаторов см. в документации поставщика услуг удостоверений.

Создание поля безопасности

В индексе поиска в коллекции полей требуется одно поле, содержащее удостоверение группы или пользователя, аналогичное вымышленному полю "security_id" в предыдущем примере.

  1. Добавьте поле безопасности в виде Collection(Edm.String). Убедитесь, что он имеет атрибутtrue, filterable чтобы результаты поиска отфильтровылись на основе доступа пользователя. Например, если для документа file_name задано group_ids значение ["group_id1, group_id2"] "secured_file_b", только пользователи, принадлежащие идентификаторам групп "group_id1" или "group_id2", имеют доступ на чтение к файлу.

    Задайте атрибут false поля retrievable таким образом, чтобы он не возвращался в рамках поискового запроса.

  2. Для индексов требуется ключ документа. Поле "file_id" удовлетворяет требованиям. Индексы также должны содержать содержимое, допускаемое для поиска. Поля "file_name" и "file_description" представляют это в этом примере.

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

Отправка данных в индекс с помощью REST API

Отправьте HTTP-запрос POST в коллекцию документов конечной точки URL-адреса индекса (см. документы — индекс). Текст HTTP-запроса — это отрисовка документов, которые необходимо индексировать:

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

В тексте запроса укажите содержимое документов:

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

Если нужно обновить для имеющегося документа список групп, можно использовать действие merge или mergeOrUpload.

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

Применение фильтра безопасности в запросе

Чтобы сократить количество документов на основе доступа по group_ids, выполните поисковой запрос с использованием фильтра group_ids/any(g:search.in(g, 'group_id1, group_id2,...')) (где "group_id1 group_id2,..." — это группы, к которым принадлежит инициатор запроса).

Этот фильтр соответствует всем документам, для которых поле group_ids содержит один из заданных идентификаторов. Полные сведения о поиске документов с помощью службы "Поиск ИИ Azure" можно прочитать в документах поиска.

В этом примере показано, как настроить запрос с помощью запроса POST.

Выполните запрос 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]

В тексте запроса укажите фильтр:

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

Будут возвращены документы, в поле group_ids которых содержится "group_id1" или "group_id2". Другими словами, вы получаете документы, к которым у инициатора запроса есть доступ на чтение.

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

Следующие шаги

В этой статье описывается шаблон фильтрации результатов на основе удостоверения пользователя и search.in() функции. При применении этой функции идентификаторы субъектов для запрашивающего пользователя сопоставляются с идентификаторами субъектов, связанными с каждым целевым документом. Во время обработки поискового запроса функция search.in отфильтровывает результаты поиска, отклоняя файлы, для которых ни один из субъектов-пользователей не имеет доступа на чтение. Идентификаторы субъектов могут представлять группы безопасности, роли или даже удостоверение пользователя.

Альтернативный шаблон на основе идентификатора Microsoft Entra или для повторного просмотра других функций безопасности см. по следующим ссылкам.