How to pass a passphrase to ssh-add without triggering a prompt?

From the ssh-add manpage:

 DISPLAY and SSH_ASKPASS
         If ssh-add needs a passphrase, it will read the passphrase from
         the current terminal if it was run from a terminal.  If ssh-add
         does not have a terminal associated with it but DISPLAY and
         SSH_ASKPASS are set, it will execute the program specified by
         SSH_ASKPASS (by default ``ssh-askpass'') and open an X11 window
         to read the passphrase.  This is particularly useful when calling
         ssh-add from a .xsession or related script.  (Note that on some
         machines it may be necessary to redirect the input from /dev/null
         to make this work.)

So we can use this to cheat a little.

We start with no identities in the agent:

$ ssh-add -l
The agent has no identities.

So now we need a program that will supply the password:

$ cat x
#!/bin/sh
echo test123

And then convince ssh-add to use that script:

$ DISPLAY=1 SSH_ASKPASS="./x" ssh-add test < /dev/null
Identity added: test (sweh@godzilla)

And there it is:

$ ssh-add -l                                          
2048 SHA256:07qZby7TafI10LWAMSvGFreY75L/js94pFuNcbhfSC0 sweh@godzilla (RSA)

Edit to add, based on revised question:

The password could be passed as a variable, and the askpass script use that variable.

For example:

$ cat /usr/local/sbin/auto-add-key
#!/bin/sh
echo $SSH_PASS

$ SSH_PASS=test123 DISPLAY=1 SSH_ASKPASS=/usr/local/sbin/auto-add-key ssh-add test < /dev/null
Identity added: test (sweh@godzilla)

In the workflow presented you would do SSH_PASS=$passphrase to use the newly generated passphrase.


You can use script(1) as a mini-expect.

On Linux:

{ sleep .1; echo password; } | script -q /dev/null -c 'ssh-add /path/to/identity'

On BSD:

{ sleep .1; echo password; } | script -q /dev/null ssh-add /path/to/identity

You may want to increase the delay (sleep .3 or sleep 1) if the right hand of the pipeline is slow to start. For anything more complex, use expect. Do not use sshpass since it's really no better than script and itself subject to races.