
scopeblind-gateway v0.13.1
Подписанные Ed25519 квитанции + политики Cedar для ИИ-агентов. Финансовый мандатный шлюз (Legate), пакеты доказательств, 3 IETF Internet-Drafts. npx protect-mcp
protect-mcp
Шлюз политик Cedar с отказом по умолчанию плюс подписанные квитанции для вызовов инструментов ИИ-агента.
protect-mcp — это шлюз, который стоит перед вызовами инструментов ИИ-агента. Он проверяет
каждый вызов на соответствие политике Cedar (тот же язык,
который AWS использует для IAM), блокирует то, что нарушает правила, до запуска и подписывает
проверяемую офлайн квитанцию Ed25519 о каждом решении. Он работает локально, никуда не отправляет
телеметрию о ваших решениях и распространяется под лицензией MIT.
Чем он отличается
- Отказ по умолчанию. При любой ошибке политики, отсутствии движка или
сбое оценки решение — DENY. Шлюз никогда не разрешает молча. Существует
режим наблюдения для теневого развёртывания, но даже там вызов, который был бы
заблокирован, помечается
would_deny: true, так что сбой никогда не остаётся незамеченным. - Он доказывает собственную сдержанность.
serve --enforceиdoctorзапускают при старте самотестирование и отказываются взводить шлюз, если не могут показать, что известное запрещённое действие действительно отклоняется. Шлюз, который не может доказать, что отклоняет, не запускается. - Каждое решение — это квитанция, которую может проверить любой. Решения подписаны Ed25519
и проверяются офлайн с помощью
@veritasacta/verify. Доверие к поставщику не требуется: математике всё равно, кто её запускает.
Быстрый старт: от установки до первого полезного доказательства```bash
1. Generate an Ed25519 keypair, config template, and sample policy.
npx protect-mcp init
2. Wrap any MCP server in shadow mode. Nothing is blocked yet; calls are logged.
npx protect-mcp wrap -- node your-mcp-server.js
3. Inspect the local-only dashboard: tool inventory, risk, approvals, receipts.
npx protect-mcp dashboard --open
4. Draft a reviewable policy from observed calls.
npx protect-mcp recommend --write
5. When reviewed, restart the wrapper in enforce mode with that policy.
npx protect-mcp --policy protect-mcp.recommended.json --enforce -- node your-mcp-server.js
Для Claude Desktop сначала выполните пробный патч конфигурации, затем примените его:```bash
npx protect-mcp wrap --claude-desktop
npx protect-mcp wrap --claude-desktop --write
npx protect-mcp dashboard --open
Панель управления привязывается к 127.0.0.1, читает только локальные файлы журналов и квитанций и ничего не загружает. Используйте npx protect-mcp connect, только если вам явно нужна размещённая панель ScopeBlind.
Шлюз как MCP-сервер
Если вы предпочитаете вызывать шлюз как инструменты, а не подключать хуки Claude Code, запустите его как MCP-сервер:```bash npx protect-mcp mcp
Он взаимодействует по MCP через stdio и предоставляет четыре инструмента только для чтения, весь цикл:
- **`evaluate_action`**: принимает решение о предлагаемом вызове инструмента на основе встроенной политики Cedar, с отказом при сбое (любая ошибка политики — DENY). Возвращает `{ allowed, decision, reason, policy_digest }`.
- **`sign_decision`**: превращает решение в подписанную квитанцию Ed25519 (отказ подписывает `gateway_restraint`, разрешение — `decision_receipt`). Возвращает квитанцию и её открытый ключ; генерирует эфемерный ключ, если вы его не предоставили.
- **`verify_receipt`**: проверяет подписанную квитанцию офлайн с помощью открытого ключа. Возвращает `{ valid, error, type, kid, issuer }`.
- **`self_test`**: доказывает это, без входных данных. Известное запрещённое действие отклоняется, затем подписанная квитанция проходит полный цикл, а подделанная копия не проходит.
Направьте на него любой MCP-хост, например Claude Desktop:```json
{
"mcpServers": {
"protect-mcp": { "command": "npx", "args": ["-y", "protect-mcp", "mcp"] }
}
}
Чеки байт-совместимы с теми, которые шлюз подписывает во время выполнения, поэтому
чек, созданный здесь, проверяется с помощью @veritasacta/verify
и браузерного верификатора точно так же.
Локальная панель действий
protect-mcp dashboard — это представление оператора для перехода от видимости к
принудительному применению:
- Инвентаризация инструментов: каждый наблюдаемый инструмент, количество вызовов, высокий/средний/низкий риск, и имеет ли активная политика точное правило, подстановку по шаблону или не имеет правила.
- Покрытие политики: локальное редактирование политики в один клик для
Require approval,BlockилиObserve. Перезапустите обёртку после проверки изменений. - Очередь одобрения точных действий: точный инструмент, действие, назначение, отредактированный предпросмотр полезной нагрузки, хеш полезной нагрузки, основание политики и фиксация причины до того, как человек одобрит, отклонит, отредактирует или возьмёт на себя управление.
- Цепочка чеков: идентификаторы запросов, сопоставленные с хешами подписанных чеков, чтобы аудитор мог видеть, какие решения имеют криптографическое подтверждение.
- Экспорт аудита: загружает офлайн-проверяемый пакет аудита, когда подписанные чеки существуют. Если существуют только неподписанные локальные журналы, панель объясняет, что сначала необходимо включить подписывание.
Для одобрений через резервный вариант на живом рабочем столе запустите панель с локальной конечной точкой одобрения шлюза
и nonce, выведенным обёрткой:```bash
npx protect-mcp dashboard --open
--approval-endpoint http://127.0.0.1:9876
--approval-nonce "$PROTECT_MCP_APPROVAL_NONCE"
`Approve` перенаправляет на живой локальный шлюз, когда эти флаги присутствуют.
`Deny`, `Edit` и `Take over` записываются локально как записи разрешения
одобрения; используйте их как инструкцию оператора и перезапустите инструмент при необходимости.
### Платная граница MVP: привязка дайджеста, а не загрузка данных
Локальные самоподписанные квитанции остаются бесплатными и проверяемыми офлайн. Платная граница —
это независимое доказательство того, что ScopeBlind видел дайджест квитанции в определённое время, под идентичностью организации,
не получая необработанный промпт, полезную нагрузку инструмента, вывод, приватный ключ или
необработанную квитанцию.```bash
# Create or refresh a local org identity and public-key directory.
npx protect-mcp registry init --org "Meridian Global Macro" --billing-account acct_meridian
# Local preview: writes a digest registry and shareable static verifier page.
npx protect-mcp registry anchor
# Hosted mode: uploads receipt digests only for independent anchoring.
SCOPEBLIND_TOKEN=... npx protect-mcp registry anchor \
--hosted \
--endpoint https://api.scopeblind.com \
--verifier-base https://legate.scopeblind.com
Локальный предпросмотр намеренно помечен как local-preview-not-independent.
Размещённый режим фиксирует только хеши квитанций, идентификаторы запросов, публичные ключи организации и
метаданные биллинга. Он не загружает необработанные квитанции или конфиденциальный контекст.
Killer Demo: от тени к политике к доказательству
protect-mcp killer-demo создаёт полный трёхминутный пакет для продаж/демонстрации:```bash
npx protect-mcp killer-demo --dir ./scopeblind-demo
Он создаёт макет файловой системы, GitHub, электронной почты и активности PMS; показывает рискованные вызовы в
теневом режиме; применяет пакет политик; требует одобрения для чувствительного бронирования PMS;
выполняет через шлюз; записывает подписанную квитанцию; доказывает, что оригинальная
квитанция верифицируется; доказывает, что подделанная квитанция не проходит проверку; и создаёт пакет выборочного
раскрытия, который скрывает чувствительный контекст, показывая минимальное доказательство.
Сначала откройте сгенерированный `DEMO-RUNBOOK.md`. Затем выполните напечатанную команду
панели управления, чтобы провести клиента через точную последовательность.
### Selective Disclosure v0
Квитанции в режиме commitment могут содержать `committed_fields_root` вместо раскрытия
каждого поля в открытом виде. Позже держатель может раскрыть только выбранные поля:```bash
npx protect-mcp verify-disclosure \
--receipt ./receipts/selective-disclosure.receipt.json \
--disclosure ./receipts/selective-disclosure.tool-only.json
Верификатор проверяет хеш родительской квитанции, подпись Ed25519, корень обязательств и доказательство Меркла для каждого раскрытого поля. Затем он объясняет, какие поля были раскрыты, а какие зафиксированные поля остаются скрытыми. Это раскрытие обязательств с солью, а не полное доказательство с нулевым разглашением, но оно делает заявление о приватности конкретным: аудиторы могут проверить выбранные факты, не получая полную полезную нагрузку инструмента или конфиденциальный контекст рабочего места.
Доказать утверждение о записи (аттестации, не зависящие от позиции)
Вы можете доказать УТВЕРЖДЕНИЕ о своей записи, не раскрывая её. Создайте подписанную, не зависящую от позиции аттестацию по всей записи, которая раскрывает только категории по каждому решению (дайджест квитанции, вердикт, теги возможностей), но никогда ваши входные данные инструмента, выходные данные или данные:```bash
"No action reached the network across the record":
npx protect-mcp claim --no net.egress
other predicates:
--only fs.read,fs.write all actions were confined to these capabilities
--no-verdict blocked no action was blocked
--count blocked how many were blocked
Любой может проверить это офлайн, видя только категории, но никогда — содержимое:```bash
npx protect-mcp verify-claim claim-<id>.json
Верификатор пересчитывает корень Меркла по раскрытому набору и независимо пересчитывает предикат, поэтому эмитент не может солгать о заявлении при данном раскрытии. Добавьте --anchor, чтобы записать дайджест заявления в публичный, доступный только для добавления журнал прозрачности ScopeBlind, чтобы контрагент, который вам не доверяет, мог подтвердить, что раскрытый набор полон и не был тихо пересобран (отправляется только хеш; запись остаётся локальной):```bash
npx protect-mcp claim --no net.egress --anchor
Это подотчётная аттестация, не зависящая от позиции, а не полное доказательство с нулевым разглашением: она раскрывает форму, но не содержимое.
## Попробуйте за 60 секунд (агент не требуется)
[](https://legate.scopeblind.com/record)
Посмотрите двухминутный фильм на [legate.scopeblind.com/record](https://legate.scopeblind.com/record), затем воспроизведите его на своей собственной копии:```bash
npx protect-mcp sample # seed a labeled sample record (8 decisions: 1 blocked, 2 payments)
npx protect-mcp record # open it: signatures verified in your browser
npx protect-mcp claim --payment-under 100 --anchor --output payments-under-100.json
npx protect-mcp verify-claim payments-under-100.json
npx protect-mcp anchor-record
Поместите сгенерированный demo-tampered.jsonl на страницу записи, чтобы увидеть, как будет обнаружено изменение, внесённое после подписания. sample отказывается трогать существующую запись, поэтому запускайте его в пустой папке. Когда вы будете готовы к реальному делу, подключите шлюз ниже, и те же команды будут выполняться для собственной записи вашего агента.
Быстрый старт с хуком Claude Code```bash
Generate hook config and a sample Cedar policy.
npx protect-mcp init-hooks
Serve the Claude Code hook gate in enforce mode. It runs a restraint self-test
first and refuses to start if it cannot prove it denies a forbidden vector.
npx protect-mcp serve --enforce --cedar ./cedar
Одноразовая оценка, так, как её вызывает хук PreToolUse. Код выхода 2 означает запрет
(инструмент заблокирован); код выхода 0 означает разрешение:```bash
npx protect-mcp evaluate --cedar ./cedar --tool Bash --input '{"command":"rm"}'
echo $? # 2 -> denied, fail-closed
npx protect-mcp evaluate --cedar ./cedar --tool Read --input '{"path":"README.md"}'
echo $? # 0 -> allowed
Отсутствующая или незагружаемая политика отклоняет (exit 2), если вы явно не передадите
--fail-on-missing-policy false.
Хуки Claude Code
protect-mcp init-hooks создаёт для вас .claude/settings.json. Чтобы подключить
шлюз вручную, нужны две команды: evaluate (PreToolUse, блокирует при exit 2)
и sign (PostToolUse, записывает квитанцию). Закрепите версию, чтобы сессия Claude Code
всегда запускала протестированный вами шлюз:```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "npx [email protected] evaluate --cedar ./cedar --tool "$TOOL_NAME" --input "$TOOL_INPUT""
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "npx [email protected] sign --tool "$TOOL_NAME" --receipts ./receipts --key ./keys/gateway.json"
}
]
}
]
}
}
### Подпишите само решение политики
Начиная с версии 0.13.0, `sign` может вычислить политику и записать фактическое решение в
квитанцию вместо безусловного разрешения. Передайте каталог политики и
те же входные данные и контекст, которые хук передал бы в `evaluate`:```bash
npx [email protected] sign --cedar ./cedar --tool Bash \
--input '{"command":"rm -rf /"}' --context '{"command_pattern":"rm -rf"}' \
--receipts ./receipts --key ./keys/gateway.json
Затем полезная нагрузка квитанции содержит decision (allow или deny), reason
(cedar_allow или cedar_deny) и policy_digest (дайджест acta-policy-digest-v1
набора политик), и ссылается на draft-farley-acta-signed-receipts-03. Команда
выводит решение и дайджест в stdout. Отказ также подписывается: квитанция — это
запись о решении, а не разрешение продолжить.
Поддерживаются две модели действий Cedar. Runtime-шлюз вычисляет
Action::"MCP::Tool::call" с инструментом в качестве ресурса, что ожидают
политики в cedar/ и что sign --cedar использует по умолчанию. Политики,
которые называют инструмент действием (action == Action::"Bash"), например
опубликованная политика соответствия в agent-governance-testvectors, требуют
--action-model tool. evaluate принимает тот же флаг.
evaluate завершается с кодом 2 при отказе, чтобы Claude Code заблокировал вызов
инструмента, и с кодом 0 при разрешении. sign работает по мере возможности: он
добавляет квитанцию, подписанную Ed25519, когда ключ настроен, а если подписывающий
недоступен, он записывает честную неподписанную строку ("signed": false), а не
завершает работу инструмента с ошибкой.
Использование в других агентах (Codex, Cursor, Gemini, Hermes)
Тот же шлюз с отказом по умолчанию работает как хук инструмента в любом агенте,
который их поддерживает. Добавьте --format <host>, чтобы команда читала полезную
нагрузку хука этого хоста из stdin и отказывала в соответствии с его контрактом:```bash
the PreToolUse / before-tool command for each host
npx -y protect-mcp@latest evaluate --format codex --cedar ./cedar # OpenAI Codex npx -y protect-mcp@latest evaluate --format gemini --cedar ./cedar # Gemini CLI BeforeTool npx -y protect-mcp@latest evaluate --format cursor --cedar ./cedar # Cursor beforeShellExecution npx -y protect-mcp@latest evaluate --format hermes --cedar ./cedar # Hermes pre_tool_call
Сопоставьте каждый с `sign --format <host>` на событии post-tool для получения подтверждений. Важный случай — **Hermes**, который игнорирует коды выхода хуков и читает вердикт из stdout, поэтому `--format hermes` запрещает через `{"decision":"block"}`, а не через exit 2 (сырой exit-2 в этом случае молча завершился бы с разрешением). Без `--format` команды читают флаги `--tool`/`--input` точно так же, как в разделе про Claude Code выше.
## Написание политики
Политики Cedar хранятся в каталоге, на который вы указываете с помощью `--cedar`. Правило `forbid` запрещает, правило `permit` разрешает. Для сопоставления со значением во входных данных инструмента используйте идиому `.contains()`:```cedar
// Allow read-only tools.
permit(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"Read"
);
// Deny dangerous shell commands by matching the command against a list.
forbid(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"Bash"
) when {
["rm", "dd", "mkfs"].contains(context.command)
};
// Block destructive tools outright.
forbid(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"delete_file"
);
Опасность: НЕ пишите
context.command in ["rm", "dd"]для сопоставления строки со списком.inпредназначен для иерархий сущностей, а не для проверки принадлежности строки. Cedar воспринимает это выражение как ошибку типа и молча отбрасывает всё правилоforbid, что (при fail-open шлюзе) оставляет действующим остаточныйpermit. Это именно тот дефект, который лежит в основе приведённого ниже advisory. Используйте[...].contains(context.command)вместо этого. Начиная с 0.7.0 шлюз отклоняет при такой ошибке, а не разрешает, и тест-ловушка в CI проваливает сборку, если этот паттерн будет повторно внесён в поставляемую политику. См. GHSA-hm46-7j72-rpv9.
Стартовые наборы политик
Большинству команд не следует писать Cedar с нуля в первый же день. Установите стартовый набор, запустите в теневом режиме, изучите квитанции, затем ужесточите или включите принудительное применение:```bash npx protect-mcp policy-packs list npx protect-mcp policy-packs show secrets-safe npx protect-mcp policy-packs install filesystem-safe --dir ./cedar npx protect-mcp policy-packs install all --dir ./cedar npx protect-mcp serve --cedar ./cedar
Встроенные пакеты:
- `filesystem-safe`: деструктивные действия с файлами и чтение путей, похожих на секреты.
- `git-safe`: принудительные push, жёсткие сбросы, деструктивная очистка, удаление репозитория.
- `email-safe`: разрешает черновики, блокирует отправку без участия человека.
- `database-safe`: режим БД с ориентацией на чтение, блокировка SQL-запросов на запись и администрирование.
- `cloud-spend-safe`: очевидное создание облачных расходов и уничтожение инфраструктуры.
- `secrets-safe`: типичная эксфильтрация секретов из файлов, окружения, shell и облака.
- `finance-mandate-safe`: нарушения ограничительных списков и концентрации в потоках бронирования.
## Проверка квитанции
Квитанции подписаны и могут быть проверены офлайн любым обладателем открытого ключа. Без
сети, без вендора, без доверия к ScopeBlind:```bash
npx @veritasacta/verify ./receipts/receipts.jsonl --format jsonl
# Exit 0 = valid, non-zero = tampered or malformed
npx protect-mcp bundle --output audit.json экспортирует самодостаточный,
проверяемый офлайн аудиторский пакет ваших квитанций вместе с публичным ключом подписи.
Безопасность
protect-mcp 0.7.0 по своей архитектуре отказывает при сбое. При любой ошибке
вычисления политики, отсутствии движка или политике, завершившейся с ошибкой при
вычислении, решение — DENY, а не allow. serve --enforce и doctor запускают
самопроверку при загрузке, которая доказывает, что шлюз отклоняет известный
запрещённый вектор, прежде чем ему можно доверять, и отказываются вооружаться,
если это невозможно.
Затронутые версии: 0.5.x и 0.6.x. Эти ветки отказывают открыто (они возвращают
ALLOW при ошибке вычисления) и не вычисляют Cedar корректно относительно
закреплённого движка, поэтому правило forbid может не сработать. **Обновитесь до
= 0.7.0.**
Подробности и устранение: GHSA-hm46-7j72-rpv9. Чтобы сообщить об уязвимости, см. SECURITY.md.
Команды
| Команда | Описание |
|---|---|
serve | Запускает HTTP-сервер хуков для Claude Code (порт 9377). --enforce сначала запускает самопроверку сдержанности; --cedar <dir> и --policy <path> выбирают политику. |
init | Генерирует пару ключей Ed25519 (keys/gateway.json), шаблон конфигурации и пример политики. |
sample | Создаёт явно помеченную примерную запись (8 решений: один заблокированный вызов, два платежа; kid sample-demo) плюс подделанную копию, чтобы record, claim, verify-claim и anchor-record можно было воспроизвести с нуля до подключения агента. Отказывается трогать существующую запись; --force переопределяет. |
policy | Просмотр и изменение политики Cedar из терминала: policy list (permit / forbid / default-deny по инструментам, с указанием, как часто шлюз разрешал или запрещал его), policy show, policy allow <tool>, policy deny <tool>, policy path. Запущенный serve выполняет горячую перезагрузку при изменении. |
wrap | Выводит защищённую команду MCP или патчит MCP-серверы Claude Desktop. По умолчанию пробный запуск; используйте --write для обновления конфигурации Claude Desktop. |
dashboard | Запускает локальную панель на 127.0.0.1, показывающую инвентарь инструментов, риск, покрытие политикой, одобрения точных действий, цепочки квитанций и экспорт аудита. |
recommend | Составляет проверяемую JSON-политику на основе наблюдаемых локальных вызовов. По умолчанию пробный запуск; используйте --write для создания protect-mcp.recommended.json. |
registry | Создаёт идентичность организации, привязывает дайджесты квитанций и записывает статическую страницу верификатора. Размещённый режим загружает только дайджесты. |
record | Открывает локальный, доступный для поиска просмотрщик ваших квитанций (--live транслирует по мере работы агента): подписи Ed25519 проверяются в вашем браузере с использованием вашего ключа шлюза, теги возможностей, дерево происхождения и подписанный экспорт в один клик. Всё локально, ничего не загружается. |
claim | Создаёт подписанное, не зависящее от позиции удостоверение предиката над записью (--no <cap> вкл. --no payment, --only <c1,c2>, --no-verdict <verdict>, --count <verdict>, --payment-under <cap>), раскрывая только категории решений. Добавьте --anchor, чтобы записать дайджест утверждения в публичный журнал прозрачности; зарегистрированные ключи привязываются как именованная организация. |
anchor-record | Сохраняет контрольную точку корня Меркла записи + количество + временной диапазон в публичный журнал (удобно для heartbeat: пропускается, если не изменилось). Более позднее утверждение, чьё обязательство совпадает с привязанной контрольной точкой, доказуемо относится ко всей записи на момент этой контрольной точки. |
verify-claim | Проверяет пакет утверждения офлайн: подпись, пересчитанный корень Меркла, независимо пересчитанный предикат и боковой файл привязки, если он присутствует (связывает привязанный конверт с этим конкретным утверждением, затем подтверждает, что публичный журнал его содержит). --check-anchor требует привязку; --offline пропускает обращение к журналу. |
killer-demo | Генерирует полный демонстрационный пакет от теневого режима до политики, одобрения и подписанной квитанции. |
verify-disclosure | Проверяет пакет scopeblind.selective_disclosure.v0 и объясняет раскрытые и скрытые поля. |
policy-packs | Перечисляет, изучает и устанавливает стартовые пакеты политик Cedar. |
evaluate | Вычисляет один вызов инструмента относительно политики Cedar (шлюз PreToolUse). Код выхода 2 = запрет (отказ при сбое), код выхода 0 = разрешение. |
sign | Подписывает один вызов инструмента в квитанцию (PostToolUse). По мере возможности: записывает честную неподписанную строку, если нет ключа. |
simulate | Пробный запуск политики относительно записанного журнала решений, чтобы увидеть, что она заблокировала бы. |
demo | Запускает встроенный демонстрационный сервер, обёрнутый шлюзом, чтобы мгновенно увидеть квитанции. |
doctor | Проверяет вашу настройку (ключи, политики, движок Cedar, верификатор) и запускает самопроверку сдержанности. |
bundle | Экспортирует проверяемый офлайн аудиторский пакет квитанций вместе с публичным ключом. |
report | Генерирует отчёт о соответствии (Markdown или JSON) из журнала решений и квитанций. |
Запустите npx protect-mcp --help для полного справочника флагов.
Ссылки
- Протокол (IETF): draft-farley-acta-signed-receipts
- CHANGELOG
- npm
- scopeblind.com
Лицензия MIT. Создано ScopeBlind.