Сотрудник не может открыть документ в хранилище, но получает его содержание в ответе корпоративного помощника. Ниже — как согласовать идентичность, права, индекс и контекст и проверить это на практике.
Права на документ в RAG проверяются до поиска, а не после ответа: система определяет сотрудника, ограничивает поиск доступными ему фрагментами и только затем строит ответ и цитаты. Признак доступа хранится у каждого фрагмента индекса и сверяется с правами запроса. Обязательная оговорка: свежесть прав зависит от синхронизации с источником, поэтому отзыв доступа может действовать с задержкой.
Сотрудник отдела закупок в условной компании «Северный мост» открывает внутренний чат и спрашивает: «Какие условия по отсрочке у подрядчика X?» Через несколько секунд он получает ответ с точной формулировкой из договора, который ему видеть не положено: файл лежит в папке юридического департамента, доступ к ней у закупщика закрыт. Формально он не взламывал систему и не обходил запреты — просто задал вопрос корпоративному помощнику. Именно этот разрыв между «нельзя открыть» и «можно прочитать в ответе» и разбирается ниже.
Механизм здесь простой и потому коварный. Поиск по документам (RAG, retrieval-augmented generation) сначала находит фрагменты, похожие на запрос, а потом передаёт их языковой модели, которая собирает ответ. Если на этапе поиска не учтены права конкретного сотрудника, система найдёт всё, что индексировано, независимо от того, что человеку разрешено открывать в файловом хранилище или в системе управления документами. Права проверяются в одном месте, а контент выдаётся в другом. Задача этой статьи — показать, как согласовать идентичность, права, индекс и контекст так, чтобы поиск не расширял доступ, и как это проверить на практике.

Что именно означает «права на документ» в контексте поиска
В обычной файловой системе право — это атрибут связки «пользователь — объект»: может читать, не может, может редактировать. В поисковом индексе эта связка не переносится автоматически: индекс хранит текстовые фрагменты и метаданные, но не наследует модель прав файловой системы. Поэтому связку «пользователь — объект» приходится воспроизводить в индексе явно. Поэтому между «документ лежит в защищённой папке» и «фрагмент документа лежит в индексе» появляется зазор, и всё дальнейшее — про то, как этот зазор закрыть.
Есть три разных слоя, которые часто путают. Первый — права на источник: кто может открыть исходный файл в месте его хранения. Второй — права на индекс: какие фрагменты система вообще имеет право искать от имени конкретного человека. Третий — права на контекст: что попадает в окно модели и в цитаты ответа. Утечка может случиться на любом из них, и закрытие одного слоя не гарантирует остальные. Документ, корректно отфильтрованный при поиске, всё равно может утечь, если его текст случайно оказался в общем кеше или в подобранном «похожем» фрагменте.
Отдельная тонкость — что считать «документом». Это может быть файл, страница вики, запись в базе, письмо, тикет. У каждого источника своя модель прав, и сводить их к одному признаку «доступно/недоступно» опасно: у страницы вики может быть наследование от пространства, у файла — от папки, у записи в базе — от роли. Прежде чем строить фильтр, нужно честно перечислить, из каких систем приходят документы и какая модель прав у каждой. Без этого инвентаря любая фильтрация будет догадкой.
Если ваша задача — проверить права документного поиска, на странице соответствующего направления 404ai можно посмотреть опубликованные возможности и оставить описание текущего процесса. Конкретные подключения, исходные данные и критерии приёмки согласуем отдельно.
Почему проверка прав до поиска, а не после ответа
Соблазн очевиден: пусть система найдёт всё релевантное, а потом мы отфильтруем то, что сотруднику нельзя. Проблема в том, что «потом» — это уже после того, как закрытый текст попал в контекст модели. Модель могла его пересказать, смешать с открытыми данными, упомянуть в промежуточных рассуждениях. Отфильтровать финальный ответ — значит надеяться, что утечка не просочилась в формулировку. Это не фильтрация, а попытка поймать воду после того, как она разлилась.
Правильный порядок обратный: сначала определить, кто спрашивает и что ему разрешено, затем ограничить поиск этим множеством, и только потом строить ответ из разрешённых фрагментов. Такой подход иногда называют security trimming — обрезкой по безопасности на этапе извлечения. Он требует, чтобы у каждого фрагмента в индексе был признак, по которому можно сопоставить его с правами спрашивающего. Этот признак — самая ответственная часть конструкции, и ниже ему посвящён отдельный разбор.
Есть и вторая причина проверять права до поиска: цитаты. Хороший ответ по документам ссылается на источники, чтобы сотрудник мог проверить. Но цитата — это тоже раскрытие: даже если в тексте ответа закрытых данных нет, ссылка на закрытый документ и его заголовок уже сообщают сотруднику то, что ему знать не положено. Поэтому фильтр должен работать и на уровне того, какие источники вообще могут быть процитированы.
Признак доступа: как связать фрагмент индекса с правами человека
Главный инженерный вопрос: как в индексе, который не знает про файловую систему, отметить, кому фрагмент доступен. Есть несколько подходов, и у каждого свои ограничения.
Первый — хранить у фрагмента список идентификаторов групп и пользователей, которым он доступен, и при поиске фильтровать по пересечению с группами спрашивающего. Это прямое отражение модели прав источника, но требует синхронизации: если в источнике права изменились, индекс должен узнать об этом. Второй — хранить у фрагмента ссылку на исходный объект и проверять права «на лету» при каждом запросе, обращаясь к системе-источнику. Это точнее, но дороже по задержке и зависит от доступности источника. Третий — гибрид: грубая фильтрация по группам в индексе плюс точная проверка на лету для тех фрагментов, что прошли первый фильтр.
Выбор зависит от того, насколько свежими должны быть права и сколько запросов выдерживает система. Если права меняются редко, синхронизация списков групп раз в час может быть приемлемой. Если сотрудника увольняют и доступ отзывают немедленно, «раз в час» — это окно утечки. Здесь нет универсально правильного ответа, есть осознанный компромисс, который нужно зафиксировать и проверить. О том, как устроены роли и привилегии в одной из распространённых платформ, полезно свериться с документацией Microsoft по ролям и привилегиям безопасности — это помогает понять, насколько гранулярной бывает модель прав в реальных системах, хотя конкретные механизмы вашего хранилища нужно проверять отдельно.
Эпизод первый: права отозвали, а индекс ещё помнит
Условная ситуация. В компании «Северный мост» сотрудник полгода работал над проектом и имел доступ к папке с коммерческими предложениями. Проект закрыли, доступ к папке отозвали в понедельник утром. В среду сотрудник спрашивает у корпоративного помощника: «Напомни, какие скидки мы давали по проекту „Ладога“?» Если индекс синхронизируется раз в сутки, а отзыв прав произошёл между синхронизациями, помощник может ответить по документам, которые человеку уже недоступны.
Здесь важно, что сотрудник не злоумышленник. Он задаёт рабочий вопрос и получает рабочий ответ — просто система не знает, что право уже отозвано. Утечка происходит без злого умысла, и обнаружить её сложно: в логах запрос выглядит нормально, ответ выглядит нормально. Именно поэтому отзыв прав — первый сценарий, который стоит проверять, и проверять не «в теории», а на реальном сотруднике с реальным отзывом доступа.
Что помогает. Во-первых, точная проверка прав на лету хотя бы для чувствительных источников: если фрагмент пришёл из папки, права на которую меняются часто, лучше сверить доступ в момент запроса, а не полагаться на вчерашний снимок. Во-вторых, журнал, в котором видно, по каким документам сотрудник получил ответ, — чтобы можно было восстановить картину, если что-то пошло не так. В-третьих, договорённость о том, что отзыв доступа в источнике и отзыв в индексе — это одна операция, а не две независимые. О том, как устроена обрезка по безопасности в поисковых системах, есть отдельный материал Microsoft — Security trimming in search; он описывает общий принцип, но не заменяет проверку вашей конкретной связки хранилища и индекса.
Эпизод второй: файл скопировали в общую папку
Другая условная история. Юрист сохраняет копию договора в общую папку «Для всех», потому что коллегам нужно быстро посмотреть условия. Оригинал лежит в защищённой папке юридического департамента, копия — в общедоступной. Индекс индексирует обе. С точки зрения прав всё корректно: копия действительно доступна всем, кто открыл общую папку. Но с точки зрения здравого смысла произошла утечка: закрытый документ стал доступен через копию, и никто этого не заметил.
Этот сценарий показывает, что фильтрация по правам — необходимое, но не достаточное условие. Она честно отражает права источника, но не отвечает на вопрос «а должен ли этот документ вообще быть в общем доступе». Копирование, пересылка, сохранение во временную папку — всё это создаёт новые объекты с новыми правами, и поиск будет их находить. Проблема не в поиске, а в гигиене хранения, но поиск делает её видимой и опасной: раньше копию надо было найти вручную, теперь её находит помощник по одному вопросу.
Практический вывод — не пытаться решить это только фильтром. Нужны, во-первых, правила, что можно копировать в общие папки, и, во-вторых, регулярная сверка: какие документы в общих папках дублируют закрытые источники. Поиск может помочь и здесь: если один и тот же текст находится и в закрытой, и в открытой папке, это повод разобраться. Но автоматически «склеивать» такие документы и скрывать копию нельзя — это уже цензура контента, а не контроль доступа.
Общий индекс на несколько компаний: где граница
Отдельный класс задач — когда один поисковый индекс обслуживает несколько организаций или несколько изолированных подразделений. Экономия очевидна: один индекс, одна модель, одно обслуживание. Риск тоже очевиден: если фильтр по организации не сработал, сотрудник одной компании получит фрагмент из документов другой. В отличие от внутренней утечки, это уже межорганизационная, и последствия у неё тяжелее.
Технически это решается тем же признаком доступа, что и внутри одной компании, но с обязательным измерением «организация» в каждом фрагменте и в каждом запросе. Ошибка, которая здесь встречается чаще всего, — доверять организации из параметров запроса, которые пришли от клиента. Если сотрудник может подставить чужой идентификатор организации, фильтр пропустит чужие документы. Поэтому организация должна определяться на стороне сервера по аутентифицированной сессии, а не по тому, что прислал клиент.
Второй риск — общие документы, которые по ошибке попали в индекс без метки организации. Такие «бесхозные» фрагменты либо не должны находиться вообще, либо должны быть явно помечены как доступные всем, и это должно быть осознанным решением, а не следствием забытой миграции. Хорошая практика — при загрузке в индекс отказывать документам без метки организации, а не молча помечать их как общие.
Сервисная роль шире пользовательской: скрытая причина утечек
Многие утечки происходят не потому, что фильтр неверный, а потому, что поиск ходит в хранилище под сервисной учётной записью, у которой прав больше, чем у любого сотрудника. Это удобно: одна учётная запись читает всё, индексирует всё, не спотыкается о права. Но если фильтрация по пользователю не реализована поверх этого, сервисная роль становится дырой: она видит всё, и всё попадает в ответ.
Здесь помогает разделение обязанностей. Сервисная учётная запись для индексации может читать всё — это её работа. Но поиск от имени сотрудника не должен использовать эту же учётную запись напрямую: он должен либо фильтровать результаты по правам сотрудника, либо обращаться к хранилищу от имени сотрудника (delegated access), если хранилище это поддерживает. Второй вариант точнее, но сложнее в настройке и не всегда возможен. Первый требует дисциплины: фильтр должен быть обязательным, а не опциональным, и его отсутствие должно ломать поиск, а не тихо отключаться.
Полезно периодически сверять: какие права у сервисной учётной записи и совпадают ли они с тем, что реально нужно для индексации. Если сервисная роль может не только читать, но и писать, и удалять, — это уже избыточные права, и их стоит сузить. Это не паранойя, а гигиена: чем меньше у сервисной роли прав, тем меньше ущерб, если что-то пойдёт не так.
Кеш между сотрудниками: незаметный канал утечки
Кеширование ответов — естественная оптимизация: если двадцать сотрудников задают один и тот же вопрос, зачем строить ответ двадцать раз. Но кеш, общий для всех, ломает фильтрацию: ответ, построенный для одного сотрудника с широкими правами, может быть отдан другому с узкими. Внешне всё корректно — вопрос тот же, ответ тот же, — но права у спрашивающих разные.
Решение — либо не кешировать ответы, зависящие от прав, либо включать в ключ кеша идентичность (или, точнее, набор прав) спрашивающего. Второе практичнее: кеш становится «на пользователя» или «на группу прав», и ответ не перетекает между разными уровнями доступа. Цена — меньше попаданий в кеш и больше вычислений, но это цена корректности.
Отдельно стоит кеш на уровне фрагментов: если поиск закешировал набор найденных фрагментов для запроса, этот набор тоже привязан к правам. Здесь та же логика: ключ кеша должен включать контекст доступа, иначе кеш тихо расширит права. И ещё одна тонкость — кеш на уровне модели: если провайдер модели кеширует контекст между запросами, нужно понимать, как он это делает и не смешивает ли контексты разных пользователей. Это вопрос к документации провайдера, и его стоит проверить до, а не после.
Цитата, которая раскрывает закрытое
Даже при корректной фильтрации поиска остаётся тонкий слой — цитаты и ссылки на источники. Ответ может быть построен только из разрешённых фрагментов, но если в цитате указан заголовок закрытого документа или его идентификатор, сотрудник узнаёт о существовании и теме документа. Иногда это допустимо, иногда — нет. Например, знать, что «есть договор с подрядчиком X», может быть нормально, а знать его номер и дату — уже лишнее.
Поэтому стоит определить политику цитат отдельно от политики поиска. Варианты: цитировать только те источники, которые сотрудник может открыть; цитировать с обезличенным заголовком; не цитировать вовсе, если источник закрыт, но использовать его содержание (что само по себе спорно — см. выше про проверку до поиска). Рекомендация — цитировать только открытые для сотрудника источники, а закрытые не использовать ни в ответе, ни в цитате: их содержание не должно попадать в контекст модели. Это не идеально, но честнее, чем делать вид, что цитата ничего не раскрывает.
Проверить это можно так: взять сотрудника с узкими правами, задать вопрос, ответ на который требует закрытого документа, и посмотреть, что он получит — отказ, обобщённый ответ без цитаты или утечку. Ответ «отказ» — самый безопасный, но не всегда самый полезный. Ответ «обобщённый без цитаты» — компромисс, который нужно явно одобрить как политику, а не оставить на усмотрение реализации.
Права на поисковый фрагмент: что должно быть у фрагмента и у запроса
Чтобы всё это не осталось благими пожеланиями, полезно зафиксировать минимальную форму данных. У каждого фрагмента в индексе должны быть: идентификатор исходного объекта, ссылка на систему-источник, метка организации (если индекс общий), набор групп или правил доступа, дата последней синхронизации прав и признак чувствительности. У каждого запроса — аутентифицированный идентификатор сотрудника, его группы, организация и момент времени. Без этих полей фильтрация превращается в гадание.
| Поле | Где хранится | Зачем нужно | Что ломается без него |
|---|---|---|---|
| ID исходного объекта | Фрагмент индекса | Сверить права на лету | Нельзя проверить актуальность доступа |
| Система-источник | Фрагмент индекса | Понять модель прав | Неясно, откуда брать права |
| Организация | Фрагмент и запрос | Изоляция компаний | Межорганизационная утечка |
| Группы доступа | Фрагмент индекса | Грубая фильтрация | Поиск находит всё |
| Дата синхронизации | Фрагмент индекса | Оценить свежесть прав | Незаметный отзыв доступа |
| Признак чувствительности | Фрагмент индекса | Точная проверка на лету | Дорогая проверка всего |
| ID сотрудника | Запрос | Идентичность | Анонимный поиск |
| Группы сотрудника | Запрос | Пересечение с фрагментом | Фильтр не с чем сравнивать |
Эта таблица — не догма, а чек-лист. В конкретной системе поля могут называться иначе и лежать в разных местах, но суть одна: у фрагмента и у запроса должно быть достаточно информации, чтобы принять решение о доступе до того, как текст попадёт в модель. Если какого-то поля нет, это не «мелочь», а конкретный сценарий утечки, который стоит закрыть.
Права на поисковый фрагмент на экране сотрудника
С точки зрения сотрудника всё это выглядит как поведение помощника. Если он задаёт вопрос, а ответа нет, важно, чтобы отказ был понятен и не выглядел поломкой. «Не могу ответить: у вас нет доступа к нужным документам» — честно, но иногда бесполезно. «Вот что я нашёл в доступных вам документах, а по остальному обратитесь к владельцу папки» — полезнее, но требует аккуратной формулировки, чтобы не раскрыть лишнего.
Хорошая практика — различать три состояния: ответ найден и полностью основан на доступных документах; ответ найден частично, и помощник честно говорит, что часть информации может быть в недоступных источниках; ответа нет, и помощник предлагает, к кому обратиться. Третье состояние особенно важно: оно превращает отказ в навигацию, а не в тупик. Сотрудник не получает закрытых данных, но получает путь к ним через человека, который вправе решить.
Отдельно стоит подумать о том, как сотрудник узнаёт, что его вопрос вообще упирается в права. Если помощник молчит, человек может решить, что документов нет, и пойти искать вручную — а найдёт или не найдёт, зависит от его прав. Ясное сообщение «это есть, но не для вас, вот кто может помочь» снижает и раздражение, и соблазн обходить систему.
Тесты: как убедиться, что фильтр работает
Проверять фильтрацию нужно не один раз при внедрении, а регулярно, потому что права, индекс и код меняются. Минимальный набор тестов выглядит так. Первый — тест на отзыв: сотрудник с доступом задаёт вопрос, получает ответ, доступ отзывают, сотрудник задаёт тот же вопрос, ответа по закрытому документу быть не должно. Второй — тест на копию: закрытый документ копируют в общую папку, проверяют, что поведение соответствует политике (находит или нет — в зависимости от решения). Третий — тест на изоляцию: сотрудник одной организации не получает фрагментов другой. Четвёртый — тест на кеш: два сотрудника с разными правами задают один вопрос, ответы не должны перетекать. Пятый — тест на цитату: закрытый источник не появляется в цитатах.
| Тест | Что проверяет | Как воспроизвести | Признак провала |
|---|---|---|---|
| Отзыв доступа | Свежесть прав | Отозвать доступ между запросами | Ответ по закрытому документу |
| Копия в общую папку | Политику копий | Скопировать закрытый файл | Неожиданная доступность |
| Изоляция организаций | Разделение компаний | Запрос от другой организации | Чужие фрагменты |
| Кеш между правами | Привязку кеша | Два пользователя, один вопрос | Ответ с широкими правами |
| Цитата закрытого | Политику цитат | Вопрос по закрытому источнику | Заголовок в цитате |
| Сервисная роль | Объём прав | Проверить права учётной записи | Избыточные права |
Эти тесты стоит автоматизировать и запускать при каждом изменении в индексации, фильтрации или модели прав. Ручная проверка раз в квартал не ловит регрессии, которые появляются при каждом обновлении. И ещё: тесты должны быть на реальных данных, а не на синтетических документах, потому что синтетика не воспроизводит наследование прав и странные копии, которые и создают утечки.
Практикум: проверка на одном вопросе за час
Условный сценарий для проверки. Возьмите один вопрос, ответ на который требует документа из папки с ограниченным доступом. Например, «какие условия по гарантии в договоре с подрядчиком Y». Убедитесь, что сотрудник с доступом к папке получает корректный ответ с цитатой. Затем возьмите сотрудника без доступа к папке и задайте тот же вопрос. Ожидаемый результат — либо отказ, либо ответ без цитаты и без содержания закрытого документа. Если сотрудник без доступа получает содержание — фильтр не работает.
Дальше усложните. Отзовите доступ у первого сотрудника и повторите его вопрос через минуту. Если ответ всё ещё приходит — синхронизация прав слишком медленная или её нет. Скопируйте закрытый документ в общую папку и повторите вопрос от сотрудника без доступа. Здесь результат зависит от вашей политики: если копия доступна, помощник её найдёт, и это повод разобраться с гигиеной хранения, а не с фильтром. Наконец, задайте один и тот же вопрос от двух сотрудников с разными правами подряд и сравните ответы: если они совпадают там, где не должны, — проблема в кеше.
Этот практикум не требует специальных инструментов, кроме доступа к системе и пары тестовых учётных записей. Час работы даёт больше, чем страница документации, потому что проверяет именно вашу связку хранилища, индекса и модели. И результат легко превратить в регрессионный тест, который будет запускаться дальше.
Что делать с найденными расхождениями
Если проверка выявила утечку, не стоит сразу чинить всё. Сначала — зафиксировать, на каком слое она произошла: права на источник, права на индекс или права на контекст. От этого зависит, что менять. Утечка на уровне источника — вопрос к гигиене хранения и к тому, кто и зачем копирует документы. Утечка на уровне индекса — вопрос к синхронизации прав и к признаку доступа у фрагментов. Утечка на уровне контекста — вопрос к кешу и к цитатам.
Дальше — решить, какой уровень свежести прав вам действительно нужен, и зафиксировать это как требование, а не как пожелание. Если отзыв доступа должен действовать немедленно, синхронизация раз в сутки не подходит, и это нужно признать до инцидента, а не после. Если допустимо окно в несколько часов, это тоже решение, но его нужно записать и проверить, что оно соблюдается.
И последнее: не полагаться на то, что «модель не станет раскрывать закрытое». Модель не знает, что закрыто, — она работает с тем, что ей передали. Ответственность за то, что ей передали, лежит на системе поиска и на тех, кто её настраивает. Поэтому единственный надёжный шаг — проверить права документного поиска на своём вопросе и своей учётной записи, а не верить, что фильтр «где-то там» настроен. Начните с одного вопроса, одного закрытого документа и одного сотрудника без доступа — и посмотрите, что вернёт помощник.
Смежный вопрос разобран отдельно: ИИ-агенты для CRM: права, одобрение и контроль.
Источники и границы разбора
Источники и статус проверки на 9 ноября 2026. Первичные документы поясняют указанные механизмы; доступность и границы каждого источника отмечены ниже. Методические рекомендации и условные примеры составляют самостоятельную часть разбора.
- Корпоративная база знаний с ИИ
Опубликованное направление работы 404ai. Предлагаемая в статье методика не означает, что каждое описанное действие уже доступно без настройки; состав решения согласуется отдельно.
- Microsoft: Security trimming in search
Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.
- Microsoft: Hybrid search
Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.
- Microsoft: Security roles and privileges
Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.