Bitwarden Secrets Manager
Ключи API можно подтягивать из Bitwarden Secrets Manager при старте процесса, а не держать открытым текстом в ~/.hermes/.env. Один загрузочный секрет — токен доступа машинного аккаунта — заменяет собой N отдельных ключей по провайдерам, а ротация учётных данных сводится к одной правке в веб-приложении Bitwarden.
Как это работает
- Вы заводите машинный аккаунт (machine account) в Bitwarden Secrets Manager, даёте ему доступ на чтение к проекту и генерируете токен доступа.
- Этот единственный токен Hermes хранит в
~/.hermes/.envпод именемBWS_ACCESS_TOKEN. - На каждом запуске
hermes(а также шлюза или задания cron) — уже после загрузки~/.hermes/.env— Hermes вызываетbws secret list <project_id>и кладёт полученные ключи вos.environ. - По умолчанию значения, которые уже есть в окружении, перезаписываются, так что источником истины становится Bitwarden: поменяли ключ один раз в веб-приложении — и каждый процесс Hermes подхватит его на следующем старте. Хотите, чтобы вместо этого побеждал
.env, — переключите в конфигеoverride_existing: false.
Если в PATH есть исполняемый bws, Hermes берёт его, прежде чем смотреть выбор PM.
Если нет ни того ни другого, при первом обращении закреплённый пакет запрашивается у
PM — с учётом политики отложенной установки.
Зачем машинные аккаунты (и почему не спрашивают 2FA)
Bitwarden Secrets Manager рассчитан на неинтерактивные нагрузки: машинные аккаунты в принципе не защищаются 2FA, потому что человека в цепочке нет. Учётными данными служит сам токен доступа. У кого он есть, тот читает любой секрет, к которому имеет доступ машинный аккаунт, — относитесь к нему как к ценному bearer-токену: храните в .env (не в config.yaml), а при утечке отзывайте и генерируйте заново через веб-приложение Bitwarden.
Настраиваете машинный аккаунт вы в веб-приложении, где работает ваша обычная 2FA. Дальше токен живёт автономно.
Настройка
1. Создайте машинный аккаунт и токен доступа
В веб-приложении Bitwarden (или на vault.bitwarden.eu для европейских аккаунтов):
- Переключитесь на Secrets Manager через переключатель продуктов.
- Создайте или выберите Project (например, «Hermes keys»).
- Добавьте ключи провайдеров как секреты. Поле Name у секрета станет именем переменной окружения — используйте
OPENROUTER_API_KEY,ANTHROPIC_API_KEYи так далее. - Machine accounts → New machine account → My Hermes machine → вкладка Projects → выдайте доступ Read к вашему проекту.
- Вкладка Access tokens → Create access token → срок Never (или укажите дату) → скопируйте токен (начинается с
0.). Повторно Bitwarden его не покажет — сохраните копию.
Secrets Manager входит в бесплатный тариф Bitwarden с ограничениями; чтобы попробовать, платный план не нужен.
2. Запустите мастер
hermes secrets bitwarden setup
Он:
- Если
bwsнет, запросит его закреплённый пакет у PM. - Запросит токен доступа (ввод скрыт). Сохранит его в
~/.hermes/.envкакBWS_ACCESS_TOKEN. - Спросит, к какому региону Bitwarden относится ваш машинный аккаунт — US Cloud, EU Cloud или self-hosted / свой URL. Значение пишется в
config.yamlкакsecrets.bitwarden.server_urlи передаётсяbwsчерезBWS_SERVER_URL. - Покажет проекты, видимые машинному аккаунту; выберите один. Запишется в
config.yamlкакsecrets.bitwarden.project_id. - Сделает тестовую выборку секретов проекта и покажет, какие переменные окружения подставятся.
- Переключит
secrets.bitwarden.enabled: true.
Поддерживается и неинтерактивная настройка через флаги:
hermes secrets bitwarden setup \
--access-token "$BWS_ACCESS_TOKEN" \
--server-url https://vault.bitwarden.eu \
--project-id <project-uuid>
3. Проверьте
hermes secrets bitwarden status
Теперь каждый вызов hermes подтягивает свежие секреты на старте. При первом применении секретов в процессе в stderr появится однострочная сводка.
CLI
| Команда | Что делает |
|---|---|
hermes secrets bitwarden setup | Интерактивный мастер (установка бинарника, запрос токена, выбор проекта, тестовая выборка) |
hermes secrets bitwarden status | Показывает конфиг + версию бинарника + наличие/валидность токена |
hermes secrets bitwarden token | Ротация токена доступа: сначала проверяет новый токен в Bitwarden, затем сохраняет его в .env |
hermes secrets bitwarden sync | Сухой прогон: подтягивает секреты сейчас и показывает, что было бы применено |
hermes secrets bitwarden sync --apply | Подтягивает и экспортирует в окружение текущей оболочки |
hermes secrets bitwarden install | Устанавливает или чинит закреплённый в PM бинарник bws. Аутентификация в Bitwarden не нужна. |
hermes secrets bitwarden install --force | Проверяет и чинит управляемую копию. Корректные записи можно переиспользовать без повторной загрузки. |
hermes secrets bitwarden disable | Переключает enabled: false; токен и id проекта оставляет на месте |
Ротация просроченного или отозванного токена
Когда токен машинного аккаунта просрочен, отозван или аккаунт удалён, при старте выводится:
Bitwarden Secrets Manager: Bitwarden rejected the machine-account access token (BWS_ACCESS_TOKEN) — it was likely revoked, expired, or belongs to another region. (...)
Bitwarden Secrets Manager: → Run `hermes secrets bitwarden token` to paste a fresh access token ...
Чинится без перезапуска всего мастера:
hermes secrets bitwarden token # ввод скрыт
hermes secrets bitwarden token --access-token 0.… # неинтерактивно
Команда проверяет новый токен в Bitwarden до записи чего-либо — отклонённый токен не тронет текущий .env. При успехе токен сохраняется, кэши выборки очищаются, а если настроенный проект не виден новому машинному аккаунту, выводится предупреждение.
Конфигурация
Значения по умолчанию в ~/.hermes/config.yaml:
secrets:
bitwarden:
enabled: false
access_token_env: BWS_ACCESS_TOKEN
project_id: ""
server_url: ""
cache_ttl_seconds: 300
encrypted_cache:
enabled: false
max_stale_seconds: 0
override_existing: true
auto_install: true
| Ключ | По умолчанию | Что делает |
|---|---|---|
enabled | false | Главный выключатель. Пока false, к Bitwarden обращений нет. |
access_token_env | BWS_ACCESS_TOKEN | Имя переменной окружения с загрузочным токеном. Поменяйте, если BWS_ACCESS_TOKEN у вас уже занято под другое. |
project_id | "" | UUID проекта, из которого синхронизируем. |
server_url | "" | Регион Bitwarden или self-hosted-эндпоинт. Пусто — значение по умолчанию для bws (US Cloud, https://vault.bitwarden.com). Для EU Cloud укажите https://vault.bitwarden.eu, для self-hosted — свой URL. Прокидывается в подпроцесс bws как BWS_SERVER_URL. |
cache_ttl_seconds | 300 | Сколько секунд переиспользуется результат выборки внутри процесса или на диске. 0 отключает переиспользование свежего кэша. |
encrypted_cache.enabled | false | Хранить результат последней успешной выборки в зашифрованном (AES-GCM) кэше на диске — ~/.hermes/cache/bws_cache.enc.json. |
encrypted_cache.max_stale_seconds | 0 | При включённом зашифрованном кэше разрешает использовать его только после сетевых сбоев или таймаутов, и не старше этого возраста в секундах. При ошибках аутентификации устаревшие секреты не используются никогда. Успешная запись в зашифрованный кэш удаляет старый незашифрованный cache/bws_cache.json. |
override_existing | true | При true значения из Bitwarden перетирают то, что уже есть в окружении (так ротация в веб-приложении реально срабатывает). Поставьте false, если локально должны побеждать .env или экспорты оболочки. |
auto_install | true | Запрашивает закреплённый в PM пакет bws, если бинарника нет. Действует и политика отложенной установки PM. |
Сценарии сбоев
Старт Hermes Bitwarden не блокирует никогда. Если что-то пошло не так, в stderr выводится однострочное предупреждение, и Hermes продолжает работать с теми учётными данными, что уже были в .env:
| Симптом | Причина | Что делать |
|---|---|---|
BWS_ACCESS_TOKEN is not set | В конфиге включено, но токен стёрт из .env | Перезапустите hermes secrets bitwarden setup |
Bitwarden rejected the machine-account access token … invalid_client | Токен отозван, просрочен, машинный аккаунт удалён — либо токен от другого региона Bitwarden (например, токен EU бьёт в identity-эндпоинт US) | Выполните hermes secrets bitwarden token и вставьте новый токен; при несовпадении региона перезапустите setup и выберите EU/self-hosted (либо задайте secrets.bitwarden.server_url) |
bws exited 1: invalid access token | Токен отозван или неверный | Выполните hermes secrets bitwarden token с новым токеном |
bws timed out | Сеть заблокирована или API Bitwarden тормозит | Проверьте связь с api.bitwarden.com (или вашим server_url) |
bws binary not available | Нет ни выбора PM, ни исполняемого файла в PATH, а автоматическая установка отключена или не удалась | Выполните hermes secrets bitwarden install и прочитайте его диагностику. |
| Ошибка контрольной суммы | Загрузка не совпадает с lock-файлом PM | Остановитесь и проверьте источник загрузки. Не обходите проверку хеша. |
Предупреждения при старте теперь содержат строку-подсказку с →, где указана точная команда для исправления.
Заметки по безопасности
- Загрузочный токен (
BWS_ACCESS_TOKEN) сам по себе чувствителен: у кого он есть, тот читает любой секрет, доступный машинному аккаунту. Берегите его как обычный ключ API. - Перезаписать собственный загрузочный токен Hermes из Bitwarden не даст — даже при
override_existing: true. Если вы хранитеBWS_ACCESS_TOKENсекретом внутри проекта, при применении он молча пропускается. - PM сверяет управляемый архив с его хешем SHA-256 в
pm/lock.json. Несовпадение прерывает установку. - Версию объявляет тот же lock-файл. При первом обращении релиз «latest» не ищется. Внешние бинарники под эти проверки PM не подпадают.
Когда этим лучше не пользоваться
- Персональные установки на одной машине, где и
~/.hermes/.envвполне хватает. Вы меняете одни учётные данные на другие и добавляете сетевую зависимость на старте. - Изолированные (air-gapped) окружения, у которых нет доступа к
api.bitwarden.com. - CI/CD, где уже настроен механизм подстановки секретов (GitHub Actions secrets, Vault и прочее) — выберите один путь, а не два сразу.
А вот где это в самый раз: парки из множества машин, общие dev-боксы, шлюзовые VPS — словом, любая конфигурация, где нужны централизованные ротация и отзыв сразу для нескольких установок Hermes.