If you want to use Touch ID have a look at: How to use use Bitwarden CLI with macOS Touch ID
Wirtten and tested on macOS Ventura
Before you can use Bitwarden CLI for your SSH private keys you have to add them to your Bitwarden account. Just create a normal login. The name, username and URI fields doesn't matter for my functions.
What madders is that you add your private SSH-Key as attachment (If your key is encrypted add type the password in the password field) and add a new custom field of type bool:
Name the custom field ssh
, it doesn't matter if you check the box or not:
Afterwards your new login should look simmilar to this:
Reapeat this for every key you want to add.
Add the following code to your .zshrc
:
ssh-add-with-passphrase () {
key_file="$(mktemp)"
echo "${1}" > ${key_file}
chmod 600 ${key_file}
if [ -z "${2}" ]; then
ssh-add ${key_file}
else
expect << EOF
spawn ssh-add ${key_file}
expect "Enter passphrase"
send "${2}\n"
expect eof
EOF
fi
rm -rf ${key_file}
}
ssh-add-bw-keys () {
bw_status=$(bw status | jq -r '.status')
if [[ ${bw_status} != 'unlocked' ]]; then
echo "Bitwarden Vault: ${bw_status}"
echo "Please login:"
bw --regenerate-session-key
fi
bw sync &> /dev/null
bw list items | jq -c '.[] | select(.fields[0].name=="ssh" and .attachments != null)' | while read key; do
local key_pw=$(printf '%q' $(jq -r '.login.password' <<< "${key}"))
local key_id=$(jq -r '.id' <<< "${key}")
local key_file_name=$(jq -r '.attachments[].fileName' <<< "${key}")
local id_ssh=$(bw get attachment ${key_file_name} --itemid ${key_id} --raw)
ssh-add-with-passphrase "${id_ssh}" "${key_pw}" &> /dev/null
done
}
ssh () {
echo "Temporary adding keys from bitwarden..."
ssh_exec=$(sh -c "which ssh")
ssh-add-bw-keys
nohup bash -c 'sleep 10; ssh-add -D &> /dev/null' </dev/null >/dev/null 2>&1 &
disown
echo -e '\e[1A\e[KSuccessfull!'
${ssh_exec} $@
}
If you're using ansible also add:
ansible () {
ansible_exec=$(sh -c "which ansible")
ssh-add-bw-keys
${ansible_exec} $@
ssh-add -D &> /dev/null
}
Afterwards reopen the Terminal or type exec zsh
.
With this function wrapper, you will be prompted for your Bitwarden masterkey everytime you use ssh
. If you rather want to use your sudo
password or Touch ID have look here.
What happens here, is that we query all SHH-Keys know to bitwarden and add them to our SSH-Agent. For me it takes about 2 seconds to find and add all my SSH-Keys.
After 10 seconds all keys are deleted again.
Adding all Keys migth not be the most elegant way and writting the ssh-key temporaly to disk not the most secure way. But I hope to see a officail solution soon™.
Meanwhile if you have a better solution, feel free to leave a comment!
I already tried SSH-ASKPASS
and injecting a variable into spawn
but failed.