keywarden
keywarden
Ваш ИИ-агент может использовать ваши API-ключи. Но никогда не сможет их прочитать.
keywarden — это локальное зашифрованное хранилище учётных данных, которое говорит на MCP. Claude Code, Claude Desktop, Cursor или любой MCP-клиент подключается к нему и получает две возможности: совершать аутентифицированный API-вызов и запускать команду с учётными данными в своём окружении. Ни одна из них никогда не помещает сами учётные данные в контекст модели.
Инструмента get_secret не существует. Это отсутствие и есть весь продукт.
agent keywarden upstream
| | |
| "POST /v1/chat | |
| using openai/prod"| |
|-------------------->| |
| | check policy |
| | decrypt key |
| | attach Authorization |
| |------------------------->|
| |<-------------------------|
| response only | scrub any key from body |
|<--------------------| append to audit log |Зачем
Сейчас обычный способ дать агенту использовать ваш OpenAI-ключ — положить ключ в файл .env и позволить агенту прочитать его. Как только он это делает, ключ оказывается в контекстном окне модели. Оттуда он попадает в логи провайдера, возможно, в обучающий набор, возможно, в отчёт о сбое, и уж точно — в вашу собственную историю транскриптов, которую вы вставите в отчёт об ошибке через полгода.
Ротация ключа — это неприятно. Не знать, утёк ли он, — ещё хуже.
keywarden убирает тот шаг, на котором модель вообще видит ключ.
Related MCP server: AgentPay MCP Server
Установка
npm install -g keywardenNode 20.10 или новее. Две зависимости времени выполнения: MCP SDK и zod. Никаких нативных модулей, компилятора и демона.
Быстрый старт
keywarden init --passphrase
keywarden add openai/prod --provider openai
keywarden mcp-configinit создаёт ~/.keywarden/ с зашифрованным хранилищем и политикой «запрещено по умолчанию». add запрашивает каждое поле, поэтому ничего не попадает в историю вашей оболочки. mcp-config выводит блок для вставки в ваш MCP-клиент.
Затем в Claude Code:
Вызови endpoint моделей OpenAI с моим прод-ключом и скажи, к каким из них у меня есть доступ.
Модель вызывает http_request с ref: "openai/prod". keywarden подставляет ключ, совершает вызов и возвращает ответ. Попросите её напечатать ключ — она ответит, что не может.
Инструменты, которые получает агент
Инструмент | Что делает |
| Только метаданные: refs, провайдеры, имена полей, последнее использование. Никогда значения. |
| Одно учётное данное плюс как его можно использовать, какие хосты, какие переменные окружения. |
| Встроенные пресеты и что ожидает каждый из них. |
| Аутентифицированный HTTPS-вызов. keywarden подставляет учётные данные. |
| Запускает локальный процесс с учётными данными, внедрёнными как переменные окружения. |
| Последние записи из журнала, защищённого от подделки. |
Установите KEYWARDEN_DISABLE_EXEC=1, чтобы полностью убрать run и оставить только HTTP-прокси.
Три поверхности, одна модель авторизации
Одно и то же хранилище, механизм политик, гранты и журнал аудита доступны тремя способами. То, какой из них вы используете, ничего не меняет в том, что разрешено.
поверхность | для | как идентифицируется вызывающий |
MCP (stdio) | Claude Code, Claude Desktop, Cursor | клиент, который запустил сервер |
CLI | вы, в терминале | доступ к файловой системе хранилища |
HTTP (loopback) | любой язык, CI, скрипт, веб-интерфейс | ограниченный API-ключ keywarden |
HTTP-поверхность — это то, что делает keywarden пригодным для кода, который не говорит на MCP, и это первое место, где keywarden может отличить одного вызывающего от другого:
keywarden apikey create ci-runner --ref 'openai/**' --http --audit --ttl 30d
keywarden serve --port 8787curl -s http://127.0.0.1:8787/v1/proxy/openai%2Fprod \
-H "Authorization: Bearer kw_live_..." \
-H "content-type: application/json" \
-d '{"method":"POST","url":"/v1/chat/completions","body":{"model":"gpt-4o","messages":[]}}'Вызывающий держит ключ keywarden с областью действия openai/**, несущий только те возможности, которые были предоставлены, истекающий через 30 дней, отзываемый одной командой. Он никогда не содержит OpenAI-ключ. Маршруты: /v1/secrets, /v1/secrets/:ref, /v1/proxy/:ref, /v1/run, /v1/audit, /v1/usage, /v1/whoami, /healthz.
Сервер привязывается к 127.0.0.1 и отказывается работать на маршрутизируемом интерфейсе без --allow-remote, потому что любой, кто может дотянуться до этого порта, получает оракул авторизации для каждого учётного данного, которое покрывает ключ.
Кто что использовал и сколько это стоило
Каждая запись в журнале аудита называет субъекта, и субъект находится внутри хэша, поэтому атрибуцию нельзя переписать, не разорвав цепочку. Каждый проксированный ответ разбирается для извлечения количества токенов, сообщённого провайдером.
keywarden usage --since 7dCREDENTIAL CALLS IN OUT TOTAL
openai/prod 142 418,220 96,410 514,630
anthropic/prod 38 92,004 31,887 123,891
ACTOR CALLS IN OUT TOTAL
http:ci-runner 118 356,900 74,220 431,120
mcp:mcp-client 62 153,324 54,077 207,401keywarden записывает токены, а не деньги. Цены меняются, различаются по контрактам, и устаревшая захардкоженная ставка даёт уверенно неверное число в финансовом отчёте. Обратите внимание, что run нельзя тарифицировать: как только учётные данные оказываются внутри дочернего процесса, keywarden видит код возврата, а не количество токенов.
Два способа использовать учётные данные
Прокси — для HTTP API. Агент описывает запрос, keywarden подставляет учётные данные и совершает вызов. Работает для OpenAI, Anthropic, Stripe, GitHub, Slack, Cloudflare, Vercel, Supabase и любого API, которое аутентифицируется через заголовок или query-параметр.
// what the agent sends
{ "ref": "openai/prod", "method": "POST", "url": "/v1/chat/completions", "body": { "model": "gpt-4o", "messages": [] } }Инъекция — для всего остального. AWS требует подписи запросов SigV4, Postgres URL — это вообще не HTTP, а terraform apply хочет настоящие переменные окружения. keywarden сам запускает процесс:
{ "command": "aws", "args": ["s3", "ls"], "inject": ["aws/prod"] }Дочерний процесс получает AWS_ACCESS_KEY_ID и остальных. Модель получает stdout, причём любые учётные данные, появляющиеся в нём, маскируются на выходе.
Политика
~/.keywarden/policy.json определяет, какое учётное данное может быть использовано, какой возможностью и против чего. Правила оцениваются сверху вниз, побеждает первое совпадение, а по умолчанию — запрет.
{
"version": 1,
"default": "deny",
"redactResponses": true,
"rules": [
{
"ref": "openai/**",
"http": { "allow": true, "methods": ["POST"], "paths": ["/v1/**"] },
"exec": { "allow": false, "commands": [] },
"rateLimitPerMinute": 30
},
{
"ref": "aws/prod",
"http": { "allow": false },
"exec": { "allow": true, "commands": ["aws", "terraform"] },
"rateLimitPerMinute": 10,
"expiresAt": "2026-12-31T00:00:00.000Z"
}
]
}Или из CLI:
keywarden policy allow "openai/**" --http --path "/v1/**" --method POST
keywarden policy allow aws/prod --exec aws --exec terraform --arg-deny "s3://*"
keywarden policy test aws/prod exec terraform* совпадает внутри одного сегмента пути, ** охватывает несколько сегментов. expiresAt делает правило временным.
Просто назвать команду недостаточно. Разрешите aws для aws s3 ls — и тот же бинарник сделает aws s3 cp в чужой бакет. Это разрыв на уровне последовательности, на который постоянно указывает литература по угрозам MCP: каждый отдельный вызов авторизован, а их комбинация — это эксфильтрация. Поэтому правила ограничивают и аргументы:
"exec": {
"allow": true,
"commands": ["aws"],
"argsDeny": ["s3://*", "--endpoint-url"], // any match refuses the call
"argsAllow": ["s3", "ls", "--region", "*"] // if set, every argument must match
}Гранты: временный, истекающий, ограниченный по использованию доступ
Политика — это постоянная конфигурация. Она не подходит для сценария «позволь агенту сделать вот это, сейчас, на пятнадцать минут», который сегодня означает расширение правила и забывание снова его сузить.
Грант — это возможность, которая несёт собственные ограничения, заимствованная из традиции macaroon и biscuit, и выдаётся вами в терминале:
keywarden grant aws/prod --exec aws --ttl 15m --uses 5 --arg-deny "s3://*"
keywarden grant openai/prod --http --path "/v1/chat/**" --method POST --ttl 1h --uses 20
keywarden grant list
keywarden grant revoke <id>Гранты истекают сами, умирают, когда заканчивается их бюджет использования, и подписываются HMAC-ключом, производным от вашего хранилища, поэтому отредактированный вручную grants.json отклоняется, а не принимается. Отклонённая попытка не сжигает использование.
Установите "requireGrant": true в правиле политики — и постоянная конфигурация становится необходимой, но не достаточной: ничего не происходит, пока вы не выдадите грант. Это шаг одобрения с участием человека, без необходимости интерактивного запроса внутри stdio-сервера.
политика | грант | результат |
разрешает, без | — | разрешить |
разрешает, с | действующее совпадение | разрешить |
разрешает, с | нет | запретить |
запрещает | действующее совпадение | разрешить |
запрещает | нет | запретить |
Целостность конфигурации
Шифрование секретов — это половина дела. policy.json решает, можно ли использовать учётное данное, а providers.json решает, куда оно отправляется. Оба — обычные файлы. Тот, кто не может расшифровать ни одного байта, всё равно может добавить провайдера, чьи хосты принадлежат ему, и перенаправить ваше учётное данное на него.
Поэтому хранилище фиксирует хэш обоих файлов и отказывается работать с любым из них, пока вы не посмотрите на изменение:
keywarden trust show # what drifted
keywarden trust # review, then pin the current contentsСам файл хранилища снабжается MAC-кодом целиком, а не только по полям, потому что замена provider: "openai" на что-то другое никогда не затрагивает шифротекст и в противном случае прошла бы проверку чисто.
Что keywarden действительно обеспечивает
Нет инструмента, возвращающего открытый текст. В MCP-поверхности нет пути кода, который возвращает значение учётного данного.
Разрешающий список исходящих. Учётное данное может быть отправлено только на хосты, объявленные его провайдером, плюс те, что вы добавили в политику. Инъекция в промпт, говорящая агенту отправить ваш ключ на
attacker.example, проваливается на проверке хоста, ещё до обращения к сети.Только HTTPS, без перехода по редиректам. 302 на другой origin не повторит ваш заголовок
Authorizationвне хоста.Защита от SSRF. Loopback, частные диапазоны, CGNAT и link-local (что покрывает endpoint метаданных облака
169.254.169.254) блокируются, а адрес проверяется в том DNS-запросе, который реально использует сокет, поэтому DNS-ребinding не открывает окно.Никакого шелла.
runпередаёт массив argv вspawnсshell: false. Нет разбора метасимволов, в который можно внедриться.Сконструированное окружение дочернего процесса. Дочерний процесс получает разрешающий список унаследованных переменных плюс внедрённые. Ваши остальные секреты и собственная парольная фраза keywarden не наследуются.
Редактирование вывода. Каждый результат инструмента сканируется на известные значения учётных данных, их base64 и URL-encoded формы и около дюжины известных форм ключей. Это эшелонированная защита, а не основной контроль.
Аудит, защищённый от подделки. Каждое решение — разрешение или запрет — добавляется в журнал с хэш-цепочкой.
keywarden audit verifyпересчитывает цепочку и сообщает о первой изменённой или удалённой записи.Целостность всего файла. Хранилище снабжается MAC-кодом, включая метаданные, поэтому учётное данное нельзя перенаправить другому провайдеру без обнаружения.
policy.jsonиproviders.jsonпривязаны по хэшу к хранилищу и отклоняются при изменении вне полосы.Усиление окружения. Сервер отказывается запускаться, когда установлены
NODE_TLS_REJECT_UNAUTHORIZED=0,NODE_OPTIONSилиSSLKEYLOGFILE, и предупреждает оNODE_EXTRA_CA_CERTSиHTTPS_PROXY. CVE-2026-21852 против Claude Code был одним переопределением окружения, которое перенаправляло исходящий трафик с прикреплённым заголовкомAuthorization; процесс, чья работа — прикреплять учётные данные, не должен запускаться, когда путь запроса находится под чужим контролем.Ограничения аргументов.
argsAllow/argsDenyсужают какие именно вызовы разрешённой команды допустимы, а не только какой бинарник.Ослабленные гранты. Истекающие, ограниченные по использованию, выдаваемые оператором возможности, устойчивые к подделке благодаря MAC, производному от хранилища.
Обрамление недоверенных данных. Тела проксированных ответов помечаются как недоверенное содержимое от указанного хоста, поэтому внедрённая инструкция в API-ответе подаётся модели как данные.
Криптография
Конвертное шифрование, всё из node:crypto, никаких сторонних криптобиблиотек.
Случайный 256-битный ключ данных шифрует каждое поле с помощью AES-256-GCM, используя ref и имя поля учётного данного как дополнительные аутентифицированные данные, поэтому шифротекст нельзя переместить между записями хранилища.
Ключ данных оборачивается ключом, производным от вашей парольной фразы, с помощью scrypt при
N=2^17, r=8, около 128 MiB и примерно секунда на попытку. Это сделано намеренно: файл хранилища — это то, с чем уходит атакующий, поэтому офлайн-подбор должен быть дорогим.Ротация парольной фразы переоборачивает 32 байта. Она не перешифровывает каждый секрет.
Режимы хранилища
--passphrase — это надёжный режим. MCP-серверу нужен KEYWARDEN_PASSPHRASE в его окружении, чтобы разблокироваться без запроса.
--keyfile записывает случайный ключ в ~/.keywarden/masterkey, чтобы ничто не требовало запроса. Это удобно, но означает, что любой, кто может читать ваш домашний каталог, сможет открыть хранилище. Это всё равно гораздо лучше, чем разбросанные по проектам файлы .env в открытом виде, потому что ключ находится в одном месте, его использование ограничено политикой, и каждое использование логируется. Знайте, на какой компромисс вы пошли. keywarden doctor вам напомнит.
В Windows режимы файлов устанавливаются, но не соблюдаются так, как POSIX соблюдает 0600. См. THREAT_MODEL.md.
CLI
keywarden init --passphrase|--keyfile create the vault
keywarden doctor check the install, flag weak settings
keywarden trust [show] re-pin policy.json + providers.json after reviewing a change
keywarden grant <ref> ... issue a temporary, use-capped capability
keywarden grant list | revoke <id>
keywarden add <ref> --provider <id> store a credential (prompts for each field)
keywarden list metadata only
keywarden describe <ref> metadata plus how it can be used
keywarden reveal <ref> print plaintext, asks first, always audited
keywarden rm <ref> [--field f] delete
keywarden exec <ref[,ref]> -- <cmd> run a command with credentials injected
keywarden policy show|init|allow|deny|test
keywarden audit [tail|verify]
keywarden passphrase rotate
keywarden providers built-in presets
keywarden mcp-config print the MCP client config
keywarden doctor check the install, flag weak settingsПользовательские провайдеры
Всё, что не встроено, помещается в ~/.keywarden/providers.json. См. docs/PROVIDERS.md.
{
"acme": {
"label": "Acme Internal API",
"hosts": ["api.acme.internal", "*.acme.io"],
"baseUrl": "https://api.acme.io",
"fields": ["token", "tenant"],
"required": ["token"],
"auth": { "type": "header", "name": "X-Acme-Key", "template": "{{token}}" },
"env": { "ACME_TOKEN": "{{token}}", "ACME_TENANT": "{{tenant}}" }
}
}От чего keywarden вас не защищает
Прочтите THREAT_MODEL.md, прежде чем доверить ему что-либо дорогое. Краткая версия:
Если агент может выполнять произвольные локальные команды через какой-либо другой инструмент, он сможет прочитать ваш файл хранилища и, в режиме ключевого файла, ваш мастер-ключ. keywarden защищает контекст модели, а не ваш диск.
runпередаёт учётные данные реальному процессу. Если вы внесёте в список разрешённых команду, которую можно направить на извлечение собственного окружения, учётные данные уйдут. Вносите в список разрешённых узко.Редактирование — это страховочная сетка с дырами. Учётные данные, которые API возвращает в перекодированном виде, который мы не распознаём, не будут обнаружены.
keywarden не мешает агенту сделать что-то дорогостоящее или разрушительное с учётными данными, которые ему разрешено использовать. Для этого существуют политики ограничения и лимиты скорости.
Разработка
npm install
npm run build
npm test # 89 unit tests + 46 end-to-end checks against the real CLI, MCP and HTTP serversНабор e2e-тестов управляет реальными бинарными файлами во временной KEYWARDEN_HOME и проверяет, в частности, что ни один ответ инструмента не содержит учётные данные.
Чтение
THREAT_MODEL.md — что входит в область применения, а что честно нет
docs/RESEARCH.md — литература 2026 года, на которой основан этот дизайн, что было принято, а что рассмотрено и отклонено
docs/COMPETITORS.md — ландшафт, и в чём keywarden действительно отличается, а не просто по-другому маркетируется
docs/TEAM.md — многопользовательская архитектура: идентичность, обмен ключами без читаемого сервера, процесс утверждения, учёт затрат и порядок сборки
docs/PROVIDERS.md — написание собственного провайдера
Хостинговая версия
Планируется хостинговая версия для тех, кто хочет командное хранилище, управление через браузер и синхронизацию между машинами, с той же гарантией нулевой экспозиции. Всё в этом репозитории остаётся под лицензией MIT и полностью пригодным для автономного использования. См. docs/HOSTED.md.
Лицензия
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceCredential isolation proxy for AI agents. Injects API keys at the network boundary so your agent never sees the raw credential. Supports domain allowlists, agent auth, policy enforcement, and audit logging.38913Apache 2.0
- FlicenseNot gradedqualityAmaintenanceProvides a trust and governance layer for AI agents, enabling secure API access, credential vaulting, paid execution with human approval, and automatic call resume.82

AgentValetofficial
AlicenseAqualityAmaintenanceIdentity and credential governance for AI agents. Every agent gets its own cryptographic identity, scoped short-lived credentials per platform, human approval on sensitive actions, and an immutable audit log.71MIT- AlicenseNot gradedqualityCmaintenanceEnables AI agents to securely perform privileged actions like creating GitHub issues by minting short-lived, single-purpose tokens on demand, with policy enforcement and audit logging.MIT
Related MCP Connectors
Issue, rotate and revoke scoped API-key passes for 25+ providers — the agent never sees a real key
Encrypted secret store and rotation for autonomous agent credentials
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/DINAKAR-S/keywarden'
If you have feedback or need assistance with the MCP directory API, please join our Discord server