Секреты и токены
Велес хранит секреты отдельно от обычногоconfig.json. Конфигурация может содержать только ссылку на секрет (SecretRef) или пустое значение, а реальные токены загружаются во время работы и не отправляются в интерфейс Велеса или модель.
Что обязательно для запуска
Шлюз Велеса запускается только при наличии двух серверных секретов:gateway.tokenили переопределяющего егоVELES_GATEWAY_TOKEN— для доступа Nerve к шлюзу;VELES_SECRETS_MASTER_KEY— для чтения и записи зашифрованного хранилища.
VELES_SECRETS_MASTER_KEY должен быть корректным ключом в окружении процесса сервера Велеса. Интерфейс Велеса не должен получать этот ключ. Ключи поставщиков моделей, векторной памяти, распознавания аудио, глубокого исследования, веб-поиска, каналов и навыков для запуска шлюза не нужны. Если они ещё не заполнены, Nerve всё равно откроется и покажет их в разделе «Секреты»; зависимая возможность сообщит об ошибке только при попытке её использовать.
Вместо задания переменной в текущей оболочке её можно записать в .env каталога, из которого выполняется uv run veles gateway. Уже заданная переменная окружения имеет приоритет над значением из файла. Не добавляйте .env с настоящими ключами в репозиторий.
Где лежат локальные секреты
Зашифрованное локальное хранилище пишет файлы в каталогsecrets внутри рабочей области, указанной в agents.defaults.workspace активного config.json:
<workspace>/secrets/values.enc.json— обычные ключи API и секреты окружения навыков;<workspace>/secrets/auth-profiles.enc.json— OAuth-профили, например OpenAI Codex.
version, alg, nonce, ciphertext, timestamps). Значения секретов не лежат там открытым текстом.
SecretRef
SecretRef говорит Велесу, откуда брать секрет:
local— зашифрованное локальное хранилище Велеса;env— переменная окружения процесса сервера;file— файл на машине сервера;exec— команда, которая возвращает секрет.
local используется объект, а не строковая подстановка:
"${NAME}" означает только ссылку на переменную окружения и не подходит для локальных секретов Велеса.
Несколько потребителей могут ссылаться на один локальный id: зашифрованное значение при этом хранится в одном экземпляре. Например, источник задач Bitrix24 использует те же два значения, что и навык alor-bitrix24:
scripts/config.template.json использует тот же приём для OpenRouter. Поля providers.openrouter.apiKey, tools.audio.apiKey и tools.vectorMemory.embeddingApiKey ссылаются на единый идентификатор providers.openrouter.api_key; глубокое исследование тоже читает ключ этого поставщика. Поэтому в Nerve достаточно один раз заполнить цель OpenRouter. Токен Telegram, ключ Tavily и ключ разбора документов Mistral имеют отдельные цели и также записываются через раздел «Секреты».
Обычными владельцами этих значений в панели секретов остаются канонические цели навыка. Когда навык alor-bitrix24 обнаружен, технические цели tasks.bitrix.webhook_user_id и tasks.bitrix.webhook_code скрыты из каталога, предупреждений и признаков перезапуска, но продолжают разрешать и маскировать поля конфигурации задач. Если навыка ещё нет, они показываются как запасной способ первоначальной настройки и записывают значение по тому же каноническому идентификатору. Поэтому повторно сохранять идентификатор пользователя и код вебхука для доски не нужно. Очистка такой ссылки потребителя не удаляет общее значение, которым владеет цель навыка.
Интерфейс Велеса в первую очередь управляет local: пользователь вводит значение один раз, Велес шифрует его и дальше возвращает только замаскированный статус.
Пароль входа в Nerve тоже хранится на стороне Велеса, но не показывается как обычная цель в каталоге секретов. Велес записывает только scrypt-хэш пароля во внутренний ключ зашифрованного хранилища. Nerve при входе отправляет пароль в auth.login, получает gateway.token только в серверный процесс и не сохраняет его в браузере.
Если это зашифрованное хранилище нельзя прочитать, Велес не считает пароль отсутствующим и не включает вход через gateway.token. Сначала восстановите ключ шифрования или доступ к хранилищу секретов.
Как интерфейс показывает секреты
В интерфейсе Велеса откройте «Рабочая область» → «Секреты». Интерфейс получает список целей так:GET /api/secrets;- внутренний вызов
secrets.catalog; - Велес строит каталог из провайдеров, инструментов, каналов, MCP-серверов и метаданных навыков.
MISSING или EMPTY, это не значит, что секрет находится в интерфейсе. Это только замаскированная цель: Велес знает, что такой секрет может понадобиться, но значение ещё не настроено.
Общие предупреждения каталога в Nerve не показываются. Ошибка конкретного секрета отображается рядом с его целью, поэтому сообщение остаётся связано с нужным полем. Значения секретов при этом не показываются.
Поле поиска в панели Секреты фильтрует уже загруженный список на стороне Nerve. Оно не делает дополнительных запросов к gateway и ищет по названию секрета, target id, пути конфигурации и источнику.
Секреты навыков
Навык может объявить нужный секрет окружения вSKILL.md:
skills.github.env.GH_TOKEN. Если значение сохранить в панели секретов, Велес будет подставлять GH_TOKEN только на время выполнения ответа. Значение не попадает в инструкцию модели и не записывается в config.json.
requires.env делает переменную обязательной: без неё навык считается недоступным. Для опциональных API-ключей используйте отдельный список секретов:
config.json. Необязательный секрет можно оставить пустым или удалить позднее; обязательный разрешено заменить, но не удалить через редактор навыка.
Например, устанавливаемый из каталога навык fda-database объявляет опциональный OPENFDA_API_KEY как skills.fda-database.env.OPENFDA_API_KEY: ключ повышает дневной лимит openFDA, но без него навык всё равно работает. Навык entrez-search аналогично объявляет необязательные NCBI_API_KEY и NCBI_EMAIL. Эти значения подставляются из защищённого окружения и не передаются в аргументах команды.
Навык google-workspace хранит более крупные значения: файл клиента Google, токен и временное состояние авторизации. Они тоже записываются в зашифрованное локальное хранилище, но как JSON-значения с ключами skills.google-workspace.google_client_secret_json, skills.google-workspace.google_token_json и skills.google-workspace.google_oauth_pending_json.
Навык alor-teamly читает логин и параметры выбора домена/аккаунта из обычной настройки skills.entries.alor-teamly.config. Только пароль LDAP хранится как секрет skills.alor-teamly.env.TEAMLY_PASSWORD. Полученные от Teamly куки сохраняются отдельно под внутренним ключом skills.alor-teamly.session_json. Пароль не передаётся модели, не помещается в командную строку и не записывается в открытый файл.
OpenAI Codex OAuth
OpenAI Codex использует OAuth, а не ключ API. Его токены хранятся в зашифрованном хранилище профилей:- этап, на котором возникла ошибка;
- исходные технические сведения от Велеса;
- рекомендуемое следующее действие.
Что важно помнить
config.jsonне должен хранить новые секреты открытым текстом.- Интерфейс Велеса никогда не показывает сохранённое значение секрета.
- Без корректного
VELES_SECRETS_MASTER_KEYшлюз Велеса не запускается. Ссылки на остальные отсутствующие секреты не блокируют запуск: их можно заполнить через Nerve после подключения. - Для постоянного развёртывания нужно сохранять каталог
.velesи передавать главный ключ через менеджер секретов окружения.
