From 7e8661f68bae792159eb802e12cee34cc45b670d Mon Sep 17 00:00:00 2001 From: user Date: Sun, 22 Feb 2026 02:13:32 +0100 Subject: [PATCH] docs: add non-interactive ssh-add patterns to ssh howto Cover passphrase injection via script(1) with env vars and the SSH_ASKPASS alternative for headless automation. --- topics/ssh.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/topics/ssh.md b/topics/ssh.md index f6ac5d6..9098554 100644 --- a/topics/ssh.md +++ b/topics/ssh.md @@ -68,6 +68,34 @@ ssh-add -D ssh -A user@bastion # remote can use your local keys ``` +### Non-Interactive ssh-add (passphrase from env) + +`ssh-add` insists on a terminal for passphrase input. Use `script` to fake a TTY and feed the passphrase from an environment variable: + +```bash +# SSH_KEY_PASS must be set (e.g. sourced from a secrets file) +{ sleep 0.1; echo "$SSH_KEY_PASS"; } | script -q /dev/null -c "ssh-add $HOME/.ssh/id_ed25519" +``` + +Useful in automation (CI, cron, Ansible) where no interactive terminal exists. + +```bash +# Full pattern: source secrets, start agent, add key +source ~/.bashrc.secrets # exports SSH_KEY_PASS +eval "$(ssh-agent -s)" +{ sleep 0.1; echo "$SSH_KEY_PASS"; } | script -q /dev/null -c "ssh-add $HOME/.ssh/id_ed25519" +ssh-add -l # verify key loaded +``` + +Alternative with `SSH_ASKPASS` (avoids `script`): + +```bash +export SSH_ASKPASS_REQUIRE=force +export SSH_ASKPASS="$(mktemp)" && printf '#!/bin/sh\necho "$SSH_KEY_PASS"' > "$SSH_ASKPASS" && chmod +x "$SSH_ASKPASS" +ssh-add ~/.ssh/id_ed25519 +rm -f "$SSH_ASKPASS" +``` + ## Config File (~/.ssh/config) ```ssh-config