Skip to main content
Glama

Сайт находится по адресу conarium.dev; этот репозиторий и есть продукт.

Проверьте это, прежде чем читать остальное

Нижесказанному не обязательно верить на слово. Существует живая цепочка квитанций; проверьте её по её открытому ключу на своей машине, без аккаунта и без ваших данных:

npm i @conarium-ai/core
curl -fsS https://demo.conarium.dev/proof/chain.jsonl   -o chain.jsonl
curl -fsS https://demo.conarium.dev/proof/key.pem       -o key.pem
curl -fsS https://demo.conarium.dev/proof/key.pem.keyid -o key.pem.keyid
npx conarium-verify chain.jsonl --pubkey key.pem
note: tail truncation is not visible — this run did not see receipts deleted from the
end of the file. Pin with --expect-count, --expect-last-hash, or --anchor-check.
ok: 3 receipt(s) verified (3 with undeclared model, 3 with undeclared client)

Код возврата 0. Три квитанции — это одно обычное чтение, одно, где пять адресов электронной почты и номер карты были замаскированы до того, как модель их увидела, и один отказ. Измените любое поле — и пересчитанный хэш перестанет совпадать с сохранённым — код возврата 10. Измените подпись — код возврата 13.

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

Related MCP server: @lucairn/mcp-server

Ограничения

Чего этот репозиторий не делает, описано в LIMITATIONS.md (Türkçe). Страница сравнения с датами — conarium.dev/compare.html — это единственная копия; в этом репозитории вторая копия не хранится.

Стандарты

draft-dogru-scitt-disclosure-evidence — это индивидуальная заявка. Не принята рабочей группой IETF и не имеет формального статуса — интернет-черновик — это датированная публичная запись, а не стандарт. Он опубликован, чтобы формат квитанций можно было реализовать без нас. Исходные файлы находятся в standards/.

👁️ Проблема

Подключите Cursor или Copilot к производственной базе данных — и он выпьет необработанный поток: номера СНЛС, кредитные карты, зарплаты и действующие ключи. Один недобросовестный промпт может раскрыть ваши самые чувствительные таблицы. Специалисты по безопасности просто не могут этого допустить.

🛡️ Решение: Conarium

Conarium работает как высокопроизводительный MCP-прокси (Model Context Protocol). Он располагается непосредственно между ИИ-ассистентом и вашими базами данных, оценивая политики за миллисекунды, чтобы применять ограничения по количеству строк и маскировать PII (персональные данные) на лету.

ИИ получает контекст, необходимый для написания кода; значения, защищённые вашей политикой, маскируются до того, как дойдут до него. Маскирование скрывает значение — оно не делает его невозможным для изучения, и если язык запроса допускает предикаты по защищённому столбцу, разрешённый запрос всё равно может ответить на вопросы о нём. protectedColumns — это более узкий ответ на этот вопрос, и ограничение указано в LIMITATIONS.md, а не оставлено вам на самостоятельное обнаружение.

Ключевые возможности

  • Встроенное маскирование PII: электронные письма, идентификаторы, карты и секреты редактируются в потоке ответа ([MASKED_PII] / [MASKED_SECRET]) до того, как модель увидит хотя бы один символ.

  • Списки разрешений и запретов: внесите в белый список то, к чему ИИ может получить доступ. Ваши таблицы secrets и financials остаются невидимыми.

  • Ограничение строк: жёсткие лимиты на запрос. Предотвращает скрытую выгрузку миллионов строк.

  • Защищённый от несанкционированного доступа журнал аудита: каждое обращение через Conarium регистрируется (кто, что, когда, строки, решение). Хэш-цепочка делает обнаружение изменений и удаления из середины цепи возможным — но не невозможным: файл на диске всё ещё можно удалить или обрезать, а для обнаружения обрезки нужна контрольная точка извне файла (см. «Покрытие и сверка» ниже). Безопасно для PII: необработанные PII не записываются в журналы.

  • Проверяемые квитанции: квитанции с подписью Ed25519, независимо проверяемые — см. ниже.

  • Индивидуальные профили маскирования: то, что нужно маскировать для ИИ-агента, отличается от того, что нужно маскировать для контролёра данных. Именованный профиль ослабляет маскирование для одного идентифицированного лица, а в квитанции указывается, какой профиль применялся, — см. ниже.

  • Покрытие и сверка: подписанное заявление о покрытии цепочки квитанций (conarium-coverage), а также двусторонняя сверка со счётчиками запросов самой базы данных (conarium-reconcile) — активность, зафиксированная в БД, но не покрытая ни одной квитанцией, отображается, а не остаётся незамеченной.

  • На 100% самостоятельное размещение: работает полностью в вашей инфраструктуре. Ничто из того, что мы поставляем, не передаёт ваши данные куда-либо: необработанные защищённые значения остаются в вашем периметре, а до вашего ИИ-клиента доходит разрешённое политикой раскрытие, точные байты которого фиксируются в квитанции (disclosure.hash). Утверждать, что ваши данные вообще не покидают вашу сеть, было бы неверно: выпуск контролируемого раскрытия ассистенту — это и есть работа. Шлюз совершает ровно один исходящий запрос, который не является вашим: при запуске он запрашивает публичный реестр npm, не вышла ли новая версия, и, если да, выводит одну строку в stderr. Он не передаёт о вас ничего — ни идентификатора, ни конфигурации, ни счётчиков — и удалённый шлюз, на который никто не смотрит неделями, — причина, по которой он вообще существует. Отключите его с помощью CONARIUM_NO_UPDATE_CHECK=1 или укажите внутреннее зеркало с помощью CONARIUM_NPM_REGISTRY. Тайм-аут — 2 секунды, и он никогда не блокирует и не прерывает запуск. Мы упоминаем об этом, потому что продукт для управления, совершающий нераскрытое исходящее соединение, уже проиграл спор.

  • Нативный MCP: работает из коробки с Cursor, GitHub Copilot, Claude Code и Codex.

Проверяемые квитанции

Conarium может создавать переносимые квитанции (в формате Art. 12 / 19), которые третья сторона проверяет в автономном режиме одним файлом — установка Conarium не требуется.

Официальное заявление (не расширять): квитанция Conarium доказывает, что записи, всё ещё находящиеся в файле, не были изменены, переупорядочены или датированы задним числом после их создания, и что ни одна из них не была удалена из середины цепочки (prevHash / seq). Это не доказывает, что они были корректны в момент создания. Это также не может само по себе доказать, что записи не были удалены с конца: более короткая оставшаяся цепочка по-прежнему внутренне непротиворечива. Для обнаружения усечения хвоста требуется контрольная точка извне файла — --expect-count, --expect-last-hash, якорь OpenTimestamps или conarium-reconcile со счётчиками самой базы данных.

(TR) Conarium Makbuzu, dosyada hâlâ duran kayıtların oluşturulduktan sonra değiştirilmediğini, ortadan silinmediğini, yeniden sıralanmadığını ve geriye dönük tarihlenmediğini kanıtlar. Oluşturma anında doğru olduğunu kanıtlamaz. Sondan kesmeyi tek başına göremez: kalan zincir tutarlıdır, yalnızca kısadır. (/TR)

# Generate an Ed25519 keypair (private PEM + .pub.pem + .keyid sidecars).
# The .keyid sidecars are not optional: without them the verifier answers 13
# for every receipt, which reads like tampering and is not.
npx conarium-init

export CONARIUM_AUDIT_SIGNING_KEY=./audit-ed25519.pem

# init writes keys and config, not receipts: your own audit file does not exist
# until the gateway has served a query. The three commands below therefore run
# against the demo chain downloaded above, so they work as written — swap in
# your own sink (conarium.config.json → audit.sink) once it has records.

# Verify a receipt chain (exit 0 = the records *in the file* are intact)
npx conarium-verify chain.jsonl --pubkey key.pem

# Pin length / last hash if you need to catch records dropped from the end
npx conarium-verify chain.jsonl --pubkey key.pem --expect-count 3

# Check the OpenTimestamps sidecar. The demo chain ships without one, so this
# answers 14, deliberately not 0: an absent anchor is not a verified anchor.
# A sidecar that exists but is not yet confirmed → exit 0 with a warning.
npx conarium-verify chain.jsonl --pubkey key.pem --anchor-check

Второй верификатор, только на Go и стандартной библиотеке, находится в verifiers/go. go build -o conarium-verify ., затем те же аргументы, что и для conarium-verify; test-vectors/ — это контракт.

Дополнительное анкерование: CONARIUM_ANCHOR_SINK=opentimestamps. Обновляйте ожидающие доказательства позже с помощью npx conarium-anchor-upgrade ./audit.jsonl.anchors.jsonl. Клиент находится в дереве исходников (Node crypto + HTTPS календаря). Он не устанавливает javascript-opentimestamps. См. LIMITATIONS.md.

Индивидуальные профили маскирования

Маскирование, правильное для ИИ-агента, неверно для человека, владеющего данными. Владельцу, спрашивающему «какой клиент должен больше всех», нужно имя; ассистенту, суммирующему выручку, — нет. Отвечать на это глобальным переключателем вкл/выкл означало бы отключить единственную реальную гарантию продукта, поэтому маскирование разрешается индивидуально:

{
  "policy": {
    "allowTables": ["zion.customers", "zion.orders"],
    "maskColumns": ["*.customer_name", "*.email", "*.phone"],  // default: everyone
    "maxRows": 100,

    "profiles": {
      // The controller sees customer names; email and phone stay masked.
      "controller-full": { "maskColumns": ["*.email", "*.phone"], "maxRows": 1000 }
    },
    "actorProfiles": { "emekcan": "controller-full" }
  }
}

Осознанно узко, потому что это единственная функция, которая может ослабить защиту:

  • Профиль может переопределять maskColumns, maxRows и maskLabelledNames — и ничего больше. Разрешения на таблицы, инструменты и коннекторы остаются глобальными; профиль никогда не может расширить доступное, только то, что в нём читаемо. protectedColumns не переопределяется: профиль, который мог бы его отключить, стал бы персональным чёрным ходом.

  • Только персональные токены. Участник, прошедший проверку подлинности с помощью общего токена, никогда не получит профиль. «Тот, кто владеет этой строкой, видит немаскированные PII» — именно тот сбой, предотвращению которого и посвящён этот продукт.

  • Во всех остальных случаях — отказ по умолчанию: отсутствие участника, неучтённый участник или несуществующее имя профиля — всё это возвращается к базовой политике, но никогда к более широкой.

  • Сканеры контента по-прежнему работают. Детекторы электронной почты / национального идентификационного номера / телефона / карты / IBAN / секретов вообще не переопределяются, поэтому они остаются замаскированными в произвольном тексте независимо от применённого профиля. IBAN принимается только при соблюдении ISO 7064 mod-97-10. MRZ паспорта (TD3, контрольные цифры 7-3-1) включён по умолчанию и точно так же не может быть отключён профилем — только policy.detectors.mrz: false в базовой политике отключает его. IP-адреса выключены до policy.detectors.ip: true. Маскирование имён — единственный детектор, который профиль может отключить (maskLabelledNames: false), потому что контролёр, читающий собственный список клиентов, — это тот случай, для которого и существует эта функция.

  • В квитанции указано, какой профиль применялсяpolicy.id становится conarium.policy/<profile> внутри подписанного хэша. Доступ, выполненный в рамках ослабленного профиля, не может быть впоследствии представлен как полностью замаскированный. Это сохраняет честность аудита: дело никогда не было в том, что «никто не видит PII», а в том, что «каждый доступ управляется, и доказательства показывают, по каким правилам».

Имена в произвольном тексте

У любого другого идентификатора есть форма. В адресе электронной почты есть @, у национального идентификационного номера есть контрольная сумма, у карты есть длина — решает регулярное выражение, и решение воспроизводимо. У имени нет формы, поэтому maskColumns был единственным, что его ловило, и имя, введённое в текстовое поле note, доходило до модели без изменений.

Два детерминированных прохода закрывают ту часть этого пробела, которую можно честно закрыть:

Проход

Что его запускает

Пример

Перенос

Значение уже маскируется этой политикой в каком-либо столбце

customer_name маскируется, поэтому note: "Ayşe Demir called" тоже маскируется — в том числе и в разных строках

С пометкой

Сам текст это помечает: заголовок или подпись поля

Sn. Ahmet Yılmaz, Yetkili: Ayşe Demir, customer: John Smith

Чего это намеренно не делает: голое имя в бегущем тексте не обнаруживается. «Вчера звонил Ахмет» проходит насквозь. Для этого нужен NER — модель, словарь и оценка уверенности — а каждое решение этого шлюза должно быть воспроизводимо из одного лишь правила, тем, кто нам не доверяет. Вероятностный маскер был бы также вероятностной квитанцией. Инструменты, которые запускают NER (например, на основе Presidio), покрывают больше типов сущностей; они покупают это порогом уверенности. Ни одна позиция не доминирует — эта сформулирована так, чтобы аудитор знал, какую именно он держит в руках.

Всё ещё не обнаруживается контент-сканерами — намеренно, а не по упущению: почтовые адреса и голые имена. Детектор адресов не может отличить «Atatürk Caddesi No:15» от «Atatürk Barajı» без справочника. Детектор имён не может отличить Deniz / Güneş / Umut от обычных слов. Обоим понадобился бы словарь или модель; решения этого шлюза детерминированы. Закройте эти пробелы с помощью maskColumns (имена столбцов) и conarium-suggest-policy (основанная на именах догадка, которая не пишет ваш конфиг).

IP-адреса обнаруживаются когда вы их включаете (policy.detectors.ip: true). По умолчанию они выключены: серверный IP — не всегда персональные данные, а маска, которую нельзя отключить, ломает работу SOC. 1.2.3.4 структурно является валидным IPv4-адресом; когда детектор включён, он маскируется, даже если вы имели в виду номер версии. Даты (13.08.2026) и суммы (1.250,00) — не IPv4.

Номера паспортов в свободном тексте не обнаруживаются. MRZ — да: две строки TD3 × 44 символа, P в позиции 1, 7-3-1 контрольных цифр. Промах контрольной суммы — не MRZ, и он остаётся нетронутым. TD1/TD2 не реализованы.

HTML &#64; / &#x40;, JSON \u0040 и %40 маскируются, когда они находятся внутри токена, имеющего форму email. Одиночные 5&#64; store или C:\path\u0040abc остаются нетронутыми. Один проход декодирования; &amp;#64; не преследуется.

TCKN, разбитый на два одинаково названных поля в одной строке (tckn_1 / tckn_2), маскируется, когда конкатенация проходит контрольную сумму. Несвязанные столбцы не комбинируются.

Символы нулевой ширины, полноширинные цифры / и юникодные тире удаляются или преобразуются в ASCII до детекторов — этот проход не является универсальным декодером кодировок; обёрнутые base64/hex токены внутри поля маскируются только тогда, когда они декодируются в существующее срабатывание детектора.

Длина сканирования. Одно текстовое поле длиннее policy.scanCharCap (по умолчанию 16 384; переменная окружения CONARIUM_SCAN_CHAR_CAP переопределяет) заменяется целиком на [MASKED_PII], даже если оно не содержит идентификатора. Сканер не пропускается: пропуск означал бы, что длинная заметка, JSON-блоб или строка лога — это путь в обход маскирования. Это настройка удобства использования. Повышение её растёт квадратично по стоимости сканирования — поле из 40 КБ буквенно-цифровых символов занимало ~1 с на неограниченном email-регэкспe до того, как этот регэксп был ограничен. maskedCount фиксирует, что решение было принято.

Перенос игнорирует значения короче трёх символов (двухсимвольное значение совпадает везде и разорвало бы вывод) и сопоставляет по юникодным границам слов, так что Ali маскируется в Ali onayladı, но не внутри Kalite.

Покрытие и сверка (обнаружение обхода)

Квитанции доказывают, что прошло через шлюз. Сверка спрашивает базу данных, что она видела, и сравнивает:

Ни одна команда не выдумывает свои входные данные, и conarium-init не создаёт их, поэтому обе отвечают 20 (входные данные отсутствуют), пока вы их не создали: declaration.json — это ваше собственное заявление о периоде и охвате (docs/RECEIPT-SPEC.md называет поля), а два снимка приходят из scripts/pg-snapshot.sql.

# One-sided: signed coverage declaration over a period + declared scope
npx conarium-coverage ./declaration.json --pubkey ./audit-ed25519.pub.pem --receipts ./receipts.jsonl

# Two-sided: reconcile the DB's own per-role query counters against receipts.
# Snapshots come from pg_stat_statements (scripts/pg-snapshot.sql), taken at
# window start and window end with a dedicated DB role per gateway instance.
npx conarium-reconcile --before before.json --after after.json --receipts ./receipts.jsonl
# exit 0  = every DB query pattern in the window is attributable to a receipt for
#           the same table (object attribution, not per-statement coverage —
#           see LIMITATIONS.md)
# exit 40 = the DB recorded activity no receipt covers — the gateway may have
#           been bypassed, or the receipt sink failed

Язык намеренный: отсутствие сообщается как «доступ НЕ ЗАФИКСИРОВАН» / «не подтверждён квитанцией», никогда «доступа не было» — отсутствующая запись по своей природе неоднозначна, и инструмент, который притворяется иначе, врёт своему аудитору.

Запущено против нашего собственного производственного ERP в день релиза, включая реальный обход, который мы совершили сами и который инструмент поймал: docs/dogfood/2026-08-06-reconcile.md.

Полная схема, коды выхода и известные пробелы: docs/RECEIPT-SPEC.md.

Контрассигнация (та часть, которую вы не можете сделать сами)

Квитанции доказывают, что прошло через шлюз. Сверка доказывает, что ничего не прошло в обход него. Оба — ваши, самохостинговые и подписанные вашим собственным ключом — что как раз и обесценивает аудитор: вы хранили запись, вы её подписали, и вы её сохранили. Контрассигнация отвечает на это, помещая вторую сторону на ту же голову цепочки.

Сервис есть в этом пакете, так что вы можете запустить свой собственный и подписывать свои собственные головы — полезно для второго внутреннего хранителя и бессмысленно против возражения выше. Ценность ему придаёт то, что подписант — не вы.

# Run the endpoint. It refuses to start without a signing key or a token file:
# with neither present the three lines below exit 2 and name what is missing,
# which is the intended answer, not a failed install. Generating both is in
# deploy/anchor-service/.
CONARIUM_ANCHOR_TOKENS=./anchor.tokens.json \
CONARIUM_ANCHOR_SIGNING_KEY=./anchor.pem \
CONARIUM_ANCHOR_BASE_URL=https://anchor.example.com \
npx conarium-anchor-service

# Verify a countersignature you were given — offline, no network, no package.
# record.json is what the endpoint returned to you; without it, exit 20.
npx conarium-countersign-verify ./record.json --pubkey ./anchor.pub.pem
# exit 0  = signature valid (and inclusion valid if a proof or --log-url was given)
# exit 13 = signature invalid / unknown keyId
# exit 14 = inclusion proof present and false
# exit 15 = the log could NOT be checked — deliberately not the same as 14

Журнал — это хэш-цепочка: записи добавляются, никогда не переписываются, и OTS-метка времени покрывает голову, а не каждую отправку. Что доказывает контрассигнация — и, что не менее важно, чего она не доказывает — описано в docs/COUNTERSIGN.md, вместе с тем, во что обошлась бы утечка ключа подписи.

Pro — это хостинговая контрассигнация — кто-то другой, кроме вас, подписывает голову цепочки. $20/месяц или $200/год — экономия $40. Один период, не подписка. Он не продлевается сам — когда период заканчивается, доступ заканчивается, и вы можете купить его снова. 14-дневный возврат без вопросов; после этого частичных возвратов нет. НДС добавляется там, где применимо. Оформление заказа ещё не открыто: conarium.dev/buy перенаправляет на форму листа ожидания, пока платёжный путь не заработает, так что эти условия — опубликованная цена, а не то, что можно оплатить сегодня. Бинарник выше — это то, что вы запускаете сами; Pro — второй подписант. Поставляется в пакете с 0.2.16; конечная точка, управляемая VERAX, ещё не открыта для клиентов. Бизнес остаётся в листе ожидания: плановая сверка, оповещения о покрытии и подписанный отчёт о периоде — в контракте, ещё не выпущены.

Реализация формата самостоятельно

Квитанция должна пережить эту реализацию, поэтому она поставляется с векторами соответствия — двенадцать замороженных случаев плюс машиночитаемый манифест в test-vectors/:

npm run test:vectors     # our verifier against the frozen cases

Направьте свой собственный верификатор на каждый receipts.jsonl, передайте аргументы, перечисленные в manifest.json, и сравните код выхода. expected-hashes.json даёт канонические JCS → SHA-256 хэши, чтобы вы могли проверить свою канонизацию без нашего приватного ключа, который намеренно не публикуется.

Векторы при первом запуске нашли две вещи в этом репозитории: проверку схемы, которая сообщала о структурно невалидной квитанции как о подделанной, и наше неверное предположение о неподписанных квитанциях. Обе теперь заморожены как случаи 007 и 008.

Якорение вашей цепочки (опционально)

conarium-stamp якорит файл к календарям OpenTimestamps, а conarium-anchor-upgrade заполняет высоту блока Bitcoin, когда она появляется. Этих двух обычно достаточно для большинства установок.

Если вы предпочитаете выставить якорение как небольшой сервис — для нескольких шлюзов или чтобы дать аудитору стабильный URL — bin/conarium-anchor-service.mjs — это он: отправляет хэши, хранит доказательства, отдаёт сырой .ots по постоянному пути и обновляет ожидающие якоря по таймеру.

Это код, который вы запускаете, а не сервис, которым мы управляем — нет хостингового экземпляра, на который можно зарегистрироваться. Он также отдаёт сырое доказательство именно для того, чтобы третья сторона могла проверить его эталонным клиентом OpenTimestamps и полностью игнорировать сервис. Конечная точка якорения, которой нужно доверять, победила бы цель якорения.

Подпись закрывается при сбое: установите CONARIUM_AUDIT_SIGNING_KEY и/или CONARIUM_AUDIT_HMAC_KEY, или явно CONARIUM_AUDIT_UNSIGNED=1 для одноразовых установок. Ротация ключей: храните предыдущие публичные PEM в CONARIUM_AUDIT_TRUST_PUBKEYS (разделители , / ;). После первой подписанной строки аудита каждая последующая строка должна нести sig.

Где это находится среди похожих проектов

Conarium — не первый проект, создающий подписанные, проверяемые квитанции для активности ИИ. Acta, Emilia Protocol, AuthProof, Agent Receipts и Invariant SVR — все делают это в той или иной форме, и некоторые опережают нас в стандартизации — у Acta и Emilia есть IETF Internet-Drafts. Связанные исследования: Aegon (arXiv 2604.06693), Decentralised Trust Layers (ACM Web Conf 2026) и ISO/IEC TS 27560:2023 для подписанных записей согласия.

Эти квитанции удостоверяют, что агент сделал. Квитанция Conarium удостоверяет, что модели было предотвращено увидеть — потому что компонент, который маскирует данные, — это тот же компонент, который подписывает запись. Принуждение и доказательство — здесь одна часть, а не две системы, которые нужно согласовывать.

Что мы будем защищать: Conarium — единственная известная нам реализация, которая сочетает все три: (1) встроенное принуждение (политика + маскирование), (2) переносимую, офлайн-проверяемую квитанцию этого принуждения и (3) сверку покрытия — проверку собственных счётчиков запросов базы данных против цепочки квитанций, чтобы доступ, обходящий шлюз, всплывал, а не оставался невидимым. Подписывать квитанции без принуждения — распространено; принуждать без переносимых квитанций — распространено; сверять обе стороны против собственного учёта источника данных — та часть, которую мы не нашли больше нигде. Измерено от начала до конца на живом ERP реальной действующей компании — 121 374 записи, 121 366 личностей замаскировано, 485 496 полей замаскировано, ноль утечек модели (Governance Report 001).

Что это за число и чем оно не является. Оно получено из пакетного запуска против ERP нашей собственной компании, и подкрепляет его хэш-цепочный файл аудита из 123 строк, арифметику которого вы можете пересчитать сами и чья цепочка была повторно проверена 17 дней спустя. Что его не подкрепляет — это цепочка квитанций: тот запуск выдал записи аудита, а не подписанные переносимые квитанции, и его действующее лицо — пакетная сервисная личность, а не человек. Так что если вы спросите «покажите мне квитанции на эти 485 496 полей», честный ответ — их не существует; цепочка квитанций — это отдельное и гораздо меньшее измерение. Масштаб и офлайн-проверяемость — два разных утверждения здесь, и мы предпочли бы провести эту линию сами, чем чтобы вы её нашли. Механизм проверяем без доверия к нам; эта конкретная цифра — наше собственное измерение, и Governance Report 001 перечисляет его ограничения.

Это утверждение намеренно оговорено, и docs/PRIOR-ART.md — доказательство за ним: десять проектов, проверенных 6 августа 2026 года, что есть у каждого, ближайшая академическая предшествующая работа (Sello / Notarized Agents, которая называет этот пробел лучше, чем мы), и девять вещей, которые мы не смогли проверить. Если вы знаете реализацию, сочетающую все три, откройте issue, и оно будет исправлено.


🏗️ Архитектура (Триада)

Conarium работает на строгой трёхчастной архитектуре, балансируя власть между тремя столпами:

graph LR
    A([AI Assistant\nCursor / Copilot]) -- "MCP Query" --> B{The Gateway\nConarium Proxy};
    B -- "Intercept & Parse" --> C[The Engine\nGovernance & Regex];
    C -- "Execute Query" --> D[(Your Database\nPostgres / SQL Server / Oracle)];
    D -- "Raw Data" --> C;
    C -- "Mask & Cap" --> B;
    B -- "Sanitized Data" --> A;
    C -. "Write Log" .-> E[The Ledger\nAudit DB];
    
    style A fill:#05070f,stroke:#5a8cff,stroke-width:2px,color:#fff
    style B fill:#05070f,stroke:#ff6f80,stroke-width:2px,color:#fff
    style C fill:#05070f,stroke:#6fe0e0,stroke-width:2px,color:#fff
    style D fill:#05070f,stroke:#f2d79a,stroke-width:2px,color:#fff
    style E fill:#05070f,stroke:#838dad,stroke-width:2px,color:#fff
  1. Шлюз: Прокси, который бегло говорит с LLM-ассистентами.

  2. Движок: Оценивает JSON-политики, регэксп-сканирования и лимиты строк за миллисекунды.

  3. Реестр: Защищённый от вмешательства журнал аудита, записывающий каждый запрос и решение, которое он опосредует.


🚀 Быстрый старт

# 1. Install
npm i @conarium-ai/core

# 2. Write a fail-closed skeleton (config + Ed25519 pair + .keyid sidecars)
npx conarium-init
export CONARIUM_AUDIT_SIGNING_KEY="$PWD/audit-ed25519.pem"

# 3. Check the install before trusting it. Until step 4 points the config at a
#    reachable DSN, doctor reports the placeholder host unreachable and exits 1.
#    That FAIL is the check working, not the install being broken — it is the one
#    thing a gateway must not be quiet about, because it keeps running with zero
#    connectors and looks healthy while serving nothing.
npx conarium-doctor

# 4. Point the generated conarium.config.json at your read-only DSN,
#    fill policy.allowTables, then run the governed MCP gateway
npx conarium

Шаг 3 — не украшение. Отсутствующий файл конфигурации не останавливает шлюз — он запускается с нулём коннекторов и ничем не управляет — а коннектор, которому не удалось подключиться, логируется, а не вызывает исключение. conarium-doctor называет оба, выходит с 1, когда что-то не так, чтобы он мог гейтить развёртывание, и никогда не печатает секреты, так что его вывод безопасно вставлять в issue.

git clone https://github.com/dogrucanemek-alt/conarium.git
cd conarium
npm install && npm run build
# The repository already ships a conarium.config.json, so init refuses rather
# than overwrite it (exit 1). Pass --force only if you want it regenerated.
node bin/conarium-init.mjs --force
node bin/conarium-doctor.mjs --no-net
npm start

conarium-init отказывается перезаписывать существующие файлы, если не передать --force. Он никогда не выводит приватный ключ — только его путь.

Ярлык на рабочем столе для консоли

Редактор политик — это npx conarium-console. Он по-прежнему привязывается к 127.0.0.1 и по-прежнему требует токен. Эти две команды лишь добавляют дверь на рабочий стол:

npx conarium-console --install-shortcut
npx conarium-console --uninstall-shortcut

Windows

.lnk на рабочем столе (окно консоли свёрнуто)

macOS

~/Applications/Conarium Console.app

Linux

~/.local/share/applications/conarium-console.desktop

Двойной щелчок запускает ту же консоль, ждёт, пока порт начнёт слушать, затем открывает ваш браузер. Токен не помещается в URL; одноразовый nonce (≤30 с) обменивается на сессионный cookie. Если ярлык с таким именем уже существует, используется суффикс -2 вместо перезаписи.

Экспортируйте CONARIUM_CONSOLE_TOKEN перед --install-shortcut, чтобы лаунчер мог прочитать его из ~/.conarium/console.token (создаётся с правами 0600). Сам файл ярлыка не содержит токен.

Ярлык использует assets/conarium-mark.ico / .icns / -512.png, все из одного SVG. Если эти файлы отсутствуют, ярлык всё равно создаётся, и команда выдаёт предупреждение.

Вкладка Makbuzlar в консоли перечисляет подписанные квитанции из audit.receiptSink (сначала новые) и показывает тот же HTML-код квитанции, что и demo.conarium.dev/proof. Она проверяет хеш-цепочку и записывает zincir sağlam или kırık (satır N). Если приёмник пуст или не задан, она сообщает об этом — она не выдумывает образец квитанции. Журналы аудита остаются неподписанным следом для экспериментов; они не являются квитанциями.

Когда пакет появится на npm, те же бинарники будут поставляться в tarball (conarium-init, conarium-doctor, conarium-verify, conarium-suggest-policy). До тех пор запускайте их из этого репозитория, как указано выше.

Прежде чем сообщать об ошибке: запустите doctor

conarium-doctor проверяет то, что отказывает тихо. Два из них наиболее важны: отсутствующий файл конфигурации не останавливает шлюз — он запускается с нулевым количеством коннекторов и ничего не управляет — и коннектор, который не может подключиться, логируется, а не вызывает исключение, поэтому процесс выглядит здоровым, хотя ничего не обслуживает. Doctor также ловит отсутствующий файл <pubkey>.keyid, из-за которого каждая квитанция проверяется как 13 (выглядит как подделка, но это не так).

Он завершается с кодом 0, когда всё чисто, и 1, когда что-то не так, поэтому его можно использовать для контроля развёртывания. Он никогда не выводит секреты — пароли, токены и ключевой материал сообщаются только в виде формы (postgresql://appuser@db.internal:5432/prod (password set, not shown)), что означает, что вывод можно безопасно вставлять в issue или письмо.

Conarium общается по MCP через stdio, поэтому ваш ИИ-ассистент запускает его как команду. Добавьте это в конфигурацию вашего MCP-клиента (например, Cursor):

{
  "mcpServers": {
    "conarium": {
      "command": "npx",
      "args": ["-y", "--package=@conarium-ai/core", "conarium", "--config", "/path/to/your/conarium.config.json"]
    }
  }
}

⚙️ Конфигурация (Policy as Code)

Управляйте доступом с помощью простого файла политики conarium.json:

{
  "maxRows": 50,
  "allowTables": ["public.customers", "public.orders"],
  "denyTables": ["public.secrets", "public.financials"],
  "maskColumns": ["email", "ssn", "*.card", "*.api_key"],
  "protectedColumns": ["*.email", "customers.tckn"],
  "allowConnectors": ["postgres-main", "docs"]
}

Всё, что не указано в allowTables, по умолчанию запрещено; совпадающие maskColumns редактируются до [MASKED_PII] до того, как данные вообще достигнут модели.

protectedColumns использует тот же синтаксис glob. Каждый шаблон также маскируется в результате. Кроме того, этот столбец не может появляться в предикате (WHERE, HAVING, JOIN … ON, ORDER BY, GROUP BY) или в производном выражении SELECT — запрос отклоняется. Простой SELECT email по-прежнему разрешён и возвращается замаскированным. Если поле опущено, поведение не меняется. Профиль не может его установить. mssql / oracle отказываются запускаться, если поле не пусто: эти шлюзы не могут обрабатывать позиции предикатов, и этот продукт не заявляет правило, которое не может обеспечить.

policy.dialect выбирает SQL-шлюз, который использует инструмент query: postgres (по умолчанию, если опущено), mssql или oracle. Это заявление оператора — Conarium не угадывает диалект по запросу. Опечатка или mysql приводит к отклонению конфигурации.

Коннекторы закрыты по умолчанию (fail-closed). allowConnectors — это строгий список разрешённых: если он отсутствует или пуст, ни один коннектор не разрешён (раньше пустой список означал «разрешить все»). Если вы настраиваете коннекторы, вы должны перечислить их здесь — в противном случае сервер откажется запускаться и точно укажет, какое поле добавить. denyConnectors по-прежнему имеет приоритет над allowConnectors.

policy.detectors и policy.scanCharCap

Детекторы личности — TCKN, карта, IBAN, email — нельзя отключить. Конфигурация, которая пытается это сделать (detectors: { tckn: false }), отклоняется при загрузке. Это и есть продукт: маскирование, которое банк может отключить из JSON-файла, — это не маскирование.

Key

Default

Why

detectors.ip

false

IP-адрес сервера не всегда является персональными данными. Маска без возможности отключения ломает SOC («сколько запросов с этого адреса?»). Включайте, когда столбец действительно является адресом клиента.

detectors.mrz

true

MRZ паспорта — это идентичность и содержит контрольные цифры. Отключите в базовой политике, если вы не работаете с проездными документами.

scanCharCap

16384

Удобство использования. Поля длиннее этого заменяются целиком ([MASKED_PII]), никогда не пропускаются. Переменная окружения CONARIUM_SCAN_CHAR_CAP переопределяет. Поднимите её — стоимость сканирования растёт квадратично. Потолок 1 048 576.

{
  "scanCharCap": 32768,
  "detectors": { "ip": true }
}

policy.customPatterns

Форматы, которые не знают встроенные детекторы — номер клиента банка, код домашнего счёта — можно зарегистрировать как дополнительные правила на том же сканере. Это не второй путь маскирования и не заменяет maskColumns.

Каждое правило требует имя (что записывает квитанция), шаблон, необязательные glob-шаблоны столбцов и метку маски. Необязательный sample — это то, что conarium-doctor проверяет скомпилированным шаблоном — успешная компиляция не является гарантией. Сломанный или ReDoS-подобный шаблон отклоняет конфигурацию; шаблон и образец никогда не записываются в логи, квитанции или вывод doctor.

{
  "customPatterns": [
    {
      "name": "teb-hesap",
      "pattern": "HSP-[0-9]{8}",
      "columns": ["*.hesap_no"],
      "label": "[MASKED_HESAP]"
    }
  ]
}

Квантификаторы должны быть ограничены ({8}, {4,12}). +, *, вложенные группы и lookaround отклоняются при загрузке. Правило называет формат, который вы уже знаете; оно не изобретает новый.

conarium-suggest-policy --sql schema.sql выводит предположение maskColumns на основе имён столбцов (*name*, *address*, *tckn*, …). Он не записывает вашу конфигурацию. Первая строка вывода сообщает об этом.

🗺️ Дорожная карта

Conarium находится в раннем доступе — и честно говорит о том, что реально:

Сейчас доступно: управляемый MCP-шлюз (stdio + HTTP) · детерминированное маскирование PII, включая помеченные имена в свободном тексте · разрешение/запрет + ограничения строк · профили маскирования для каждого человека · журнал аудита с защитой от вмешательства и хеш-цепочкой · квитанция, подписанная Ed25519, для каждого доступа с офлайн-верификатором · подписанные декларации покрытия · двусторонняя сверка с собственными счётчиками базы данных · якорение OpenTimestamps и опциональная служба якорения · векторы соответствия · SQL-шлюз: Postgres, Microsoft SQL Server, Oracle (MySQL не реализован; синонимы Oracle и ссылки на базы данных не разрешаются — см. LIMITATIONS) · коннекторы Postgres, Supabase, docs, OpenAPI, Jira и Slack · conarium-init / conarium-doctor через npx (@conarium-ai/core).

Далее: привязка согласия (спецификация опубликована, кода нет — сначала патентная экспертиза) · вторая независимая реализация формата квитанций · привязка идентичности пользователя к поставщику удостоверений, а не к карте токенов оператора.

Сознательно не запланировано, чтобы никто этого не ждал:

  • LLM-основанное «семантическое» маскирование. Шлюз детерминирован намеренно. Вероятностная маска дала бы вероятностную квитанцию, а это не квитанция.

  • Облачная консоль. Мы заявляем о самостоятельном размещении; облачная консоль поместила бы нас в путь данных, в котором, как мы говорим, нас нет.

  • Никакого SOC 2 для нас. На данном этапе приоритет — независимое тестирование на проникновение и гарантии на уровне реализации, а не организационная сертификация. Это касается нашей сертификации, а не вашей: подписанные квитанции и декларации покрытия — ваши, чтобы показать вашему аудитору, и удовлетворяют ли они конкретному аудиту — это вопрос между вами и этим аудитором. Если мы когда-либо будем хранить ваши данные или если обязательство будет зависеть от самого сертификата, эта строка изменится первой.

Известные пробелы: LIMITATIONS.md, README выше, docs/RECEIPT-SPEC.md, docs/BENCHMARK.md и docs/API-STABILITY.md.

📜 Лицензия

MIT — всё, включая верификатор, инструменты сверки и службу якорения. Ни одна функция не удерживается для платного тарифа; код — MIT. Что conarium.dev продаёт — это второй подписант (Pro) и, позже, управляемое покрытие (Business — ещё не выпущено) — а не доступ к коду.

Available Tools

4 tools
describe_tableA

Get the columns of one table: name, type and description. Read-only, and it returns structure only — no row is read, so nothing here is masked. Use it to write a correct query; use list_tables first if the table name is not known. A table the policy denies returns an error rather than an empty result. Every call is written to the audit ledger, and to a signed receipt as well when a receipt sink is configured.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYesSchema-qualified table name
connectorNoConnector name (optional)

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description thoroughly discloses behavior: read-only, no row reads, no masking, error on denied tables, and audit logging. This fully compensates for lacking annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four concise sentences with high information density. Every sentence adds value: purpose, read-only assurance, usage tip, error behavior, and audit logging.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a read-only metadata tool. Covers purpose, usage order, error cases, audit trails, and privacy implications despite no annotations or output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameters are documented in the schema. The description mentions 'a table' and 'if the table name is not known', but adds no extra parameter-specific detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool describes columns of one table with name, type, and description. It differentiates from siblings like search, list_tables, and query by specifying its specific role in understanding table structure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use it to write a correct query' and 'use list_tables first if the table name is not known', providing clear guidance on when to use this tool vs. alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tablesA

List the database tables this gateway is allowed to expose. Read-only. Returns one entry per table with its connector, schema-qualified name and description; tables the policy denies are absent rather than marked, so this is the authoritative list of what any other tool here can reach. Call it before describe_table or query when the table names are not already known. Every call is written to the audit ledger, and to a signed receipt as well when a receipt sink is configured.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectorNoConnector name (optional, defaults to all)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states 'Read-only,' mentions audit logging ('Every call is written to the audit ledger'), and explains that 'tables the policy denies are absent rather than marked.' These are valuable side-effect and security behaviors beyond basic operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise (three sentences) and front-loaded with the core purpose. Each sentence adds value: purpose, usage guidance, return format, and behavioral notes. No fluff or redundancy, making it highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description explicitly explains the return format ('one entry per table with its connector, schema-qualified name and description') and the denial behavior. It covers usage and side effects adequately for a simple list operation, though it omits error handling or pagination details, which slightly reduces completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter 'connector' is fully described in the schema (100% coverage) as 'Connector name (optional, defaults to all).' The description adds no additional parameter meaning; it only mentions connector as part of the output structure. Since schema coverage is high, baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'List the database tables this gateway is allowed to expose.' It uses a specific verb (list) and resource (database tables), and explicitly distinguishes itself from siblings like describe_table and query by noting it provides the authoritative list of reachable tables. This is a model of purpose clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance: 'Call it before describe_table or query when the table names are not already known.' This tells the agent when to use it (before others when names unknown), but does not explicitly state when not to use it or mention alternative tools. It implies usage context but falls short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Run one read-only SELECT against the company database. Only SELECT is allowed; anything else is refused before it reaches the database. Rows come back capped by the policy (maxRows, often lower than any LIMIT you write) and protected values arrive already replaced with [MASKED_PII] or [MASKED_SECRET] — the raw values never leave the gateway, so do not plan on receiving them. A refusal is a normal outcome, not a fault. Use search instead when there is no SELECT yet and the goal is to find text. Every call is written to the audit ledger, and to a signed receipt as well when a receipt sink is configured.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesSQL SELECT query to execute
connectorNoConnector name (optional, defaults to first allowed)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses multiple behavioral traits: only SELECT allowed, row caps, masking of sensitive values, refusal as normal outcome, audit logging, and optional signed receipts. It also warns that raw protected values never reach the caller, which is critical for planning. This is exceptionally transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but every sentence adds value: purpose, restriction, behavior, alternative, and audit trail. It is front-loaded and well-organized. Slightly verbose but not wasteful, so a 4 is warranted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's purpose, constraints, safety features, and alternatives. Without an output schema, it doesn't specify the exact return format (e.g., column details or metadata), but it does clearly state rows come back capped and masked. Given the complexity (SQL execution with policies), it is fairly complete, though a bit more detail on response structure would be useful.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — both parameters have clear descriptions in the schema. The tool description adds minimal parameter-specific detail beyond what schema provides, but it does mention the connector defaults to first allowed, which is already in the schema. Given high coverage, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs a read-only SELECT query on the database, explicitly limits to SELECT, and distinguishes from sibling tools like search (used when there is no SELECT yet). It names the resource (company database) and the verb (run), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool vs alternatives: 'Use search instead when there is no SELECT yet and the goal is to find text.' It also clarifies that refusals are normal, setting expectations for failed invocations. This is explicit and actionable guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 4 tool updatesv0.2.23
    • First observeddescribe_table
    • First observedlist_tables
    • First observedquery
    • First observedsearch

TDQS

A4.6/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: list_tables for discovery, describe_table for schema, search for text lookup without SQL, and query for explicit SELECT statements. The description explicitly differentiates search vs query, eliminating ambiguity.

Naming Consistency5/5

All tool names follow a consistent lowercase snake_case pattern with imperative verbs: search, list_tables, describe_table, query. This is a uniform and predictable style.

Tool Count5/5

Four tools is well-scoped for a read-only database gateway: it covers table discovery, schema inspection, text search, and arbitrary SELECT queries without unnecessary bloat or gaps.

Completeness5/5

The surface is complete for its stated purpose: an agent can list tables, inspect schema, search for text, and execute read-only SQL. No dead ends or missing lifecycle operations are evident.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Privacy-preserving AI gateway. Sanitises PII before prompts reach Anthropic / OpenAI / your LLM, then emits a signed cryptographic certificate per call (Ed25519 + RFC 3161 + Sigstore Rekor). EU GDPR + AI Act ready. Free tier 500/mo with BYOK.
    1
    2
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Local zero-trust permission gateway for AI agents. Enforces policy-based tool authorization, human approvals, scoped permissions, and cryptographically verifiable audit logs.
    4
    5
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    A default-deny SQL firewall sidecar for AI agents that enforces per-agent policies on database queries, provides safe rewrites, and maintains a tamper-evident audit chain.
    AGPL 3.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dogrucanemek-alt/conarium'

If you have feedback or need assistance with the MCP directory API, please join our Discord server