ПроектыProjects Larvatus
Коробочный продукт · офлайн-поставка в контур заказчика On-premise product · offline delivery into the customer's network
Larvatus
Обратимая анонимизация документов, баз данных и трафика к языковым моделям Reversible anonymisation of documents, databases and traffic to language models
Документ уходит к ИИ или подрядчику без персональных данных и возвращается с ними, даже если его успели переписать. A document goes to an AI model or a contractor without personal data and comes back with it, even after it has been rewritten.
Пять режимов, одно ядроFive modes, one core
ЯдроCore детектор → сопоставление → генераторы замен → контроль утечек · vault связей «реальное ↔ замена» detector → mapper → replacement generators → leak verifier · vault of "real ↔ replacement" links
За периметромOutside языковые модели · CRM и ERP заказчика · Active Directory · SIEM · KMS language models · customer CRM and ERP · Active Directory · SIEM · KMS
Обратимость и есть продуктReversibility is the product
Аналоги обезличивают в один конец. Здесь связь «реальное значение ↔ замена» хранится зашифрованной, и данные можно вернуть в документ, который уже побывал у модели. Similar tools anonymise one way. Here the "real value ↔ replacement" link is stored encrypted, so data can be returned to a document that has already been through a model.
Честный процент вместо иллюзии полноты. На замере вернулось 17 значений из 18 — ровно это система и показывает, перечисляя, чего не нашла. Ненайденное обычно означает, что модель перефразировала предложение. Тихо восстановить часть и промолчать про остальное — худшее, что можно сделать с документом, который пойдёт в дело. An honest percentage instead of an illusion of completeness. In a measured run 17 values out of 18 came back, and that is exactly what the system reports, listing what it could not find. A miss usually means the model rephrased the sentence. Silently restoring part and saying nothing about the rest is the worst thing to do to a document that will be used for real.
Порядок принципиаленThe order matters
Сначала человек видит находки рядом с самим документом, потом замены применяются, а исходники удаляются. Исправить настройку после применения будет негде: оригиналов не остаётся. First a human sees the findings next to the document itself, then replacements are applied and the source files are deleted. There is nowhere to fix a setting afterwards: no originals remain.
Экран ревью — центральныйReview is the central screen
- Переключатель «Оригинал / Данные»: документ в своём оформлении или фрагменты разбора подрядAn "Original / Data" switch: the document in its own layout, or the parsed fragments in a row
- Сканы и PDF: находки рамками поверх страницы по координатам символовScans and PDFs: findings as boxes over the page, placed by character coordinates
- Работа с клавиатуры, пропущенное добавляется выделением, отмена вместо подтвержденийKeyboard-driven, missed items added by selection, undo instead of confirmations
Три уровня детекции и честная уверенностьThree detection tiers and honest confidence
69 типов данных. Русский и английский включены одновременно: двуязычные договоры, имена латиницей в корпоративных системах, филиалы иностранных компаний. 69 data types. Russian and English are on together: bilingual contracts, Latin-script names in corporate systems, subsidiaries of foreign companies.
Правила и контрольные суммыRules and checksums
ИНН, СНИЛС, ОГРН, счёт по контрольному разряду от БИК, карта по Луну, IBAN по mod-97, VIN, европейские номера — PESEL, Steuer-ID, Codice Fiscale, NIR и другие.Russian tax and social IDs, accounts validated against the bank code, cards by Luhn, IBAN by mod-97, VINs, EU national numbers such as PESEL, Steuer-ID, Codice Fiscale and NIR.
NER для русскогоNER for Russian
Natasha, работает офлайн. Имена, организации, адреса — плюс словарь терминов, который правится в админке, чтобы продукты и аббревиатуры не читались людьми.Natasha, fully offline. People, organisations, addresses, plus a terms dictionary edited in the admin panel so product names and acronyms are not read as people.
LLM для неоднозначногоLLM for the ambiguous
С кешем, запасным провайдером и учётом расхода. В офлайн-комплекте — локальная GigaChat в отдельном контейнере, чтобы текст не покидал контур.With a cache, a fallback provider and spend tracking. The offline bundle can ship a local GigaChat in its own container so text never leaves the network.
Уверенность видна в интерфейсеConfidence is visible in the interface
Один человек — один ключOne person, one key
«Иванову», «Иванова» и «Иванов» — один человек, и замена у него одна. Одной лемматизации мало: «Волков И.И.» и «Волкова И.И.» сходились в один ключ, а редкая фамилия разбиралась как слово. "Ivanovu", "Ivanova" and "Ivanov" are one person and get one replacement. Lemmatisation alone is not enough: a man and a woman with the same initials collapsed into one key, and a rare surname was parsed as a common noun.
Поэтому фамилия сводится к родонейтральному корню, а пол добавляется к ключу отдельно — из имени и отчества, которые в косвенных падежах читаются надёжнее фамилии. So the surname is reduced to a gender-neutral root, and gender is added to the key separately, from the first name and patronymic, which read more reliably in oblique cases than the surname.
Что ещё ловитсяWhat else gets caught
- Спрятанные значения: разрядка, разметка внутри значения, невидимые знаки, смешение алфавитов, Base64Hidden values: letter spacing, markup inside a value, invisible characters, mixed alphabets, Base64
- Секреты: ключи API, токены, приватные ключи, хеши паролей, ключи облаковSecrets: API keys, tokens, private keys, password hashes, cloud keys
- ИТ-инфраструктура: хосты, адреса, учётные данные в ссылкахIT infrastructure: hosts, addresses, credentials inside URLs
- Специальные категории 152-ФЗ: диагнозы, национальность, вероисповеданиеSpecial categories under Russian law: diagnoses, ethnicity, religion
- Имя колонки как признак в SQL-дампах и CSVColumn names as a signal in SQL dumps and CSV
Порог recall проверяется тестом — регресс детектора роняет сборку. Метрики считаются отдельно по источникам: свои документы, документы двух клиентов, англоязычный договор, филиал иностранной компании. Корпус синтетический, и это оговорено: перед пилотом цифры перемеряются на настоящих документах отдельным процессом с ручной разметкой. The recall threshold is a test, so a detector regression breaks the build. Metrics are computed per source: own documents, two clients' documents, an English contract, a foreign subsidiary. The corpus is synthetic, and that is stated: before a pilot the numbers are re-measured on real documents through a separate hand-labelled process.
Два способа заменитьTwo ways to replace
Выбираются профилем. Одно значение получает одну замену в пределах пакета — в любом файле и в любой колонке. Chosen by profile. One value gets one replacement across the batch, in any file and in any column.
Токены — для работы с ИИTokens, for working with AI
- БылоBefore
- ООО «Ромашка», ИНН 0012345673
- СталоAfter
- ⟦ORG-001⟧, ИНН ⟦INN-001⟧
- ПочемуWhy
- токен — атом: не склоняется, не меняет регистр и почти не переживает переформулировкуa token is an atom: it does not inflect, does not change case and barely survives rephrasing
- ОбратимостьReversibility
- близка к 100%close to 100%
Суррогаты — для документов, которые читает человекSurrogates, for documents people read
- БылоBefore
- ООО «Ромашка», ИНН 0012345673
- СталоAfter
- ООО «Ветразь», ИНН 0098765437
- ПравилоRule
- суррогат проходит те же проверки, что оригинал: ИНН по контрольной сумме, счёт по БИК, карта по Лунуthe surrogate passes the same checks as the original: tax ID checksum, account against bank code, card by Luhn
- ИначеOtherwise
- документ не пройдёт контроль, а копия базы упадёт на ограниченияхthe document fails validation and a database copy breaks on constraints
Что сохраняется в суррогатахWhat surrogates preserve
- Пол и падеж ФИО: «договор с Ивановым» остаётся грамматически вернымGender and grammatical case of names, so sentences stay correct
- Родство: однофамильцы остаются однофамильцами, отчество выводится из суррогата отцовского имениKinship: relatives stay relatives, the patronymic follows from the father's surrogate name
- Хронология: даты сдвигаются на одну константу пакета, интервалы целыChronology: dates shift by one batch constant, intervals intact
- Пропорции: суммы умножаются на один коэффициент, итоги сходятсяProportions: amounts scale by one factor, totals still add up
- Возрастная когорта: границы 14 и 18 лет суррогат не пересекаетAge cohort: a surrogate never crosses the 14 and 18 year boundaries
- Топология сети и шаблон имён серверовNetwork topology and server naming patterns
ФИО по грануламNames by granule
- Худин Иван Петрович
- → Сумароков Захар Захарович→ Sumarokov Zakhar Zakharovich
- Худина Ольга Ивановна
- → Сумарокова Февронья Захаровна→ Sumarokova Fevronya Zakharovna
Фамилия, имя и отчество сопоставляются каждое от своего корня. Стал Иван Захаром — значит, его дети Захаровичи. Согласованность получается без кеша, а пул в 420 фамилий и 2 136 названий организаций не даёт разным семьям слиться в одну. Surname, first name and patronymic each map from their own root. If Ivan became Zakhar, his children are Zakharovich. Consistency comes without a cache, and pools of 420 surnames and 2,136 company names keep different families from merging.
Связанные группы. Реквизиты банка, организации, человека и хоста заменяются согласованно: БИК соответствует названию банка, КПП — региону ИНН, год бланка паспорта — дате выдачи. Поодиночке получился бы документ, который выглядит подделкой. Linked groups. Bank, company, person and host details are replaced together: the bank code matches the bank name, the registration code matches the tax ID region, the passport blank year matches the issue date. Replaced one by one, the document would look forged.
LLM-прокси: защита без человекаThe LLM proxy: protection without a human
Для приложения это замена одного адреса. Проверяется вся история диалога, системный промпт, контекст RAG, аргументы и результаты вызова инструментов. For the application it is one changed URL. The whole dialogue history is checked, along with the system prompt, RAG context, tool arguments and tool results.
Что делать с находкой, решает ключWhat to do with a finding is set per key
Бюджет задержки — 50 мс на p95Latency budget: 50 ms at p95
Поэтому LLM-уровень детекции в прокси выключен, а история диалога, которая приходит целиком на каждом ходу, не разбирается заново: кеш запоминает разметку, а не результат. That is why the LLM detection tier is off in the proxy, and the dialogue history, which arrives in full on every turn, is not re-parsed: the cache remembers the markup, not the result.
Кеш готовых файлов вернул бы документ из одного диалога в другой с чужими токенами, и восстановление подставило бы не того человека. Маппинг и сборка каждый раз идут против живого vault. A cache of finished files would carry a document from one dialogue into another with someone else's tokens, and restoration would insert the wrong person. Mapping and assembly always run against the live vault.
Время проверки запроса, мсRequest check time, ms
Детекция линейна по объёму текста, поэтому проверка вложений — опция на ключе. Повторный ход с тем же файлом дешевле в 8 раз. Detection is linear in text size, which is why attachment checks are a per-key option. A repeat turn with the same file is 8× cheaper.
Границы для агентовBoundaries for agents
- Остановка агентов отвечает 403, а не 503The kill switch returns 403, not 503
- 503 клиентские библиотеки повторяют сами, и остановка обернулась бы тем же потоком запросовclient libraries retry 503 on their own, turning the stop into the same stream of requests
- Подтверждение хранит ответ, а не переспрашивает модельApproval stores the reply instead of re-asking
- при temperature > 0 оператор подтвердил бы одно, а выполнилось бы другоеat temperature > 0 the operator would approve one thing and another would run
- Тысячи людей за одним ключомThousands of people behind one key
- пользователь называется подписанным утверждением, иначе один получил бы чужие восстановленные данныеthe user is named by a signed assertion, otherwise one would receive another's restored data
- Упало подключение к моделиA model connection fails
- ключу задаётся цепочка: запрос уходит в следующее, приложение о переключении не узнаётa key has a chain: the request moves to the next one and the app never notices
Протоколы клиента и провайдера независимы. OpenAI Chat и Responses, Anthropic Messages, нативные GigaChat и YandexGPT. Приложение на Claude SDK может ходить в GigaChat, а приложение на OpenAI SDK — в Claude. Совпавшие протоколы идут насквозь: обход через чужой формат потерял бы блоки рассуждений и пометки кеширования. Client and provider protocols are independent. OpenAI Chat and Responses, Anthropic Messages, native GigaChat and YandexGPT. An app on the Claude SDK can reach GigaChat, and an app on the OpenAI SDK can reach Claude. Matching protocols pass straight through: a detour via another format would lose reasoning blocks and cache markers.
Базы данных, сканирование, интеграцииDatabases, scanning, integrations
Не пять продуктов: детектор, хранилище связей, генераторы и контроль утечек написаны один раз, режимы лишь по-разному подают в них данные. Not five products: the detector, link store, generators and leak control are written once; the modes only feed data into them differently.
Режим баз данныхDatabase mode
- Подключение к боевой базе только на чтениеRead-only connection to the production database
- Классификация колонок: на карте показываются только неуверенныеColumn classification: the map shows only uncertain columns
- Копия со структурой и ссылочной целостностью: на ней работают тесты и аналитикаA copy with schema and referential integrity, fit for tests and analytics
- Строка таблицы — связанная группа, как блок реквизитов в договореA table row is a linked group, just like a block of details in a contract
- PostgreSQL, SQLite, MySQL/MariaDB, Oracle, ClickHouse; выгрузка в CSV и ParquetPostgreSQL, SQLite, MySQL/MariaDB, Oracle, ClickHouse; export to CSV and Parquet
СканированиеScanning
- Каталоги, шары SMB без монтирования, базы данныхFolders, SMB shares without mounting, databases
- Карта рисков в XLSX и PDF, динамика со второго прогонаA risk map in XLSX and PDF, with trends from the second run
- В отчёте нет ни одного значения из источникаNot a single source value appears in the report
- Отдельное право и отдельный модуль лицензии: «посмотреть» не даёт права копироватьA separate permission and licence module: "just look" does not grant copying
API, пакеты и вебхукиAPI, batches and webhooks
- Документ по HTTP: обезличенный файл или отчёт о находкахA document over HTTP: an anonymised file or a findings report
- Тысячи файлов одним заданием, в том числе архивомThousands of files in one job, archives included
- Папка под наблюдением и вебхук службы поддержки с идемпотентностьюA watched folder and an idempotent service-desk webhook
- Отчёт по умолчанию не содержит значений: он часто уходит в ту же модельReports carry no values by default: they often go to the very same model
MCP-серверMCP server
- Шесть инструментов: от «проверь текст» до «верни данные по билету»Six tools, from "check this text" to "restore data for this ticket"
- Готовый скилл и промпт: «любой документ сначала проверить»A ready skill and prompt: "check every document first"
- Честная граница: правило в промпте — привычка, а не рубеж; рубеж — проксиAn honest limit: a prompt rule is a habit, not a barrier; the proxy is the barrier
Форматы, которые разбираются целикомFormats parsed in full
- DOCX
- таблицы любой вложенности, колонтитулы, сноски, надписи, поля, свойства; следы рецензирования и примечания в результат не попадаютtables of any nesting, headers and footers, footnotes, text boxes, fields, properties; tracked changes and comments never reach the result
- XLSX, XLSM
- ячейки, примечания с авторами, литералы в формулах, кэш диаграмм и сводных таблицcells, comments with authors, literals in formulas, chart and pivot caches
- PPTX, PPTM
- слайды, заметки докладчика, SmartArt, диаграммыslides, speaker notes, SmartArt, charts
- PDF и сканыPDF and scans
- распознавание Tesseract, закрас находок, результат в PDFTesseract OCR, findings painted over, output as PDF
- Текст и данныеText and data
- TXT, MD, CSV, JSON, JSONL, YAML, XML, SQL-дампы, логи; DOC и XLS через конвертацию; ZIP и TARTXT, MD, CSV, JSON, JSONL, YAML, XML, SQL dumps, logs; DOC and XLS via conversion; ZIP and TAR
Продукт, который сам хранит самое ценноеA product that holds the most valuable data itself
Vault связей — ровно то, что нужно украсть, чтобы обратить обезличивание. Поэтому ключи, сроки и изоляция спроектированы раньше экранов. The link vault is exactly what an attacker would need to undo anonymisation. So keys, retention and isolation were designed before the screens.
Иерархия ключейKey hierarchy
AES-256-GCMМастер-ключ лежит в KMS или HashiCorp Vault и передаётся файлом секрета, а не переменной окружения: её значение видно в docker inspect. Из него — ключ организации, из него — ключ пакета. Поиск по связям идёт через HMAC-SHA256 с солью, оригиналы зашифрованы.The master key lives in a KMS or HashiCorp Vault and is passed as a secret file, not an environment variable, which would show up in docker inspect. It derives the organisation key, which derives the batch key. Lookups go through salted HMAC-SHA256; originals stay encrypted.
Изоляция организацийTenant isolation
Не только фильтры в коде, но и row-level security в PostgreSQL: приложение ходит в базу ограниченной ролью, и забытый WHERE org_id не приводит к утечке.Not only filters in code but row-level security in PostgreSQL: the app connects with a restricted role, so a forgotten WHERE org_id does not leak.
Что не логируетсяWhat is never logged
Содержимое документов, оригиналы значений, промпты в режиме прокси. В журнал идут только типы, счётчики и факты действий; выгрузка в SIEM по RFC 5424, CEF или JSON.Document content, original values, prompts in proxy mode. The log gets only types, counts and actions; SIEM export via RFC 5424, CEF or JSON.
Безопасные умолчанияSafe defaults
В режиме production сервис не стартует без ключей, а пароль admin не принимается. Новый ключ прокси запрещает ПДн, а не пропускает: тихо выпустить данные хуже, чем вернуть ошибку.In production mode the service will not start without keys, and the password admin is refused. A new proxy key blocks personal data rather than passing it: a silent leak is worse than an error.
Сроки жизни данныхData lifetimes
ИсходникиSources
удаляются сразу после обработкиdeleted immediately after processing
РезультатResult
7 дней, настраивается7 days, configurable
СвязиLinks
90 дней по умолчанию, срок задаёт организация, затем автоудаление; до этой даты возможен возврат данных90 days by default, set by the organisation, then auto-deleted; restoration is possible until then
Журнал аудитаAudit log
живёт дольше пакетаoutlives the batch
Границы проговорены в документации, а не оставлены на догадку. Персональные данные есть и в находках ревью, словарях и файловом хранилище; шифрование томов настраивается инфраструктурой. Уничтожение пакета удаляет ключ, связи и файлы, но не прежние бэкапы. Limits are spelled out in the documentation, not left to guesswork. Personal data also lives in review findings, dictionaries and file storage; volume encryption is an infrastructure concern. Destroying a batch removes the key, links and files, but not earlier backups.
Поставка в закрытый контурDelivery into a closed network
Заказчик, которому нужна анонимизация, обычно не пускает сервис в интернет. Поэтому поставка — офлайн-бандл, а лицензия — офлайн-ключ. A customer who needs anonymisation usually keeps the service off the internet. So delivery is an offline bundle and the licence is an offline key.
БандлBundle
Все образы, файл развёртывания и документация под amd64 и arm64. Установка — ./install.sh с --pull never: падает, а не зависает, если чего-то не хватает.All images, the deployment file and docs for amd64 and arm64. Install is ./install.sh with --pull never: it fails fast instead of hanging when something is missing.
Своя модельLocal model
Второй комплект везёт GigaChat 3.1 в отдельном контейнере с вшитыми весами; провайдер прописывается при установке, есть сборка под NVIDIA.A second bundle ships GigaChat 3.1 in its own container with baked-in weights; the provider is configured at install, with an NVIDIA build available.
ЛицензияLicence
30 дней пробного периода, дальше офлайн-ключ с четырьмя модулями: «Документы», «Прокси для LLM», «Базы данных», «Сканер-аудит»; учёт по местам и источникам. Ключ выпускается во вендорской админке, которая в бандл не входит.A 30-day trial, then an offline key with four modules: Documents, LLM Proxy, Databases, Scan Audit; counted by seats and sources. Keys are issued from a vendor console that is not part of the bundle.
ВходSign-in
Локальные пользователи, OIDC с PKCE и маппингом групп на роли, Active Directory напрямую — паролем через каталог или билетом Kerberos.Local users, OIDC with PKCE and group-to-role mapping, or Active Directory directly by password or Kerberos ticket.
Лицензии зависимостейDependency licences
Белый список: GPL-семейство и AGPL запрещены, поэтому pg8000 вместо psycopg и pdfplumber вместо PyMuPDF. SBOM и проверка уязвимостей в CI.An allow-list: GPL-family and AGPL are banned, hence pg8000 over psycopg and pdfplumber over PyMuPDF. SBOM and vulnerability checks in CI.
CI
Сборка бандла на каждом прогоне, совместимость с PostgreSQL 15, 16 и 17, приёмочный сценарий режима БД на SQLite, MySQL, Oracle и ClickHouse.The bundle is built on every run, with compatibility checks against PostgreSQL 15, 16 and 17 and the database-mode acceptance scenario on SQLite, MySQL, Oracle and ClickHouse.
СтекStack
Похожая задача у вас?Facing a similar problem?
Я спроектировал и написал этот продукт от первой строки до офлайн-поставки. Расскажу, как дать сотрудникам ИИ и не отдать ему персональные данные. I designed and built this product from the first line to offline delivery. I can tell you how to give people AI without handing it personal data.