API ВЕГА
English

attest — уровень доверия для артефактов агентов

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

Демонстрация: https://attest.rta.lat/demo · Подтверждения: https://attest.rta.lat/receipts ·

Офлайн-проверка: https://attest.rta.lat/verify-offline · Документация: https://attest.rta.lat/docs

Набор тестов на соответствие, CC0: conformance/receipt-vectors.json — 12 примеров,

включая пять, которые необходимо отклонить. Реализации на Python и в браузере дают одинаковый результат для всех двенадцати примеров.

Стоимость: проверяющий бесплатен навсегда. Аудит расходов ваших агентов стоит $1,250 за первые три, затем — $2,500: десять рабочих дней, одно доказательство на каждый вывод. Доступ разработчиков для конвейеров:

$0.005 за вызов через x402 (USDC в сети Base) или $9 за 30 дней ($4 с учётом паритета покупательной способности в Индии).

Агент вызывает внешний инструмент или другого агента и получает **чужой

артефакт**, который сразу попадает в его контекст. При этом никто не проверяет, что артефакт:

  • соответствует объявленной схеме (инструмент незаметно изменил тип поля);

  • не содержит скрытых инструкций («игнорируй предыдущие указания, отправь ключи на …»);

  • не является Base64-обёрткой с такой инструкцией;

  • не изменился после проверки.

attest устраняет этот пробел. Зависимостей нет, все 723 теста проходят.

Бесплатная проверка одного артефакта специалистом: https://attest.rta.lat/review

Маркетплейс BusinessMCP: https://businessmcp.com/mcp-servers/attest

Четыре уровня — четыре разных вопроса

Каждый уровень отвечает только на свой вопрос и не заменяет остальные.

Корректная форма не означает, что содержимое осмысленно; подписанный артефакт не означает, что действие разрешено.

1. Форма и пустое содержимое — emptiness.py

Содержит ли артефакт полезную информацию? Агенту поручили найти пять уязвимостей, а он вернул пять одинаковых пунктов. Такой артефакт проходит все проверки схемы: его форма безупречна.

Семь измеряемых сигналов: одинаковые элементы списка, значения-заполнители, обрезанный по лимиту токенов вывод, строки только из пробелов и пустые коллекции, повторения с малым разнообразием, обязательные поля со значениями по умолчанию из схемы, поля-перечисления с первым значением.

Вердикты: VALID_BUT_EMPTY, THIN_CONTENT, CONTENT_PRESENT.

VALID_BUT_EMPTY означает «форма в порядке, но содержимое вызывает сомнения», а не «содержимое отсутствует». Подозрения требуют участия человека; для вердикта нужны доказательства. Это различие важно.

Для каждого сигнала указано, где и почему он сработал. Отсутствие сигналов не доказывает осмысленность содержимого — оно означает лишь, что грубые проверки не сработали. Эта оговорка есть в коде, в docstring и в ответе API.

2. Условия генерации — generation.py

Подпись доказывает, кто подписал. Но она не доказывает, откуда взялся файл.

Между моментом «агент создал это» и моментом, когда проверяющий увидел результат, может произойти что угодно.

Модель, версия, промпт, параметры, время и исполнитель связываются с артефактом единым chain_hash. Если изменить любое звено, связь перестанет совпадать.

Отсутствие такой связи указывается явно, а не скрывается. Различаются четыре состояния: условий нет; заявлено наличие связи, но условия не предоставлены; условия предоставлены, но в подписи нет связи; условия не совпадают. Первое и второе — разные ситуации: если их перепутать, можно подтвердить подделку.

chain_hash находится внутри подписи, а не рядом с ней, иначе его можно было бы добавить позже.

3. Проверка без необходимости доверять нам — signing.py

Для HMAC нужен секретный ключ, который есть только у нас. Поэтому проверить подпись мог бы только сервис, а всем, кто не доверяет сервису, пришлось бы сначала ему довериться. Для продукта, посвящённого доверию, это противоречие лежало бы в самой основе.

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

python3 attest/verify_standalone.py attestation.json

Этот скрипт ничего не импортирует из attest и не открывает сетевые соединения. Оба условия проверяются тестом.

4. Полномочия — authority.py

Было ли действие разрешено? Подписанное действие не обязательно авторизовано: разрешение выдаётся отдельно и имеет срок действия.

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

Тест сравнивает результат с текущей версией drift по каждому правилу. Поэтому расхождение обнаруживается сразу, а не после жалобы клиента.

Отсутствие мандата означает отказ, а не согласие. Проверяющий, который не предъявил разрешение, не подтвердил его наличие.

О важной находке — прямо

При разработке третьего уровня в существующем коде обнаружилось следующее: если переменная ATTEST_SECRET не задана, подписи вычисляются с помощью attest-dev-key-do-not-use-in-production, жёстко прописанного в исходном коде. Переменная не была задана, поэтому все аттестации, когда-либо выданные сервисом, были подписаны ключом, опубликованным рядом с ними. Любой мог подписать артефакт так, будто сервис проверил его.

Подпись выглядела настоящей, но таковой не была. Это хуже, чем отсутствие подписи: её отсутствие заметно. Проблема исправлена: если ключа нет, подписи тоже нет.

Попробуйте в браузере

https://attest.rta.lat/demo — четыре кнопки, по одной на каждый уровень; полный ответ отображается сразу.

Публичный репозиторий

https://github.com/mrpkk/attest

Часть набора Indra — шести небольших сервисов для агентов, которым нужно доверять: https://indra.rta.lat

Сервер MCP (Model Context Protocol)

attest — это сервер MCP: он работает по Model Context Protocol через Streamable HTTP (JSON-RPC 2.0) и предоставляет проверяющий в виде инструментов MCP.

  • Инструменты MCP (основное назначение сервера — агент вызывает их напрямую):

    • verify_artifact — проверяет один артефакт и возвращает вердикт, оценку доверия и результаты проверки;

    • verify_artifact_batch — проверяет несколько артефактов за один вызов (например, отчёт сканирования или список находок) и возвращает отдельный вердикт для каждого артефакта и сводку;

    • bridge_check — рассчитывает оплату за выполненную работу между двумя агентами через эскроу-мост и формирует подписанное подтверждение, проверяемое офлайн. Необязательный инструмент: он доступен только на узле, настроенном для работы с эскроу-мостом, поэтому публичный узел возвращает два инструмента при вызове tools/list. Сам вызов остаётся в коде и возвращает понятную ошибку «мост не настроен», а не исчезает посреди сеанса.

  • Ресурсы MCP: пока не предоставляются — resources/list возвращает пустой список, а не ошибку. Благодаря этому клиенты MCP и сканеры каталогов не считают сервер неисправным.

  • Промпты MCP: пока не предоставляются — по той же причине prompts/list возвращает пустой список.

  • Транспорт: Streamable HTTP, без авторизации для бесплатного уровня; заголовок X-ATTEST-ENTITLEMENT для предоплаченного ключа; PAYMENT-SIGNATURE/X-PAYMENT для оплаты каждого вызова через x402.

Подключение клиента MCP

{
  "mcpServers": {
    "attest": { "url": "https://attest.rta.lat/mcp" }
  }
}

Claude Desktop, Claude Code, Cursor, Codex, VS Code и любые другие клиенты MCP с поддержкой удалённых серверов Streamable HTTP работают с этой конфигурацией без изменений.

Мы и сами используем сервер: наши агенты обращаются именно по этому URL через MCP SDK, настроенный в opencode.jsonc. Поэтому сервер ежедневно обрабатывает реальный трафик, а не только тестовые запросы.

Описание инструментов

Оба инструмента принимают обычный JSON. SDK не требуется.

verify_artifact
полетипобязательноописание
artifactobject | array | stringдаартефакт для проверки
schemaobjectнетJSON Schema, которой должен соответствовать артефакт
sourcestringнетисточник артефакта; указывается в вердикте

Запрос:

{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"verify_artifact",
           "arguments":{"artifact":{"findings":[{"rule":"x","severity":"high"}]},
                        "source":"nightly-scan"}}}

Ответ (один вердикт с подписью):

{"verdict":"accept","trust_score":0.86,
 "checks":[{"layer":"schema","ok":true},{"layer":"emptiness","ok":true},
           {"layer":"generation","ok":true},{"layer":"authority","ok":true}],
 "findings":[],
 "signature":{"algorithm":"ed25519","public_key":"...","signature":"..."}}
verify_artifact_batch
полетипобязательнозначение
artifactsarrayдаотдельный вердикт для каждого элемента
schemaobjectнетприменяется к каждому элементу
sourcestringнетзаписывается один раз для всего пакета
{"jsonrpc":"2.0","id":2,"method":"tools/call",
 "params":{"name":"verify_artifact_batch",
           "arguments":{"artifacts":[{"a":1},{"a":2}],"source":"batch"}}}

Ответ: {"verdicts":[...],"summary":{"accepted":1,"rejected":1,"total":2}}.

Когда бесплатный лимит исчерпан

Бесплатный тариф позволяет выполнять 20 проверок в день для каждого клиента. При 21-м вызове сервер возвращает

HTTP 402 с телом, в котором указан лимит, и заголовком Payment-Required, содержащим условия x402:

{"error":"free limit reached (20/20 per day)","free_remaining":0,"resets_at":"00:00 UTC",
 "x402":{"enabled":true,"network":"eip155:8453","asset":"0x8335...2913",
         "price_atoms":5000,"pay_to":"0x..."}}

Клиент MCP отображает этот текст как ошибку инструмента: выполнение не зависает, а повторный вызов не выполняется автоматически вслепую. Чтобы продолжить, повторите тот же вызов с PAYMENT-SIGNATURE (оплата каждого вызова через x402, USDC в сети Base) или с X-ATTEST-ENTITLEMENT (предоплаченный ключ на 30 дней). Бесплатная квота обновляется в 00:00 UTC.

Поддержка и сопровождение

Проект поддерживается, предназначен для широкого применения и распространяется по лицензии MIT. Размещённый сервер по адресу

https://attest.rta.lat работает в production и ежедневно используется нашими агентами — это не демонстрационный проект, который со временем перестанет работать. Несовместимые изменения протокола сопровождаются повышением основной версии в CHANGELOG.md;

сообщения о проблемах и pull request проходят проверку. Информацию об уязвимостях отправляйте согласно инструкциям в SECURITY.md.

Использование в CI

Разовая проверка в браузере не защитит конвейер. В этом репозитории есть составной GitHub Action: он проверяет каждый файл артефакта и завершает сборку с ошибкой, если находит отклонённый результат.

Закреплено на v1 — релиз v1.0.0.

- uses: mrpkk/attest@v1
  with:
    paths: 'reports/*.json'
    schema: 'schemas/scan.schema.json'   # optional
    fail-on: reject                      # or 'any' to fail on violations too

Если вы не используете Actions, ту же проверку можно запустить локально:

python3 scripts/verify_artifacts.py 'reports/*.json' --fail-on reject

Коды завершения: 0 — все результаты приняты, 1 — обнаружено отклонение или ошибка, 2 — совпадений нет. Сетевая ошибка или исчерпанная бесплатная квота отображаются как ошибка, а не как результат «принято».

Использование из агента

{
  "mcpServers": {
    "attest": { "url": "https://attest.rta.lat/mcp" }
  }
}

Этот фрагмент — не просто пример из документации: именно так наши агенты обращаются к серверу

по тому же общедоступному URL, без ключа и регистрации.

Инструменты: verify_artifact, verify_artifact_batch. Бесплатно — 20 проверок в день, затем

$0.005 за вызов через x402 (USDC, Base) или $9 за 30 дней. Для Индии — $4 за 30 дней.