
vault-conductor v0.3.1
SSH-агент, который предоставляет SSH-ключи, хранящиеся в Bitwarden Secrets Manager
SSH-агент, который предоставляет SSH-ключи, хранящиеся в Bitwarden Secret Manager, в виде секретов.
Поддерживает SSH-аутентификацию и подпись Git-коммитов.
Demo

Возможности
Он реализует протокол SSH Agent в виде сервера Unix domain socket, выступая в роли безопасного моста между вашими SSH-клиентами и Bitwarden Secrets Manager.
Возможности:
- Жизненный цикл агента: работает как демон (в фоне) или процесс переднего плана, прослушивая Unix-сокет по адресу
/tmp/vc-$(whoami)-ssh-agent.sock - Ленивая загрузка ключей: SSH-ключи запрашиваются из Bitwarden через официальный Rust SDK только по требованию, затем кэшируются в памяти
- Безопасные SSH-операции: когда SSH-клиенты запрашивают идентификаторы или подписи, агент обрабатывает запросы с помощью крейта
ssh-agent-lib, никогда не раскрывая приватные ключи на диске - Управление процессами: фоновый режим запускает отсоединённый дочерний процесс, отслеживает PID и поддерживает корректное завершение через SIGTERM/SIGINT
- Безопасность: права на сокет устанавливаются в
0600(только владелец), ключи живут только в памяти процесса, а вызовы API Bitwarden выполняются с использованием ограниченного машинного токена, которому можно настроить детальный доступ к секретам.
Под капотом он построен на Tokio для асинхронного ввода-вывода, использует крейт ssh-key для криптографических операций и поддерживает ключи Ed25519 и RSA в формате OpenSSH.
Зачем
Это родилось из моей потребности. Функция Bitwarden SSH Agent в GUI-клиенте Bitwarden удобна, но что использовать, если у вас только CLI на devbox? Как безопасно принести свой SSH-ключ в CI/CD пайплайн для подписи git-коммитов? Что если нужно открыть SSH-соединение из эфемерного контейнера или ВМ без копирования приватного ключа? Как избежать работы с парольными фразами, хранящимися в связке ключей и привязанными к сеансам входа?
Поэтому я написал небольшой CLI-инструмент для получения SSH-ключей и предоставления доступа к ним без раскрытия их приватной части.
А чтобы не тащить всё ваше хранилище Bitwarden в окружение, он использует Bitwarden Secrets Manager, поэтому вы можете выбрать, какая машина имеет доступ к какому секрету, и настроить детальные права токена.
Требования
- Учётная запись Bitwarden с настроенным Bitwarden Secrets Manager (можно создать и настроить бесплатно) (поддержка self-hosted Bitwarden запланирована)
- SSH-ключ Ed25519 или RSA в новом формате OpenSSH, сохранённый как значение секрета в BWS
- Его необходимо сохранить вместе со строками
-----BEGIN OPENSSH PRIVATE KEY-----и-----END OPENSSH PRIVATE KEY-----. - Примечание: новый формат приватных ключей OpenSSH появился в OpenSSH 7.8 в 2018 году.
- Его необходимо сохранить вместе со строками
- macOS или Linux, выпущенные за последние 5 лет
Установка
Любым из способов ниже.
poof
С помощью poof:
poof install pirafrank/vault-conductor
Однострочный скрипт
curl -fsSL https://raw.githubusercontent.com/pirafrank/vault-conductor/main/install.sh | sh
Homebrew
brew tap pirafrank/tap
brew install vault-conductor
Вручную
или вручную скачайте последний стабильный релиз и положите его в $PATH.
Из исходников
cargo install --locked --git https://github.com/pirafrank/poof --tag VERSION
Конфигурация
Вам нужно указать:
BWS_ACCESS_TOKEN— машинный токен, который вы настроили выше. Переменная окружения имеет то же имя, что и CLI-инструментbwsот BitwardenBW_SECRET_IDS— разделённый запятыми список UUID секретов, в которых хранится каждый приватный ключ. Вы можете увидеть UUID каждого секрета в веб-приложении BWS (смотрите под именем секрета).BW_SERVER_ENDPOINT(необязательно) — пользовательская конечная точка сервера Bitwarden (только хост, без протокола). Если не указана, по умолчанию используетсяbitwarden.com. Допустимые примеры:bitwarden.eu(облако) иmyvault.example.com,192.168.1.100,vault.internal(self-hosted).
Вы можете передать их как указанные выше переменные окружения (подходит для CI и DevOps) или через файл конфигурации:
# download the example config file at the default path, then customize to your needs
mkdir ~/.config/vault-conductor
curl -sSL https://github.com/pirafrank/vault-conductor/raw/refs/heads/main/config.yaml.example > ~/.config/vault-conductor/config.yaml
chmod 0600 ~/.config/vault-conductor/config.yaml
Использование
# set SSH Agent env var to vault-conductor socket
export SSH_AUTH_SOCK="/tmp/vc-$(whoami)-ssh-agent.sock"
# Start in foreground
# (recommended for first time users to verify config is ok)
vault-conductor start --fg
# Start the agent in background
vault-conductor start
# Stop the background agent
vault-conductor stop
Команда start также поддерживает опцию --config для указания пользовательского пути к конфигурации. Переменные окружения всегда имеют приоритет над файлом конфигурации.
Отладка
Иногда вам может понадобиться отладить странную ситуацию, и нужно как можно больше логов. Выполните следующее, чтобы запуститься на переднем плане и получать подробные логи в stdout:
vault-conductor start --fg -vv
Установка как службы
Вы можете установить его как службу Systemd в пользовательском пространстве. Подробнее здесь.
Документация
Загляните в каталог docs, чтобы найти диаграммы о том, как работает и организован код. Ознакомьтесь с политикой безопасности перед использованием RSA-ключей или пересылкой агента.
Что дальше
- Поддержка нескольких SSH-ключей
- Поддержка self-hosted Bitwarden
- Улучшенное тестирование
- Предложить больше способов установки (Homebrew, AUR, nix, .deb, .rpm)
- Поддержка провайдеров, отличных от Bitwarden?
О названии
vault, /voːlt/ — подземное помещение, особенно для хранения ценностей
conductor, /kənˈdʌk·tər/ — дирижёр; то, что проводит тепло или электричество
по аналогии — то, что проводит ваш ценный SSH-ключ из хранилища Bitwarden в вашу среду разработки.
Лицензия
Этот проект лицензирован под MIT License.
Подробности см. в файле LICENSE.