Секреты
Hermes умеет вытягивать API-ключи из внешних менеджеров секретов прямо на старте процесса — вместо того чтобы держать их в ~/.hermes/.env. В .env остаётся только bootstrap-токен самого менеджера. Все остальные ключи провайдеров (OpenAI, Anthropic, OpenRouter и так далее) живут в менеджере и ротируются централизованно. Для автономного ИИ-агента на своём сервере это удобно: один источник правды для учётных данных, а не россыпь ключей по конфигам.
Что поддерживается:
- Bitwarden Secrets Manager — CLI
bws, ставится по требованию, бесплатного тарифа хватает. - 1Password — ссылки
op://через официальный CLIop; авторизация сервис-аккаунтом или десктопной сессией. - Команда-хелпер — любое CLI-хранилище (
keepassxc-cli,secret-tool,pass, самописный скрипт) через настроенную вами команду-хелпер, которая печатает строкиKEY=VALUE.
Несколько источников одновременно
Можно включить сразу несколько источников секретов — например, командный проект в Bitwarden вместе с личным плагином-хранилищем. Источники сочетаются по каждой переменной окружения отдельно, по детерминированной лестнице приоритетов:
- По умолчанию побеждает ваш
.env/ шелл. Источник заменяет уже существующее значение только тогда, когда у него самого выставленoverride_existing: true(у Bitwarden это true по умолчанию — чтобы работала централизованная ротация). - Сопоставленные источники бьют массовые. Источник, где вы явно привязываете переменные окружения к ссылкам (карта
env:), обходит источник, который неявно вливает целый проект секретов, — независимо от порядка. - Первый заявивший побеждает. Внутри одной формы порядок решает необязательный список
secrets.sources(или порядок регистрации). Повторная заявка на уже занятую переменную пропускается — с предупреждением при старте, а не молча.
override_existing никогда не позволяет одному источнику перезаписать переменную, уже занятую другим источником, и ни один источник не может перезаписать чужой bootstrap-токен (например, BWS_ACCESS_TOKEN).
secrets:
sources: [bitwarden] # необязательный явный порядок
bitwarden:
enabled: true
project_id: "..."
У каждого значения, которое подставляет источник, отмечено происхождение — в мастерах настройки и в hermes model рядом с найденными ключами стоит пометка (from Bitwarden), так что всегда видно, откуда взялось значение.
Профили и общие хранилища
Два флага на уровне оркестратора делают одно общее хранилище безопасным сразу для нескольких профилей:
-
secrets.preserve_existing— список имён переменных окружения, чьё текущее значение из.env/ шелла побеждает всегда, даже против источника сoverride_existing: true. Пригодится для секретов конкретного профиля (например,FEISHU_APP_SECRET), которые намеренно различаются между профилями, пока всё остальное ротируется централизованно:secrets: preserve_existing: [FEISHU_APP_SECRET, TELEGRAM_BOT_TOKEN] -
Алиасинг профилей (включён по умолчанию, отключается через
secrets.profile_alias: false) — когда Hermes запущен под именованным профилем, секрет хранилища с именемFOO_<PROFILE>(только для суффиксов вида учётных данных:*_API_KEY,*_TOKEN,*_SECRET,*_KEY,*_PASSWORD) заодно наполняет и каноническое имяFOO. ПоложитеTELEGRAM_BOT_TOKEN_MILLAв общий проект — и адаптеры профиляmilla, которые читают фиксированное имяTELEGRAM_BOT_TOKEN, автоматически получат нужное значение. Переменная, которую хранилище отдаёт напрямую под каноническим именем, всегда побеждает алиас.
Оба флага действуют для любого источника — и встроенного, и плагина, — потому что живут в оркестраторе, а не в бэкендах.
Секреты в дочерних процессах
Терминальные команды, песочницы execute_code и скрипты cron-задач no_agent запускаются с очищенным окружением: учётные данные, которыми управляет Hermes, вырезаются, а пробрасываются только переменные, объявленные в terminal.env_passthrough (или в required_environment_variables загруженного навыка). Объявленная переменная пробрасывается со значением профиля-владельца — из .env этого профиля или его источников секретов, — даже если профиль обслуживается мультипрофильным шлюзом или бэкендом десктопа/дашборда и его секреты никогда не попадали в окружение процесса. Объявленное значение одного профиля никогда не доходит до дочерних процессов другого, а учётные данные из .env профиля запуска выбрасываются из дочерних процессов, которые работают для обслуживаемого профиля. Учётные данные провайдеров объявить нельзя; см. Безопасность → Область действия учётных данных.
Свой бэкенд
Сторонние менеджеры секретов поставляются отдельными плагинами, а не PR в ядро. Бэкенд наследует agent.secret_sources.base.SecretSource (обязателен один метод: fetch(cfg, home_path) -> FetchResult) и регистрируется через ctx.register_secret_source(MySource()) в register(ctx) плагина. Оркестратор берёт на себя приоритеты, разрешение конфликтов, тайм-ауты и происхождение — источник только получает значения. Полный гайд с правилами контракта, хелпером безопасности подпроцессов и набором тестов на соответствие: Плагины источников секретов.
Встроенный набор закрыт намеренно (та же политика, что и у провайдеров памяти): Bitwarden и 1Password идут в комплекте. Всё остальное — Infisical, Proton Pass, HashiCorp Vault, AWS Secrets Manager, системные keystore — оформляется как плагин-репозиторий; делитесь им в Discord Nous Research (#plugins-skills-and-skins).