# Интеграция Bitwarden CLI с fzf и буфером обмена

Менеджер паролей — это специальное приложение, которое помогает делать вид, что я помню разные пароли для разных аккаунтов, а не ввожу везде один и тот же. Мне нравится Bitwarden: открытый исходный код, возможность поднять собственный сервер, клиенты под разные устройства и расширения под разные браузеры.

Самым удобным, внезапно, оказался клиент для Android, который не заставляет меня каждый раз вводить 12+ знаков мастер-пароля (такую длину требуют Bitwarden и здравый смысл), а может быть разблокирован с помощью биометрии. Похожего удобства захотелось достичь и на Linux.

## Дикий CLI

На ноутбуке я использую Bitwarden CLI. Это powerful, fully-featured tool, которым на практике оказалось не слишком удобно пользоваться, если ты человек.

### Ключи от ключей

> You are responsible for maintaining your session key.

Bitwarden CLI поддерживает механизм сессий, который призван избавить пользователя от бесконечного ввода мастер-пароля. Приложение позволяет разблокировать хранилище и получить временный сессионный ключ, который можно либо хранить в беззащитной переменной окружения, либо прикладывать к каждому запросу вручную.

По сути своей, сессионный ключ отличается от мастер-пароля тем, что его можно моментально деактивировать, но совершенно невозможно запомнить, а, значит, нужно где-то хранить. Хочется делать это удобно и безопасно, а не в общедоступной переменной окружения.

### Пароли в stdout

> The get command can only return one result, so you should use specific search terms. If multiple results are found, the CLI will return an error.

Где-то в этот момент чтения документации я окончательно начал подозревать, что официальный CLI предназначен для скриптов: всё строго, никакого автодополнения, никакого интерактивного поиска, а пароли лаконично вываливаются в стандартный вывод терминала, откуда их ещё нужно как-то переправить в место назначения.

## Приручение CLI

Может показаться, что я ругаюсь, но отсутствие удобств и излишеств в официальном CLI — это хорошо:

- Отсутствие фич всегда приятнее, чем кривые фичи.
- Минимализм упрощает жизнь мейнтейнерам.
- Минимализм повышает надёжность.
- Меньше сторонних зависимостей.
- Стандартные интерфейсы идеально подходят для автоматизации.

Идея сделать Bitwarden CLI удобнее, разумеется, пришла в голову не только мне, так что на GitHub предсказуемо быстро нашёлся скрипт-обёртка от @loeschzwerg. Этот ZSH-скрипт менее требователен к пользователю и позволяет в случае, когда под пользовательский поисковый запрос подходит несколько аккаунтов, выбрать нужный из списка с помощью fzf и автоматически скопировать логин, пароль и даже TOTP в буфер обмена.

К сожалению, найденный скрипт никак не решал проблему управления сессиями, так что я решил его немного доработать, избавив заодно от избытка многоточий в интерфейсе.

### «Безопасное» хранение сессионного ключа

Как я писал выше, мне нравится подход Android-клиента: нужно один раз ввести свой невероятно длинный мастер-пароль, после чего можно разблокировать хранилище отпечатком пальца. В ходе непродолжительных размышлений я решил, что самое простое и надёжное подобие для приложения в терминале — один раз получить сессионный ключ и сохранить его в файл, который будет доступен для чтения только пользователю `root` и недоступен любым другим приложениям, запущенным от имени текущего пользователя.

Приятный бонус для владельцев биометрических сканеров: они отлично интегрируются с утилитой `sudo`.

В результате скрипт обогатился двумя функциями и одной проверкой:

    local sessionfile="$HOME/.bitwarden_session"

    get_saved_sessionkey () {
      sudo touch $sessionfile
      echo $(sudo cat $sessionfile)
    }

    save_sessionkey () {
      local sessionkey=$1
      sudo chmod 600 $sessionfile
      sudo sh -c "echo $sessionkey > $sessionfile"
    }

    local sessionkey=$(get_saved_sessionkey)

    if [[ -z $sessionkey ]] ; then
      # Get and save a new session key
      sessionkey=$(bw unlock --raw)
      save_sessionkey $sessionkey
    else
      echo "Using the existing session key from '$sessionfile'."
    fi

При первом запуске сессионный ключ, полученный после ввода мастер-пароля, записывается в файл, который после выполнения команды `chmod 600` становится недоступен для чтения никому, кроме суперпользователя:

    ~ » ls -lah
    ...
    -rw-------. 1 root root   89 Jul 24 22:15 .bitwarden_session
    ...

    ~ » less .bitwarden_session
    .bitwarden_session: Permission denied

Парольный менеджер и скрипт-обёртка запускаются от имени текущего пользователя, повышение привилегий требуется только в момент записи и чтения сессионного ключа.

Деактивировать сохранённый ключ можно с помощью команды `bw lock`. К сожалению, я так и не понял, как с помощью утилиты `bw` можно проверить, валиден ли ключ, так что после деактивации придётся удалить файл `~/.bitwarden_session` вручную, иначе скрипт так и будет подставлять протухший сохранённый ключ, а `bw` будет каждый раз игнорировать его и настойчиво спрашивать мастер-пароль.

Update [2026-03-29]: Нормального способа проверить валидность сессионного ключа всё ещё нет, но я научил утилиту удалять файл с протухшим ключом по косвенным признакам.

## Применять с осторожностью

Взаимодействие с менеджером паролей выглядит для меня теперь примерно так:

    ~ » bwc github
    [sudo] password for $USER:
    Using the existing session key from '/home/$USER/.bitwarden_session'.
    Searching for 'github'...

    abcdefgh-ijkl-mnop-qrst-uvwxyz123456
    github.com

    Username 'username' copied to clipboard.
    [Press any key to copy the password]
    Password copied to clipboard.

Финальный вариант скрипта можно найти в репозитории He4eT/fuzzy-bitwarden-clipboard.

Настоятельно рекомендую читать любой код перед тем, как запускать его. Особенно в тех случаях, когда речь идёт о настолько чувствительных данных.

Важно! На системах без шифрования диска все эти танцы с правами на доступ к файлу не несут никакой пользы и превращают затею в увлекательный цирк.

Нельзя исключать, что я что-то совершенно неправильно понимаю в принципах работы системы прав доступа в Linux и совершил какие-нибудь грубейшие, с точки зрения настоящих специалистов по информационной безопасности, ошибки. Пожалуйста, сообщите, если я где-то неправ.

Нужно помнить, что такое упрощение жизни ведёт к новым рискам: теперь любой, кто знает ваш пароль для учётной записи системного пользователя и имеет доступ к компьютеру, будет также иметь доступ и ко всем паролям, сохранённым в Bitwarden.

Пользуйтесь с осторожностью и/или храните свои пароли в надёжных местах =)